@Test public void testGetOutgoingEdge_NonExistent() throws Exception { Node node = new ByteArrayNodeNonLeafVoidValue( "FOO", Arrays.asList( (Node) new ByteArrayNodeDefault("BAR1", 1, Collections.<Node>emptyList()))); Assert.assertNull(node.getOutgoingEdge('C')); }
@Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { Node node = new ByteArrayNodeNonLeafVoidValue( "FOO", Arrays.asList( (Node) new ByteArrayNodeDefault("BAR", 1, Collections.<Node>emptyList()))); node.updateOutgoingEdge(new ByteArrayNodeDefault("CAR", null, Collections.<Node>emptyList())); }
@Test public void testUpdateOutgoingEdge() throws Exception { Node node = new ByteArrayNodeNonLeafVoidValue( "FOO", Arrays.asList( (Node) new ByteArrayNodeDefault("BAR1", 1, Collections.<Node>emptyList()))); node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR2", null, Collections.<Node>emptyList())); }
@Override public void updateOutgoingEdge(Node childNode) { // Binary search for the index of the node whose edge starts with the given character. // Note that this binary search is safe in the face of concurrent modification due to // constraints // we enforce on use of the array, as documented in the binarySearchForEdge method... int index = NodeUtil.binarySearchForEdge(outgoingEdges, childNode.getIncomingEdgeFirstCharacter()); if (index < 0) { throw new IllegalStateException( "Cannot update the reference to the following child node for the edge starting with '" + childNode.getIncomingEdgeFirstCharacter() + "', no such edge already exists: " + childNode); } // Atomically update the child node at this index... outgoingEdges.set(index, childNode); }
/** * Traverses the tree based on characters in the given input, and for each node traversed which * encodes a key in the tree, invokes the given {@link KeyValueHandler} supplying it the key * which matched that node and the value from the node. * * @param input A sequence of characters which controls traversal of the tree * @param keyValueHandler An object which will be notified of every key and value encountered in * the input */ protected void scanForKeysAtStartOfInput(CharSequence input, KeyValueHandler keyValueHandler) { Node currentNode = super.root; int charsMatched = 0; final int documentLength = input.length(); outer_loop: while (charsMatched < documentLength) { Node nextNode = currentNode.getOutgoingEdge(input.charAt(charsMatched)); if (nextNode == null) { // Next node is a dead end... //noinspection UnnecessaryLabelOnBreakStatement break outer_loop; } currentNode = nextNode; CharSequence currentNodeEdgeCharacters = currentNode.getIncomingEdge(); int charsMatchedThisEdge = 0; for (int i = 0, j = Math.min(currentNodeEdgeCharacters.length(), documentLength - charsMatched); i < j; i++) { if (currentNodeEdgeCharacters.charAt(i) != input.charAt(charsMatched + i)) { // Found a difference in chars between character in key and a character in current node. // Current node is the deepest match (inexact match).... break outer_loop; } charsMatchedThisEdge++; } if (charsMatchedThisEdge == currentNodeEdgeCharacters.length()) { // All characters in the current edge matched, add this number to total chars matched... charsMatched += charsMatchedThisEdge; } if (currentNode.getValue() != null) { keyValueHandler.handle(input.subSequence(0, charsMatched), currentNode.getValue()); } } }
@Test public void testToString() throws Exception { Node node = new ByteArrayNodeNonLeafVoidValue("FOO", Collections.<Node>emptyList()); Assert.assertEquals("Node{edge=FOO, value=-, edges=[]}", node.toString()); }