/** * Updates distances to restore parent-child relationships that have been invalidated by * structural updates. * * <p>Each structural update (insert/delete) leads to a shift of higher PRE values. This * invalidates parent-child relationships. Distances are only updated after all structural updates * have been carried out to make sure each node (that has to be updated) is only touched once. */ public void updateDistances() { accumulatePreValueShifts(); final IntSet alreadyUpdatedNodes = new IntSet(); for (final BasicUpdate update : updStructural) { int newPreOfAffectedNode = update.preOfAffectedNode + update.accumulatedShifts; /* Update distance for the affected node and all following siblings of nodes * on the ancestor-or-self axis. */ while (newPreOfAffectedNode < data.meta.size) { if (alreadyUpdatedNodes.contains(newPreOfAffectedNode)) break; data.dist( newPreOfAffectedNode, data.kind(newPreOfAffectedNode), calculateNewDistance(newPreOfAffectedNode)); alreadyUpdatedNodes.add(newPreOfAffectedNode); newPreOfAffectedNode += data.size(newPreOfAffectedNode, data.kind(newPreOfAffectedNode)); } } }
/** * Resolves unwanted text node adjacency which can result from structural changes in the database. * Adjacent text nodes are two text nodes A and B, where PRE(B)=PRE(A)+1 and PARENT(A)=PARENT(B). */ private void resolveTextAdjacency() { // Text node merges are also gathered on a separate list to leverage optimizations. final AtomicUpdateList allMerges = new AtomicUpdateList(data); // keep track of the visited locations to avoid superfluous checks final IntSet s = new IntSet(); // Text nodes have to be merged from the highest to the lowest pre value for (int i = 0; i < updStructural.size(); i++) { final BasicUpdate u = updStructural.get(i); final Data insseq = u.getInsertionData(); // calculate the new location of the update, here we have to check for adjacency final int newLocation = u.location + u.accumulatedShifts - u.shifts; final int beforeNewLocation = newLocation - 1; // check surroundings of this location for adjacent text nodes depending on the // kind of update, first the one with higher PRE values (due to shifts!) // ... for insert/replace ... if (insseq != null) { // calculate the current following node final int followingNode = newLocation + insseq.meta.size; final int beforeFollowingNode = followingNode - 1; // check the nodes at the end of/after the insertion sequence if (!s.contains(beforeFollowingNode)) { final AtomicUpdateList merges = necessaryMerges(beforeFollowingNode, allMerges.data); mergeNodes(merges); allMerges.merge(merges); s.add(beforeFollowingNode); } } // check nodes for delete and for insert before the updated location if (!s.contains(beforeNewLocation)) { final AtomicUpdateList merges = necessaryMerges(beforeNewLocation, allMerges.data); mergeNodes(merges); allMerges.merge(merges); s.add(beforeNewLocation); } } allMerges.updateDistances(); allMerges.clear(); }
/** @inheritDoc */ public void merge(IntSet other) { if (other instanceof BitIntSet) { BitIntSet o = (BitIntSet) other; ensureCapacity(Bits.getMax(o.bits) + 1); Bits.or(bits, o.bits); } else if (other instanceof ListIntSet) { ListIntSet o = (ListIntSet) other; int sz = o.ints.size(); if (sz > 0) { ensureCapacity(o.ints.get(sz - 1)); } for (int i = 0; i < o.ints.size(); i++) { Bits.set(bits, o.ints.get(i), true); } } else { IntIterator iter = other.iterator(); while (iter.hasNext()) { add(iter.next()); } } }
public Graph neighbourhoodGraph(int nnodes[], int hops) { PrimaryHashMap<Integer, String> nodes; PrimaryHashMap<String, Integer> nodesReverse; try { File auxFile = File.createTempFile("graph-maps-" + System.currentTimeMillis(), "aux"); auxFile.deleteOnExit(); RecordManager recMan = RecordManagerFactory.createRecordManager(auxFile.getAbsolutePath()); nodes = recMan.hashMap("nodes"); nodesReverse = recMan.hashMap("nodesReverse"); } catch (IOException ex) { throw new Error(ex); } nodes.clear(); nodesReverse.clear(); WeightedArcSet list1 = new WeightedArcSet(); Int2IntAVLTreeMap map = new Int2IntAVLTreeMap(); IntSet set = new IntLinkedOpenHashSet(); int numIterators = 100; Constructor[] cons = WeightedArc.class.getDeclaredConstructors(); for (int i = 0; i < cons.length; i++) cons[i].setAccessible(true); for (int n : nnodes) map.put(n, 0); NodeIterator its[] = new NodeIterator[numIterators]; int itNum[] = new int[numIterators]; for (int n = 0; n < its.length; n++) { its[n] = nodeIterator(); itNum[n] = 0; } while (map.size() != 0) { Integer node = 0; for (int n = 0; n < its.length; n++) if (itNum[n] <= node) node = itNum[n]; node = map.tailMap(node).firstKey(); if (node == null) map.firstKey(); NodeIterator it = null; Integer aux1 = 0; int iit = 0; for (int n = 0; n < its.length; n++) { if (!its[n].hasNext()) { its[n] = nodeIterator(); itNum[n] = 0; } if (itNum[n] == node) { it = its[n]; aux1 = itNum[n]; iit = 0; break; } if (itNum[n] < node && itNum[n] >= aux1) { it = its[n]; aux1 = itNum[n]; iit = n; } } if (it == null) { its[0] = nodeIterator(); itNum[0] = 0; it = its[0]; } while (it != null && (aux1 = it.nextInt()) != null && aux1 >= 0 && aux1 < node) {} itNum[iit] = aux1 + 1; Integer aux2 = null; ArcLabelledNodeIterator.LabelledArcIterator suc = it.successors(); while ((aux2 = suc.nextInt()) != null && aux2 >= 0 && (aux2 < graph.numNodes())) try { if (commit++ % COMMIT_SIZE == 0) { try { nodes.getRecordManager().commit(); } catch (IOException e) { throw new Error(e); } try { nodesReverse.getRecordManager().commit(); } catch (IOException e) { throw new Error(e); } } if (!nodesReverse.containsKey(this.nodes.get(aux1))) { nodes.put(nodes.size(), this.nodes.get(aux1)); nodesReverse.put(this.nodes.get(aux1), nodesReverse.size()); } if (!nodesReverse.containsKey(this.nodes.get(aux2))) { nodes.put(nodes.size(), this.nodes.get(aux2)); nodesReverse.put(this.nodes.get(aux2), nodesReverse.size()); } int aaux1 = nodesReverse.get(this.nodes.get(aux1)); int aaux2 = nodesReverse.get(this.nodes.get(aux2)); WeightedArc arc1 = (WeightedArc) cons[0].newInstance(aaux1, aaux2, suc.label().getFloat()); list1.add(arc1); if (map.get(node) < hops) { if (!set.contains(aux1) && (map.get(aux1) == null || map.get(aux1) > map.get(node) + 1)) map.put(aux1.intValue(), map.get(node) + 1); if (!set.contains(aux2) && (map.get(aux2) == null || map.get(aux2) > map.get(node) + 1)) map.put(aux2.intValue(), map.get(node) + 1); } } catch (Exception ex) { ex.printStackTrace(); throw new Error(ex); } ArcLabelledNodeIterator.LabelledArcIterator anc = it.ancestors(); while ((aux2 = anc.nextInt()) != null && aux2 >= 0 && (aux2 < graph.numNodes())) try { if (commit++ % COMMIT_SIZE == 0) { try { nodes.getRecordManager().commit(); } catch (IOException e) { throw new Error(e); } try { nodesReverse.getRecordManager().commit(); } catch (IOException e) { throw new Error(e); } } if (!nodesReverse.containsKey(this.nodes.get(aux1))) { nodes.put(nodes.size(), this.nodes.get(aux1)); nodesReverse.put(this.nodes.get(aux1), nodesReverse.size()); } if (!nodesReverse.containsKey(this.nodes.get(aux2))) { nodes.put(nodes.size(), this.nodes.get(aux2)); nodesReverse.put(this.nodes.get(aux2), nodesReverse.size()); } int aaux1 = nodesReverse.get(this.nodes.get(aux1)); int aaux2 = nodesReverse.get(this.nodes.get(aux2)); WeightedArc arc1 = (WeightedArc) cons[0].newInstance(aaux2, aaux1, anc.label().getFloat()); list1.add(arc1); if (map.get(node) < hops) { if (!set.contains(aux1) && (map.get(aux1) == null || map.get(aux1) > map.get(node) + 1)) map.put(aux1.intValue(), map.get(node) + 1); if (!set.contains(aux2) && (map.get(aux2) == null || map.get(aux2) > map.get(node) + 1)) map.put(aux2.intValue(), map.get(node) + 1); } } catch (Exception ex) { ex.printStackTrace(); throw new Error(ex); } map.remove(node); set.add(node); } Graph newGraph = new Graph(list1.toArray(new WeightedArc[0])); newGraph.nodes.clear(); newGraph.nodesReverse.clear(); newGraph.nodes = nodes; newGraph.nodesReverse = nodesReverse; return newGraph; }
/** * Constructor. * * @param info input info * @param map decimal format * @throws QueryException query exception */ public DecFormatter(final InputInfo info, final TokenMap map) throws QueryException { // assign map values int z = '0'; if (map != null) { for (final byte[] key : map) { final String k = string(key); final byte[] v = map.get(key); if (k.equals(DF_INF)) { inf = v; } else if (k.equals(DF_NAN)) { nan = v; } else if (v.length != 0 && cl(v, 0) == v.length) { final int cp = cp(v, 0); switch (k) { case DF_DEC: decimal = cp; break; case DF_GRP: grouping = cp; break; case DF_EXP: exponent = cp; break; case DF_PAT: pattern = cp; break; case DF_MIN: minus = cp; break; case DF_DIG: optional = cp; break; case DF_PC: percent = cp; break; case DF_PM: permille = cp; break; case DF_ZD: z = zeroes(cp); if (z == -1) throw INVDECFORM_X_X.get(info, k, v); if (z != cp) throw INVDECZERO_X.get(info, (char) cp); break; } } else { // signs must have single character throw INVDECSINGLE_X_X.get(info, k, v); } } } // check for duplicate characters zero = z; final IntSet is = new IntSet(); for (int i = 0; i < 10; i++) is.add(zero + i); final int[] ss = {decimal, grouping, exponent, percent, permille, optional, pattern}; for (final int s : ss) if (!is.add(s)) throw DUPLDECFORM_X.get(info, (char) s); // create auxiliary strings final TokenBuilder tb = new TokenBuilder(); for (int i = 0; i < 10; i++) tb.add(zero + i); digits = tb.toArray(); // "decimal-separator-sign, exponent-separator-sign, grouping-sign, decimal-digit-family, // optional-digit-sign and pattern-separator-sign are classified as active characters" // -> decimal-digit-family: added above. pattern-separator-sign: will never occur at this stage actives = tb.add(decimal).add(exponent).add(grouping).add(optional).finish(); // "all other characters (including the percent-sign and per-mille-sign) are classified // as passive characters." }
@Override protected void rehash(final int sz) { super.rehash(sz); values = Arrays.copyOf(values, sz); }
@Test public void testAdd() { IntSet s = new IntSet(); assertTrue(s.add(1)); assertFalse(s.add(1)); for (int i = 2; i < 64; i++) assertTrue(s.add(i)); for (int i = 2; i < 64; i++) assertFalse(s.add(i)); assertTrue(s.add(-1)); assertFalse(s.add(-1)); assertTrue(s.add(-2)); assertFalse(s.add(-2)); assertTrue(s.add(128)); assertFalse(s.add(128)); assertFalse(s.add(1)); }