diff --git a/code/pom.xml b/code/pom.xml index 69cc532..c7a1041 100644 --- a/code/pom.xml +++ b/code/pom.xml @@ -43,15 +43,17 @@ org.apache.maven.plugins maven-compiler-plugin 2.3.2 - 1.6 - 1.6 + 1.5 + 1.5 + true + true + -Xlint:all,-options,-processing @@ -76,6 +78,9 @@ ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + ${project.groupId}.${project.artifactId} + @@ -107,6 +112,27 @@ + + + org.codehaus.mojo + animal-sniffer-maven-plugin + 1.16 + + + test + + check + + + + org.codehaus.mojo.signature + java15 + 1.0 + + + + + diff --git a/code/src/main/java/com/googlecode/concurrenttrees/common/CharSequences.java b/code/src/main/java/com/googlecode/concurrenttrees/common/CharSequences.java index d128862..23f468b 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/common/CharSequences.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/common/CharSequences.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,12 +15,6 @@ */ package com.googlecode.concurrenttrees.common; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CodingErrorAction; import java.util.Iterator; /** diff --git a/code/src/main/java/com/googlecode/concurrenttrees/common/Iterables.java b/code/src/main/java/com/googlecode/concurrenttrees/common/Iterables.java index dbca4ca..a3bc9ea 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/common/Iterables.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/common/Iterables.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/main/java/com/googlecode/concurrenttrees/common/KeyValuePair.java b/code/src/main/java/com/googlecode/concurrenttrees/common/KeyValuePair.java index 4bc3f42..05840fb 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/common/KeyValuePair.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/common/KeyValuePair.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/main/java/com/googlecode/concurrenttrees/common/LazyIterator.java b/code/src/main/java/com/googlecode/concurrenttrees/common/LazyIterator.java index ab87c87..6004cbb 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/common/LazyIterator.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/common/LazyIterator.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * Copyright 2007 The Guava Authors * diff --git a/code/src/main/java/com/googlecode/concurrenttrees/common/PrettyPrinter.java b/code/src/main/java/com/googlecode/concurrenttrees/common/PrettyPrinter.java index b34b6bb..46dbd07 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/common/PrettyPrinter.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/common/PrettyPrinter.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +16,7 @@ package com.googlecode.concurrenttrees.common; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; import com.googlecode.concurrenttrees.radix.node.util.PrettyPrintable; import java.io.IOException; @@ -83,7 +84,7 @@ static void prettyPrint(Node node, Appendable sb, String prefix, boolean isTail, StringBuilder label = new StringBuilder(); if (isRoot) { label.append("○"); - if (node.getIncomingEdge().length() > 0) { + if (node.getIncomingEdgeLength() > 0) { label.append(" "); } } @@ -92,7 +93,7 @@ static void prettyPrint(Node node, Appendable sb, String prefix, boolean isTail, label.append(" (").append(node.getValue()).append(")"); } sb.append(prefix).append(isTail ? isRoot ? "" : "└── ○ " : "├── ○ ").append(label).append("\n"); - List children = node.getOutgoingEdges(); + NodeList children = node.getOutgoingEdges(); for (int i = 0; i < children.size() - 1; i++) { prettyPrint(children.get(i), sb, prefix + (isTail ? isRoot ? "" : " " : "│ "), false, false); } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/common/SetFromMap.java b/code/src/main/java/com/googlecode/concurrenttrees/common/SetFromMap.java new file mode 100644 index 0000000..a63461b --- /dev/null +++ b/code/src/main/java/com/googlecode/concurrenttrees/common/SetFromMap.java @@ -0,0 +1,120 @@ +/* + * Copyright 2012-2013 Niall Gallagher + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.googlecode.concurrenttrees.common; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.*; + +/** + * A facade implementation of a Java set for representing a Java map implementation. + * + * @param The element type. + */ +public class SetFromMap extends AbstractSet implements Serializable { + + private static final long serialVersionUID = 1L; + + private final Map delegate; + + private transient Set keySet; + + public SetFromMap(Map delegate) { + this.delegate = delegate; + keySet = delegate.keySet(); + } + + private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + keySet = delegate.keySet(); + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return delegate.containsKey(o); + } + + @Override + public boolean remove(Object o) { + return delegate.remove(o) != null; + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public boolean add(E e) { + return delegate.put(e, Boolean.TRUE) == null; + } + + @Override + public Iterator iterator() { + return keySet.iterator(); + } + + @Override + public Object[] toArray() { + return keySet.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return keySet.toArray(a); + } + + @Override + public String toString() { + return keySet.toString(); + } + + @Override + public int hashCode() { + return keySet.hashCode(); + } + + @Override + public boolean equals(Object o) { + return o == this || keySet.equals(o); + } + + @Override + public boolean containsAll(Collection c) { + return keySet.containsAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return keySet.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return keySet.retainAll(c); + } +} diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/ConcurrentRadixTree.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/ConcurrentRadixTree.java index 7f745c8..2cd0229 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/ConcurrentRadixTree.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/ConcurrentRadixTree.java @@ -20,6 +20,8 @@ import com.googlecode.concurrenttrees.common.LazyIterator; import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import com.googlecode.concurrenttrees.radix.node.util.PrettyPrintable; import java.io.Serializable; @@ -40,6 +42,8 @@ * @author Niall Gallagher */ public class ConcurrentRadixTree implements RadixTree, PrettyPrintable, Serializable { + + private static final long serialVersionUID = 1L; private final NodeFactory nodeFactory; @@ -57,7 +61,7 @@ public class ConcurrentRadixTree implements RadixTree, PrettyPrintable, Se public ConcurrentRadixTree(NodeFactory nodeFactory) { this.nodeFactory = nodeFactory; @SuppressWarnings({"NullableProblems", "UnnecessaryLocalVariable"}) - Node rootNode = nodeFactory.createNode("", null, Collections.emptyList(), true); + Node rootNode = nodeFactory.createNode("", null, new SimpleNodeList(), true); this.root = rootNode; } @@ -99,10 +103,10 @@ public O putIfAbsent(CharSequence key, O value) { */ @Override public O getValueForExactKey(CharSequence key) { - SearchResult searchResult = searchTree(key); - if (searchResult.classification.equals(SearchResult.Classification.EXACT_MATCH)) { + Node searchResult = (Node) searchTree(key, true); + if (searchResult != null) { @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) - O value = (O) searchResult.nodeFound.getValue(); + O value = (O) searchResult.getValue(); return value; } return null; @@ -207,7 +211,7 @@ public boolean remove(CharSequence key) { } // Proceed with deleting the node... - List childEdges = searchResult.nodeFound.getOutgoingEdges(); + NodeList childEdges = searchResult.nodeFound.getOutgoingEdges(); if (childEdges.size() > 1) { // This node has more than one child, so if we delete the value from this node, we still need // to leave a similar node in place to act as the split between the child edges. @@ -237,11 +241,11 @@ else if (childEdges.size() == 1) { // (a special case which we never merge), then we also need to merge the parent with its // remaining child. - List currentEdgesFromParent = searchResult.parentNode.getOutgoingEdges(); + NodeList currentEdgesFromParent = searchResult.parentNode.getOutgoingEdges(); // Create a list of the outgoing edges of the parent which will remain // if we remove this child... // Use a non-resizable list, as a sanity check to force ArrayIndexOutOfBounds... - List newEdgesOfParent = Arrays.asList(new Node[searchResult.parentNode.getOutgoingEdges().size() - 1]); + NodeList newEdgesOfParent = new SimpleNodeList(new Node[searchResult.parentNode.getOutgoingEdges().size() - 1]); for (int i = 0, added = 0, numParentEdges = currentEdgesFromParent.size(); i < numParentEdges; i++) { Node node = currentEdgesFromParent.get(i); if (node != searchResult.nodeFound) { @@ -413,15 +417,15 @@ public Iterable> getKeyValuePairsForClosestKeys(CharSequence can */ @Override public int size() { - Deque stack = new LinkedList(); - stack.push(this.root); + LinkedList stack = new LinkedList(); + stack.addFirst(this.root); int count = 0; while (true) { if (stack.isEmpty()) { return count; } - Node current = stack.pop(); - stack.addAll(current.getOutgoingEdges()); + Node current = stack.removeFirst(); + current.getOutgoingEdges().addTo(stack); if (current.getValue() != null) { count++; } @@ -484,7 +488,7 @@ Object putInternal(CharSequence key, Object value, boolean overwrite) { // Create new nodes... Node newChild = nodeFactory.createNode(suffixFromExistingEdge, searchResult.nodeFound.getValue(), searchResult.nodeFound.getOutgoingEdges(), false); - Node newParent = nodeFactory.createNode(commonPrefix, value, Arrays.asList(newChild), false); + Node newParent = nodeFactory.createNode(commonPrefix, value, new SimpleNodeList(newChild), false); // Add the new parent to the parent of the node being replaced (replacing the existing node)... searchResult.parentNode.updateOutgoingEdge(newParent); @@ -502,13 +506,13 @@ Object putInternal(CharSequence key, Object value, boolean overwrite) { // Create a new child node containing the trailing characters... CharSequence keySuffix = key.subSequence(searchResult.charsMatched, key.length()); - Node newChild = nodeFactory.createNode(keySuffix, value, Collections.emptyList(), false); + Node newChild = nodeFactory.createNode(keySuffix, value, new SimpleNodeList(), false); // Clone the current node adding the new child... List edges = new ArrayList(searchResult.nodeFound.getOutgoingEdges().size() + 1); - edges.addAll(searchResult.nodeFound.getOutgoingEdges()); + searchResult.nodeFound.getOutgoingEdges().addTo(edges); edges.add(newChild); - Node clonedNode = nodeFactory.createNode(searchResult.nodeFound.getIncomingEdge(), searchResult.nodeFound.getValue(), edges, searchResult.nodeFound == root); + Node clonedNode = nodeFactory.createNode(searchResult.nodeFound.getIncomingEdge(), searchResult.nodeFound.getValue(), new SimpleNodeList(edges), searchResult.nodeFound == root); // Re-add the cloned node to its parent node... if (searchResult.nodeFound == root) { @@ -540,10 +544,10 @@ Object putInternal(CharSequence key, Object value, boolean overwrite) { CharSequence suffixFromKey = key.subSequence(searchResult.charsMatched, key.length()); // Create new nodes... - Node n1 = nodeFactory.createNode(suffixFromKey, value, Collections.emptyList(), false); + Node n1 = nodeFactory.createNode(suffixFromKey, value, new SimpleNodeList(), false); Node n2 = nodeFactory.createNode(suffixFromExistingEdge, searchResult.nodeFound.getValue(), searchResult.nodeFound.getOutgoingEdges(), false); @SuppressWarnings({"NullableProblems"}) - Node n3 = nodeFactory.createNode(commonPrefix, null, Arrays.asList(n1, n2), false); + Node n3 = nodeFactory.createNode(commonPrefix, null, new SimpleNodeList(n1, n2), false); searchResult.parentNode.updateOutgoingEdge(n3); @@ -738,7 +742,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - KeyValuePairImpl that = (KeyValuePairImpl) o; + KeyValuePairImpl that = (KeyValuePairImpl) o; return key.equals(that.key); @@ -782,9 +786,9 @@ protected Iterable lazyTraverseDescendants(final CharSequence start public Iterator iterator() { return new LazyIterator() { - Deque stack = new LinkedList(); + final LinkedList stack = new LinkedList(); { - stack.push(new NodeKeyPair(startNode, startKey)); + stack.addFirst(new NodeKeyPair(startNode, startKey)); } @Override @@ -792,15 +796,15 @@ protected NodeKeyPair computeNext() { if (stack.isEmpty()) { return endOfData(); } - NodeKeyPair current = stack.pop(); - List childNodes = current.node.getOutgoingEdges(); + NodeKeyPair current = stack.removeFirst(); + NodeList childNodes = current.node.getOutgoingEdges(); // -> Iterate child nodes in reverse order and so push them onto the stack in reverse order, // to counteract that pushing them onto the stack alone would otherwise reverse their processing order. // This ensures that we actually process nodes in ascending alphabetical order. for (int i = childNodes.size(); i > 0; i--) { Node child = childNodes.get(i - 1); - stack.push(new NodeKeyPair(child, CharSequences.concatenate(current.key, child.getIncomingEdge()))); + stack.addFirst(new NodeKeyPair(child, CharSequences.concatenate(current.key, child.getIncomingEdge()))); } return current; } @@ -899,7 +903,21 @@ protected CharSequence transformKeyForResult(CharSequence rawKey) { * parent node, the number of characters of the key which were matched in total and within the edge of the * matched node, and a {@link SearchResult#classification} of the match as described above */ + SearchResult searchTree(CharSequence key) { + return (SearchResult) searchTree(key, false); + } + + /** + * Implements {@link #searchTree(CharSequence)} but gives an option to return the exactly matched node directly + * without allocating a {@link SearchResult}. + * + * @param key a key for which the node matching the longest prefix of the key is required + * @param exactOnly If {@code true}, an exactly matched node is returned if such a node was found or {@code null} + * otherwise. If {@code false}, a {@link SearchResult} is returned. + * @return The resolved {@link SearchResult} or a {@link Node} if {@code exactOnly} was set to {@code true}. + */ + private Object searchTree(CharSequence key, boolean exactOnly) { Node parentNodesParent = null; Node parentNode = null; Node currentNode = root; @@ -918,9 +936,8 @@ SearchResult searchTree(CharSequence key) { parentNode = currentNode; currentNode = nextNode; charsMatchedInNodeFound = 0; - CharSequence currentNodeEdgeCharacters = currentNode.getIncomingEdge(); - for (int i = 0, numEdgeChars = currentNodeEdgeCharacters.length(); i < numEdgeChars && charsMatched < keyLength; i++) { - if (currentNodeEdgeCharacters.charAt(i) != key.charAt(charsMatched)) { + for (int i = 0, numEdgeChars = currentNode.getIncomingEdgeLength(); i < numEdgeChars && charsMatched < keyLength; i++) { + if (currentNode.getIncomingEdgeCharacterAt(i) != key.charAt(charsMatched)) { // 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; @@ -929,7 +946,15 @@ SearchResult searchTree(CharSequence key) { charsMatchedInNodeFound++; } } - return new SearchResult(key, currentNode, charsMatched, charsMatchedInNodeFound, parentNode, parentNodesParent); + if (exactOnly) { + if (SearchResult.doClassify(key, currentNode, charsMatched, charsMatchedInNodeFound).equals(Classification.EXACT_MATCH)) { + return currentNode; + } else { + return null; + } + } else { + return new SearchResult(key, currentNode, charsMatched, charsMatchedInNodeFound, parentNode, parentNodesParent); + } } /** @@ -970,23 +995,32 @@ enum Classification { } protected Classification classify(CharSequence key, Node nodeFound, int charsMatched, int charsMatchedInNodeFound) { + return doClassify(key, nodeFound, charsMatched, charsMatchedInNodeFound); + } + + protected static Classification doClassify(CharSequence key, Node nodeFound, int charsMatched, int charsMatchedInNodeFound) { if (charsMatched == key.length()) { - if (charsMatchedInNodeFound == nodeFound.getIncomingEdge().length()) { + if (charsMatchedInNodeFound == nodeFound.getIncomingEdgeLength()) { return Classification.EXACT_MATCH; } - else if (charsMatchedInNodeFound < nodeFound.getIncomingEdge().length()) { + else if (charsMatchedInNodeFound < nodeFound.getIncomingEdgeLength()) { return Classification.KEY_ENDS_MID_EDGE; } } else if (charsMatched < key.length()) { - if (charsMatchedInNodeFound == nodeFound.getIncomingEdge().length()) { + if (charsMatchedInNodeFound == nodeFound.getIncomingEdgeLength()) { return Classification.INCOMPLETE_MATCH_TO_END_OF_EDGE; } - else if (charsMatchedInNodeFound < nodeFound.getIncomingEdge().length()) { + else if (charsMatchedInNodeFound < nodeFound.getIncomingEdgeLength()) { return Classification.INCOMPLETE_MATCH_TO_MIDDLE_OF_EDGE; } } - throw new IllegalStateException("Unexpected failure to classify SearchResult: " + this); + throw new IllegalStateException("Unexpected failure to classify SearchResult: {" + + "key=" + key + + ", nodeFound=" + nodeFound + + ", charsMatched=" + charsMatched + + ", charsMatchedInNodeFound=" + charsMatchedInNodeFound + + '}'); } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/RadixTree.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/RadixTree.java index f319369..98014b1 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/RadixTree.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/RadixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/Node.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/Node.java index 279f369..9a4df53 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/Node.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/Node.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -96,7 +96,26 @@ public interface Node extends NodeCharacterProvider, Serializable { * * @return The first character of the "edge" encoded in this node */ - Character getIncomingEdgeFirstCharacter(); + char getIncomingEdgeFirstCharacter(); + + /** + * Returns the length of the "edge" encoded in this node, belonging to the connection from a parent node to this + * node. + *

+ * + * @return The length of the "edge" encoded in this node + */ + int getIncomingEdgeLength(); + + /** + * Returns the character at a given index of the "edge" encoded in this node, belonging to the connection from a + * parent node to this node. + *

+ * + * @param index The index of the character to resolve of the "edge" encoded in this node + * @return The character at the index of the "edge" encoded in this node + */ + char getIncomingEdgeCharacterAt(int index); /** * Returns all characters of the "edge" encoded in this node, belonging to the connection from a parent node to this @@ -115,7 +134,6 @@ public interface Node extends NodeCharacterProvider, Serializable { */ Object getValue(); - /** * Returns the child of this node whose edge starts with the given first character. *

@@ -126,7 +144,7 @@ public interface Node extends NodeCharacterProvider, Serializable { * @return The child of this node whose edge starts with the given first character, or null if this * node has no such outgoing edge */ - Node getOutgoingEdge(Character edgeFirstCharacter); + Node getOutgoingEdge(char edgeFirstCharacter); /** * Updates the child node reference for a given edge (identified by its first character) to point to a different @@ -136,7 +154,7 @@ public interface Node extends NodeCharacterProvider, Serializable { * edge from this node. *

* This write must be performed atomically, in relation to reads made via - * {@link #getOutgoingEdge(Character)}. + * {@link #getOutgoingEdge(char)}. * * @param childNode The new child node to associated with this edge */ @@ -150,5 +168,5 @@ public interface Node extends NodeCharacterProvider, Serializable { * * @return A read-only list of the child nodes to which this node has outgoing edges */ - List getOutgoingEdges(); + NodeList getOutgoingEdges(); } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/NodeFactory.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/NodeFactory.java index 6a767b3..96c3b71 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/NodeFactory.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/NodeFactory.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -47,6 +47,6 @@ public interface NodeFactory extends Serializable { * * @return An object implementing the {@link Node} interface which stores the given variables */ - Node createNode(CharSequence edgeCharacters, Object value, List childNodes, boolean isRoot); + Node createNode(CharSequence edgeCharacters, Object value, NodeList childNodes, boolean isRoot); } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/NodeList.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/NodeList.java new file mode 100644 index 0000000..3bea2cd --- /dev/null +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/NodeList.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2013 Niall Gallagher + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.googlecode.concurrenttrees.radix.node; + +import java.util.Collection; + +/** + * A list of {@link Node}s represented by a tree. This interface is used rather then a Java list, + * to allow representing concurrent arrays as such lists and to avoid allocating wrapper instances. + */ +public interface NodeList { + + int size(); + + Node get(int index); + + boolean isEmpty(); + + void set(int index, Node node); + + boolean contains(Node node); + + void addTo(Collection nodes); + + Node[] toArray(); +} diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/SimpleNodeList.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/SimpleNodeList.java new file mode 100644 index 0000000..cfd4b58 --- /dev/null +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/SimpleNodeList.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012-2013 Niall Gallagher + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.googlecode.concurrenttrees.radix.node; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * A simple implementation of a {@link NodeList} backed by a {@link List}. + */ +public class SimpleNodeList implements NodeList { + + private final List nodes; + + public static final NodeList EMPTY = new SimpleNodeList(); + + SimpleNodeList() { + this.nodes = Collections.emptyList(); + } + + public SimpleNodeList(Node node) { + this.nodes = Collections.singletonList(node); + } + + public SimpleNodeList(Node... nodes) { + this.nodes = Arrays.asList(nodes); + } + + public SimpleNodeList(List nodes) { + this.nodes = nodes; + } + + @Override + public int size() { + return nodes.size(); + } + + @Override + public Node get(int index) { + return nodes.get(index); + } + + @Override + public boolean contains(Node node) { + return nodes.contains(node); + } + + @Override + public boolean isEmpty() { + return nodes.isEmpty(); + } + + @Override + public void set(int index, Node node) { + nodes.set(index, node); + } + + @Override + public void addTo(Collection nodes) { + nodes.addAll(this.nodes); + } + + @Override + public Node[] toArray() { + return nodes.toArray(new Node[0]); + } + + @Override + public String toString() { + return nodes.toString(); + } +} diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultByteArrayNodeFactory.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultByteArrayNodeFactory.java index 3566ed3..e4b478d 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultByteArrayNodeFactory.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultByteArrayNodeFactory.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,12 +18,11 @@ import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; +import com.googlecode.concurrenttrees.radix.node.NodeList; import com.googlecode.concurrenttrees.radix.node.concrete.bytearray.*; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; -import java.util.List; - /** * A {@link NodeFactory} which creates {@link Node} objects which store incoming edge characters as a byte array inside * the node. This is similar to {@link DefaultCharArrayNodeFactory}, except nodes use a single byte to represent each @@ -37,40 +36,50 @@ */ public class DefaultByteArrayNodeFactory implements NodeFactory { + private static final long serialVersionUID = 1L; + + private final boolean fast; + + public DefaultByteArrayNodeFactory() { + fast = false; + } + + DefaultByteArrayNodeFactory(boolean fast) { + this.fast = fast; + } + @Override - public Node createNode(CharSequence edgeCharacters, Object value, List childNodes, boolean isRoot) { - if (edgeCharacters == null) { - throw new IllegalStateException("The edgeCharacters argument was null"); - } - if (!isRoot && edgeCharacters.length() == 0) { - throw new IllegalStateException("Invalid edge characters for non-root node: " + CharSequences.toString(edgeCharacters)); - } - if (childNodes == null) { - throw new IllegalStateException("The childNodes argument was null"); + public Node createNode(CharSequence edgeCharacters, Object value, NodeList childNodes, boolean isRoot) { + assert edgeCharacters != null : "The edgeCharacters argument was null"; + assert isRoot || edgeCharacters.length() > 0 : "Invalid edge characters for non-root node: " + CharSequences.toString(edgeCharacters); + assert childNodes != null : "The edgeCharacters argument was null"; + assert NodeUtil.hasNoDuplicateEdges(childNodes) : "Duplicate edge detected in list of nodes supplied: " + childNodes; + byte[] incomingEdgeCharArray = ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharacters, fast); + if (incomingEdgeCharArray == null) { + return null; } - NodeUtil.ensureNoDuplicateEdges(childNodes); if (childNodes.isEmpty()) { // Leaf node... if (value instanceof VoidValue) { - return new ByteArrayNodeLeafVoidValue(edgeCharacters); + return new ByteArrayNodeLeafVoidValue(incomingEdgeCharArray); } else if (value != null) { - return new ByteArrayNodeLeafWithValue(edgeCharacters, value); + return new ByteArrayNodeLeafWithValue(incomingEdgeCharArray, value); } else { - return new ByteArrayNodeLeafNullValue(edgeCharacters); + return new ByteArrayNodeLeafNullValue(incomingEdgeCharArray); } } else { // Non-leaf node... if (value instanceof VoidValue) { - return new ByteArrayNodeNonLeafVoidValue(edgeCharacters, childNodes); + return new ByteArrayNodeNonLeafVoidValue(incomingEdgeCharArray, childNodes); } else if (value == null) { - return new ByteArrayNodeNonLeafNullValue(edgeCharacters, childNodes); + return new ByteArrayNodeNonLeafNullValue(incomingEdgeCharArray, childNodes); } else { - return new ByteArrayNodeDefault(edgeCharacters, value, childNodes); + return new ByteArrayNodeDefault(incomingEdgeCharArray, value, childNodes); } } } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharArrayNodeFactory.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharArrayNodeFactory.java index d6f76ad..3c9fca9 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharArrayNodeFactory.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharArrayNodeFactory.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,14 +15,13 @@ */ package com.googlecode.concurrenttrees.radix.node.concrete; +import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; +import com.googlecode.concurrenttrees.radix.node.NodeList; import com.googlecode.concurrenttrees.radix.node.concrete.chararray.*; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; -import com.googlecode.concurrenttrees.common.CharSequences; - -import java.util.List; /** * A {@link NodeFactory} which creates various implementations of {@link Node} objects all of which store incoming @@ -44,18 +43,14 @@ */ public class DefaultCharArrayNodeFactory implements NodeFactory { + private static final long serialVersionUID = 1L; + @Override - public Node createNode(CharSequence edgeCharacters, Object value, List childNodes, boolean isRoot) { - if (edgeCharacters == null) { - throw new IllegalStateException("The edgeCharacters argument was null"); - } - if (!isRoot && edgeCharacters.length() == 0) { - throw new IllegalStateException("Invalid edge characters for non-root node: " + CharSequences.toString(edgeCharacters)); - } - if (childNodes == null) { - throw new IllegalStateException("The childNodes argument was null"); - } - NodeUtil.ensureNoDuplicateEdges(childNodes); + public Node createNode(CharSequence edgeCharacters, Object value, NodeList childNodes, boolean isRoot) { + assert edgeCharacters != null : "The edgeCharacters argument was null"; + assert isRoot || edgeCharacters.length() > 0 : "Invalid edge characters for non-root node: " + CharSequences.toString(edgeCharacters); + assert childNodes != null : "The edgeCharacters argument was null"; + assert NodeUtil.hasNoDuplicateEdges(childNodes) : "Duplicate edge detected in list of nodes supplied: " + childNodes; if (childNodes.isEmpty()) { // Leaf node... if (value instanceof VoidValue) { diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharSequenceNodeFactory.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharSequenceNodeFactory.java index a873422..347ec88 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharSequenceNodeFactory.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharSequenceNodeFactory.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,12 +18,11 @@ import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; +import com.googlecode.concurrenttrees.radix.node.NodeList; import com.googlecode.concurrenttrees.radix.node.concrete.charsequence.*; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; -import java.util.List; - /** * A {@link NodeFactory} which creates various implementations of {@link Node} objects all of which store incoming * edge characters as a {@link CharSequence} (a view onto the original key) rather than copying the edge into a @@ -45,19 +44,14 @@ */ public class DefaultCharSequenceNodeFactory implements NodeFactory { - @Override - public Node createNode(CharSequence edgeCharacters, Object value, List childNodes, boolean isRoot) { - if (edgeCharacters == null) { - throw new IllegalStateException("The edgeCharacters argument was null"); - } - if (!isRoot && edgeCharacters.length() == 0) { - throw new IllegalStateException("Invalid edge characters for non-root node: " + CharSequences.toString(edgeCharacters)); - } - if (childNodes == null) { - throw new IllegalStateException("The childNodes argument was null"); - } - NodeUtil.ensureNoDuplicateEdges(childNodes); + private static final long serialVersionUID = 1L; + @Override + public Node createNode(CharSequence edgeCharacters, Object value, NodeList childNodes, boolean isRoot) { + assert edgeCharacters != null : "The edgeCharacters argument was null"; + assert isRoot || edgeCharacters.length() > 0 : "Invalid edge characters for non-root node: " + CharSequences.toString(edgeCharacters); + assert childNodes != null : "The edgeCharacters argument was null"; + assert NodeUtil.hasNoDuplicateEdges(childNodes) : "Duplicate edge detected in list of nodes supplied: " + childNodes; if (childNodes.isEmpty()) { // Leaf node... diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/SmartArrayBasedNodeFactory.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/SmartArrayBasedNodeFactory.java index cd6e0db..582664b 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/SmartArrayBasedNodeFactory.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/SmartArrayBasedNodeFactory.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,10 +17,9 @@ import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; +import com.googlecode.concurrenttrees.radix.node.NodeList; import com.googlecode.concurrenttrees.radix.node.concrete.bytearray.ByteArrayCharSequence; -import java.util.List; - /** * A {@link NodeFactory} which internally uses {@link DefaultByteArrayNodeFactory} to create nodes by default (which * can reduce memory overhead), but falls back to {@link DefaultCharArrayNodeFactory} if characters are detected which @@ -30,16 +29,18 @@ */ public class SmartArrayBasedNodeFactory implements NodeFactory { + private static final long serialVersionUID = 1L; + final NodeFactory charArrayNodeFactory = new DefaultCharArrayNodeFactory(); - final NodeFactory byteArrayNodeFactory = new DefaultByteArrayNodeFactory(); + final NodeFactory byteArrayNodeFactory = new DefaultByteArrayNodeFactory(true); @Override - public Node createNode(CharSequence edgeCharacters, Object value, List childNodes, boolean isRoot) { - try { - return byteArrayNodeFactory.createNode(edgeCharacters, value, childNodes, isRoot); - } - catch (ByteArrayCharSequence.IncompatibleCharacterException e) { + public Node createNode(CharSequence edgeCharacters, Object value, NodeList childNodes, boolean isRoot) { + Node node = byteArrayNodeFactory.createNode(edgeCharacters, value, childNodes, isRoot); + if (node == null) { return charArrayNodeFactory.createNode(edgeCharacters, value, childNodes, isRoot); + } else { + return node; } } } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayCharSequence.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayCharSequence.java index a38f99c..06f5fa1 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayCharSequence.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayCharSequence.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -71,12 +71,20 @@ public String toString() { * @throws IllegalStateException If the characters cannot be encoded as described */ public static byte[] toSingleByteUtf8Encoding(CharSequence charSequence) { + return toSingleByteUtf8Encoding(charSequence, false); + } + + public static byte[] toSingleByteUtf8Encoding(CharSequence charSequence, boolean nullIfIncompatible) { final int length = charSequence.length(); byte[] bytes = new byte[length]; for (int i = 0; i < length; i++) { char inputChar = charSequence.charAt(i); if (inputChar > 255) { - throw new IncompatibleCharacterException("Input contains a character which cannot be represented as a single byte in UTF-8: " + inputChar); + if (nullIfIncompatible) { + return null; + } else { + throw new IncompatibleCharacterException("Input contains a character which cannot be represented as a single byte in UTF-8: " + inputChar); + } } bytes[i] = (byte)inputChar; } @@ -84,6 +92,9 @@ public static byte[] toSingleByteUtf8Encoding(CharSequence charSequence) { } public static class IncompatibleCharacterException extends IllegalStateException { + + private static final long serialVersionUID = 1L; + public IncompatibleCharacterException(String s) { super(s); } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeDefault.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeDefault.java index 067b03b..12ced1a 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeDefault.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeDefault.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,13 +16,12 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.util.AtomicNodeReferenceArray; import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * Similar to {@link com.googlecode.concurrenttrees.radix.node.concrete.chararray.CharArrayNodeDefault} but represents @@ -35,6 +34,7 @@ */ public class ByteArrayNodeDefault implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -43,23 +43,23 @@ public class ByteArrayNodeDefault implements Node { // References to child nodes representing outgoing edges from this node. // Once assigned we never add or remove references, but we do update existing references to point to new child // nodes provided new edges start with the same first character... - private final AtomicReferenceArray outgoingEdges; - - // A read-only List wrapper around the outgoingEdges AtomicReferenceArray... - private final List outgoingEdgesAsList; + private final AtomicNodeReferenceArray outgoingEdges; // An arbitrary value which the application associates with a key matching the path to this node in the tree. // This value can be null... private final Object value; - public ByteArrayNodeDefault(CharSequence edgeCharSequence, Object value, List outgoingEdges) { - Node[] childNodeArray = outgoingEdges.toArray(new Node[outgoingEdges.size()]); + public ByteArrayNodeDefault(CharSequence edgeCharSequence, Object value, NodeList outgoingEdges) { + this(ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence), value, outgoingEdges); + } + + public ByteArrayNodeDefault(byte[] incomingEdgeCharArray, Object value, NodeList outgoingEdges) { + Node[] childNodeArray = outgoingEdges.toArray(); // Sort the child nodes... - Arrays.sort(childNodeArray, new NodeCharacterComparator()); - this.outgoingEdges = new AtomicReferenceArray(childNodeArray); - this.incomingEdgeCharArray = ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence); + Arrays.sort(childNodeArray, NodeCharacterComparator.SINGLETON); + this.outgoingEdges = new AtomicNodeReferenceArray(childNodeArray); + this.incomingEdgeCharArray = incomingEdgeCharArray; this.value = value; - this.outgoingEdgesAsList = new AtomicReferenceArrayListAdapter(this.outgoingEdges); } @Override @@ -68,7 +68,17 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return (char) (incomingEdgeCharArray[index] & 0xFF); + } + + @Override + public char getIncomingEdgeFirstCharacter() { return (char) (incomingEdgeCharArray[0] & 0xFF); } @@ -78,7 +88,7 @@ public Object getValue() { } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { // 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... @@ -105,8 +115,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return outgoingEdgesAsList; + public NodeList getOutgoingEdges() { + return outgoingEdges; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafNullValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafNullValue.java index 5877be7..79256d7 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafNullValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafNullValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +16,8 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; - -import java.util.Collections; -import java.util.List; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; /** * Similar to {@link com.googlecode.concurrenttrees.radix.node.concrete.chararray.CharArrayNodeLeafNullValue} but represents @@ -31,13 +30,18 @@ */ public class ByteArrayNodeLeafNullValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... private final byte[] incomingEdgeCharArray; public ByteArrayNodeLeafNullValue(CharSequence edgeCharSequence) { - this.incomingEdgeCharArray = ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence); + this(ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence)); + } + + public ByteArrayNodeLeafNullValue(byte[] incomingEdgeCharArray) { + this.incomingEdgeCharArray = incomingEdgeCharArray; } @Override @@ -46,17 +50,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return (char) (incomingEdgeCharArray[0] & 0xFF); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return (char) (incomingEdgeCharArray[index] & 0xFF); + } + @Override public Object getValue() { return null; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { return null; } @@ -66,8 +80,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return Collections.emptyList(); + public NodeList getOutgoingEdges() { + return SimpleNodeList.EMPTY; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafVoidValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafVoidValue.java index ea7bd4d..6dc9266 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafVoidValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafVoidValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; -import java.util.Collections; -import java.util.List; - /** * Similar to {@link com.googlecode.concurrenttrees.radix.node.concrete.chararray.CharArrayNodeLeafVoidValue} but represents * each character in UTF-8, instead of Java's default 2-byte UFT-16 encoding. @@ -32,12 +31,18 @@ */ public class ByteArrayNodeLeafVoidValue implements Node { + private static final long serialVersionUID = 1L; + // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... private final byte[] incomingEdgeCharArray; public ByteArrayNodeLeafVoidValue(CharSequence edgeCharSequence) { - this.incomingEdgeCharArray = ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence); + this(ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence)); + } + + public ByteArrayNodeLeafVoidValue(byte[] incomingEdgeCharArray) { + this.incomingEdgeCharArray = incomingEdgeCharArray; } @Override @@ -46,17 +51,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return (char) (incomingEdgeCharArray[0] & 0xFF); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return (char) (incomingEdgeCharArray[index] & 0xFF); + } + @Override public Object getValue() { return VoidValue.SINGLETON; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { return null; } @@ -66,8 +81,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return Collections.emptyList(); + public NodeList getOutgoingEdges() { + return SimpleNodeList.EMPTY; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafWithValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafWithValue.java index d0b10bd..8e4306c 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafWithValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafWithValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +16,8 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; - -import java.util.Collections; -import java.util.List; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; /** * Similar to {@link com.googlecode.concurrenttrees.radix.node.concrete.chararray.CharArrayNodeLeafWithValue} but represents @@ -31,6 +30,7 @@ */ public class ByteArrayNodeLeafWithValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -41,7 +41,11 @@ public class ByteArrayNodeLeafWithValue implements Node { private final Object value; public ByteArrayNodeLeafWithValue(CharSequence edgeCharSequence, Object value) { - this.incomingEdgeCharArray = ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence); + this(ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence), value); + } + + public ByteArrayNodeLeafWithValue(byte[] incomingEdgeCharArray, Object value) { + this.incomingEdgeCharArray = incomingEdgeCharArray; this.value = value; } @@ -51,17 +55,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return (char) (incomingEdgeCharArray[0] & 0xFF); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return (char) (incomingEdgeCharArray[index] & 0xFF); + } + @Override public Object getValue() { return value; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { return null; } @@ -71,8 +85,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return Collections.emptyList(); + public NodeList getOutgoingEdges() { + return SimpleNodeList.EMPTY; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafNullValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafNullValue.java index c2ce78b..6959d51 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafNullValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafNullValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,13 +16,12 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.util.AtomicNodeReferenceArray; import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * Similar to {@link com.googlecode.concurrenttrees.radix.node.concrete.chararray.CharArrayNodeNonLeafNullValue} but represents @@ -35,6 +34,7 @@ */ public class ByteArrayNodeNonLeafNullValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -43,18 +43,18 @@ public class ByteArrayNodeNonLeafNullValue implements Node { // References to child nodes representing outgoing edges from this node. // Once assigned we never add or remove references, but we do update existing references to point to new child // nodes provided new edges start with the same first character... - private final AtomicReferenceArray outgoingEdges; + private final AtomicNodeReferenceArray outgoingEdges; - // A read-only List wrapper around the outgoingEdges AtomicReferenceArray... - private final List outgoingEdgesAsList; + public ByteArrayNodeNonLeafNullValue(CharSequence edgeCharSequence, NodeList outgoingEdges) { + this(ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence), outgoingEdges); + } - public ByteArrayNodeNonLeafNullValue(CharSequence edgeCharSequence, List outgoingEdges) { - Node[] childNodeArray = outgoingEdges.toArray(new Node[outgoingEdges.size()]); + public ByteArrayNodeNonLeafNullValue(byte[] incomingEdgeCharArray, NodeList outgoingEdges) { + Node[] childNodeArray = outgoingEdges.toArray(); // Sort the child nodes... - Arrays.sort(childNodeArray, new NodeCharacterComparator()); - this.outgoingEdges = new AtomicReferenceArray(childNodeArray); - this.incomingEdgeCharArray = ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence); - this.outgoingEdgesAsList = new AtomicReferenceArrayListAdapter(this.outgoingEdges); + Arrays.sort(childNodeArray, NodeCharacterComparator.SINGLETON); + this.outgoingEdges = new AtomicNodeReferenceArray(childNodeArray); + this.incomingEdgeCharArray = incomingEdgeCharArray; } @Override @@ -63,17 +63,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return (char) (incomingEdgeCharArray[0] & 0xFF); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return (char) (incomingEdgeCharArray[index] & 0xFF); + } + @Override public Object getValue() { return null; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { // 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... @@ -100,8 +110,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return outgoingEdgesAsList; + public NodeList getOutgoingEdges() { + return outgoingEdges; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafVoidValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafVoidValue.java index 9ce524d..4fa907d 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafVoidValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafVoidValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,14 +16,13 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; +import com.googlecode.concurrenttrees.radix.node.util.AtomicNodeReferenceArray; import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * Similar to {@link com.googlecode.concurrenttrees.radix.node.concrete.chararray.CharArrayNodeNonLeafVoidValue} but represents @@ -36,6 +35,8 @@ */ public class ByteArrayNodeNonLeafVoidValue implements Node { + private static final long serialVersionUID = 1L; + // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... private final byte[] incomingEdgeCharArray; @@ -43,18 +44,18 @@ public class ByteArrayNodeNonLeafVoidValue implements Node { // References to child nodes representing outgoing edges from this node. // Once assigned we never add or remove references, but we do update existing references to point to new child // nodes provided new edges start with the same first character... - private final AtomicReferenceArray outgoingEdges; + private final AtomicNodeReferenceArray outgoingEdges; - // A read-only List wrapper around the outgoingEdges AtomicReferenceArray... - private final List outgoingEdgesAsList; + public ByteArrayNodeNonLeafVoidValue(CharSequence edgeCharSequence, NodeList outgoingEdges) { + this(ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence), outgoingEdges); + } - public ByteArrayNodeNonLeafVoidValue(CharSequence edgeCharSequence, List outgoingEdges) { - Node[] childNodeArray = outgoingEdges.toArray(new Node[outgoingEdges.size()]); + public ByteArrayNodeNonLeafVoidValue(byte[] incomingEdgeCharArray, NodeList outgoingEdges) { + Node[] childNodeArray = outgoingEdges.toArray(); // Sort the child nodes... - Arrays.sort(childNodeArray, new NodeCharacterComparator()); - this.outgoingEdges = new AtomicReferenceArray(childNodeArray); - this.incomingEdgeCharArray = ByteArrayCharSequence.toSingleByteUtf8Encoding(edgeCharSequence); - this.outgoingEdgesAsList = new AtomicReferenceArrayListAdapter(this.outgoingEdges); + Arrays.sort(childNodeArray, NodeCharacterComparator.SINGLETON); + this.outgoingEdges = new AtomicNodeReferenceArray(childNodeArray); + this.incomingEdgeCharArray = incomingEdgeCharArray; } @Override @@ -63,17 +64,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return (char) (incomingEdgeCharArray[0] & 0xFF); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return (char) (incomingEdgeCharArray[index] & 0xFF); + } + @Override public Object getValue() { return VoidValue.SINGLETON; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { // 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... @@ -100,8 +111,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return outgoingEdgesAsList; + public NodeList getOutgoingEdges() { + return outgoingEdges; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeDefault.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeDefault.java index 67b3ae8..f6bb728 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeDefault.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeDefault.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,14 +15,14 @@ */ package com.googlecode.concurrenttrees.radix.node.concrete.chararray; +import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.util.AtomicNodeReferenceArray; import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; -import com.googlecode.concurrenttrees.common.CharSequences; import java.util.Arrays; -import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; /** @@ -36,7 +36,7 @@ * This implementation stores references to child nodes in an {@link AtomicReferenceArray}, in ascending sorted order * of the first character of the edges which child nodes define. *

- * The {@link #getOutgoingEdge(Character)} method uses binary search to locate a requested node, given the first character + * The {@link #getOutgoingEdge(char)} method uses binary search to locate a requested node, given the first character * of an edge indicated. The node is then read and returned atomically from the {@link AtomicReferenceArray}. *

* The {@link #updateOutgoingEdge(com.googlecode.concurrenttrees.radix.node.Node)} method ensures that any @@ -51,6 +51,7 @@ */ public class CharArrayNodeDefault implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -59,23 +60,19 @@ public class CharArrayNodeDefault implements Node { // References to child nodes representing outgoing edges from this node. // Once assigned we never add or remove references, but we do update existing references to point to new child // nodes provided new edges start with the same first character... - private final AtomicReferenceArray outgoingEdges; - - // A read-only List wrapper around the outgoingEdges AtomicReferenceArray... - private final List outgoingEdgesAsList; + private final AtomicNodeReferenceArray outgoingEdges; // An arbitrary value which the application associates with a key matching the path to this node in the tree. // This value can be null... private final Object value; - public CharArrayNodeDefault(CharSequence edgeCharSequence, Object value, List outgoingEdges) { - Node[] childNodeArray = outgoingEdges.toArray(new Node[outgoingEdges.size()]); + public CharArrayNodeDefault(CharSequence edgeCharSequence, Object value, NodeList outgoingEdges) { + Node[] childNodeArray = outgoingEdges.toArray(); // Sort the child nodes... - Arrays.sort(childNodeArray, new NodeCharacterComparator()); - this.outgoingEdges = new AtomicReferenceArray(childNodeArray); + Arrays.sort(childNodeArray, NodeCharacterComparator.SINGLETON); + this.outgoingEdges = new AtomicNodeReferenceArray(childNodeArray); this.incomingEdgeCharArray = CharSequences.toCharArray(edgeCharSequence); this.value = value; - this.outgoingEdgesAsList = new AtomicReferenceArrayListAdapter(this.outgoingEdges); } @Override @@ -84,17 +81,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharArray[0]; } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharArray[index]; + } + @Override public Object getValue() { return value; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { // 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... @@ -121,8 +128,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return outgoingEdgesAsList; + public NodeList getOutgoingEdges() { + return outgoingEdges; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafNullValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafNullValue.java index 67b67e2..6e37ee8 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafNullValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafNullValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,9 +17,8 @@ import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.radix.node.Node; - -import java.util.Collections; -import java.util.List; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; /** * Stores only incoming edge as a {@code char[]}. @@ -29,6 +28,7 @@ */ public class CharArrayNodeLeafNullValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -44,17 +44,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharArray[0]; } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharArray[index]; + } + @Override public Object getValue() { return null; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { return null; } @@ -64,8 +74,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return Collections.emptyList(); + public NodeList getOutgoingEdges() { + return SimpleNodeList.EMPTY; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafVoidValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafVoidValue.java index f699aee..7a5e7e7 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafVoidValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafVoidValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,11 +17,10 @@ import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; -import java.util.Collections; -import java.util.List; - /** * Stores only incoming edge as a {@code char[]}. * Returns {@link VoidValue} for the value. Does not store any outgoing edges. @@ -30,6 +29,8 @@ */ public class CharArrayNodeLeafVoidValue implements Node { + private static final long serialVersionUID = 1L; + // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... private final char[] incomingEdgeCharArray; @@ -44,17 +45,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharArray[0]; } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharArray[index]; + } + @Override public Object getValue() { return VoidValue.SINGLETON; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { return null; } @@ -64,8 +75,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return Collections.emptyList(); + public NodeList getOutgoingEdges() { + return SimpleNodeList.EMPTY; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafWithValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafWithValue.java index 400ced0..c392ab0 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafWithValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafWithValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,9 +17,8 @@ import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.radix.node.Node; - -import java.util.Collections; -import java.util.List; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; /** * Stores only incoming edge as a {@code char[]}, and a reference to a value. Does not store any outgoing @@ -29,6 +28,7 @@ */ public class CharArrayNodeLeafWithValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -49,17 +49,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharArray[0]; } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharArray[index]; + } + @Override public Object getValue() { return value; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { return null; } @@ -69,8 +79,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return Collections.emptyList(); + public NodeList getOutgoingEdges() { + return SimpleNodeList.EMPTY; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafNullValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafNullValue.java index 0699312..3e906c4 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafNullValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafNullValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,12 +17,12 @@ import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.radix.node.Node; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.util.AtomicNodeReferenceArray; import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; import java.util.Arrays; -import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; /** @@ -33,6 +33,7 @@ */ public class CharArrayNodeNonLeafNullValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -41,18 +42,14 @@ public class CharArrayNodeNonLeafNullValue implements Node { // References to child nodes representing outgoing edges from this node. // Once assigned we never add or remove references, but we do update existing references to point to new child // nodes provided new edges start with the same first character... - private final AtomicReferenceArray outgoingEdges; - - // A read-only List wrapper around the outgoingEdges AtomicReferenceArray... - private final List outgoingEdgesAsList; + private final AtomicNodeReferenceArray outgoingEdges; - public CharArrayNodeNonLeafNullValue(CharSequence edgeCharSequence, List outgoingEdges) { - Node[] childNodeArray = outgoingEdges.toArray(new Node[outgoingEdges.size()]); + public CharArrayNodeNonLeafNullValue(CharSequence edgeCharSequence, NodeList outgoingEdges) { + Node[] childNodeArray = outgoingEdges.toArray(); // Sort the child nodes... - Arrays.sort(childNodeArray, new NodeCharacterComparator()); - this.outgoingEdges = new AtomicReferenceArray(childNodeArray); + Arrays.sort(childNodeArray, NodeCharacterComparator.SINGLETON); + this.outgoingEdges = new AtomicNodeReferenceArray(childNodeArray); this.incomingEdgeCharArray = CharSequences.toCharArray(edgeCharSequence); - this.outgoingEdgesAsList = new AtomicReferenceArrayListAdapter(this.outgoingEdges); } @Override @@ -61,17 +58,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharArray[0]; } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharArray[index]; + } + @Override public Object getValue() { return null; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { // 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... @@ -98,8 +105,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return outgoingEdgesAsList; + public NodeList getOutgoingEdges() { + return outgoingEdges; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafVoidValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafVoidValue.java index abdbbbe..f5be6c9 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafVoidValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafVoidValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,13 +17,13 @@ import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; +import com.googlecode.concurrenttrees.radix.node.util.AtomicNodeReferenceArray; import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; import java.util.Arrays; -import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; /** @@ -34,6 +34,8 @@ */ public class CharArrayNodeNonLeafVoidValue implements Node { + private static final long serialVersionUID = 1L; + // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... private final char[] incomingEdgeCharArray; @@ -41,18 +43,14 @@ public class CharArrayNodeNonLeafVoidValue implements Node { // References to child nodes representing outgoing edges from this node. // Once assigned we never add or remove references, but we do update existing references to point to new child // nodes provided new edges start with the same first character... - private final AtomicReferenceArray outgoingEdges; - - // A read-only List wrapper around the outgoingEdges AtomicReferenceArray... - private final List outgoingEdgesAsList; + private final AtomicNodeReferenceArray outgoingEdges; - public CharArrayNodeNonLeafVoidValue(CharSequence edgeCharSequence, List outgoingEdges) { - Node[] childNodeArray = outgoingEdges.toArray(new Node[outgoingEdges.size()]); + public CharArrayNodeNonLeafVoidValue(CharSequence edgeCharSequence, NodeList outgoingEdges) { + Node[] childNodeArray = outgoingEdges.toArray(); // Sort the child nodes... - Arrays.sort(childNodeArray, new NodeCharacterComparator()); - this.outgoingEdges = new AtomicReferenceArray(childNodeArray); + Arrays.sort(childNodeArray, NodeCharacterComparator.SINGLETON); + this.outgoingEdges = new AtomicNodeReferenceArray(childNodeArray); this.incomingEdgeCharArray = CharSequences.toCharArray(edgeCharSequence); - this.outgoingEdgesAsList = new AtomicReferenceArrayListAdapter(this.outgoingEdges); } @Override @@ -61,17 +59,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharArray[0]; } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharArray.length; + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharArray[index]; + } + @Override public Object getValue() { return VoidValue.SINGLETON; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { // 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... @@ -98,8 +106,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return outgoingEdgesAsList; + public NodeList getOutgoingEdges() { + return outgoingEdges; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeDefault.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeDefault.java index ef451f8..627c03d 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeDefault.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeDefault.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,12 +16,12 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.util.AtomicNodeReferenceArray; import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; import java.util.Arrays; -import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; /** @@ -36,7 +36,7 @@ * This implementation stores references to child nodes in an {@link AtomicReferenceArray}, in ascending sorted order * of the first character of the edges which child nodes define. *

- * The {@link #getOutgoingEdge(Character)} method uses binary search to locate a requested node, given the first character + * The {@link #getOutgoingEdge(char)} method uses binary search to locate a requested node, given the first character * of an edge indicated. The node is then read and returned atomically from the {@link AtomicReferenceArray}. *

* The {@link #updateOutgoingEdge(com.googlecode.concurrenttrees.radix.node.Node)} method ensures that any @@ -51,6 +51,7 @@ */ public class CharSequenceNodeDefault implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -59,23 +60,19 @@ public class CharSequenceNodeDefault implements Node { // References to child nodes representing outgoing edges from this node. // Once assigned we never add or remove references, but we do update existing references to point to new child // nodes provided new edges start with the same first character... - private final AtomicReferenceArray outgoingEdges; - - // A read-only List wrapper around the outgoingEdges AtomicReferenceArray... - private final List outgoingEdgesAsList; + private final AtomicNodeReferenceArray outgoingEdges; // An arbitrary value which the application associates with a key matching the path to this node in the tree. // This value can be null... private final Object value; - public CharSequenceNodeDefault(CharSequence edgeCharSequence, Object value, List outgoingEdges) { - Node[] childNodeArray = outgoingEdges.toArray(new Node[outgoingEdges.size()]); + public CharSequenceNodeDefault(CharSequence edgeCharSequence, Object value, NodeList outgoingEdges) { + Node[] childNodeArray = outgoingEdges.toArray(); // Sort the child nodes... - Arrays.sort(childNodeArray, new NodeCharacterComparator()); - this.outgoingEdges = new AtomicReferenceArray(childNodeArray); + Arrays.sort(childNodeArray, NodeCharacterComparator.SINGLETON); + this.outgoingEdges = new AtomicNodeReferenceArray(childNodeArray); this.incomingEdgeCharSequence = edgeCharSequence; this.value = value; - this.outgoingEdgesAsList = new AtomicReferenceArrayListAdapter(this.outgoingEdges); } @Override @@ -84,17 +81,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharSequence.charAt(0); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharSequence.length(); + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharSequence.charAt(index); + } + @Override public Object getValue() { return value; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { // 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... @@ -121,8 +128,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return outgoingEdgesAsList; + public NodeList getOutgoingEdges() { + return outgoingEdges; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafNullValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafNullValue.java index 9a6013f..c428ccd 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafNullValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafNullValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +16,8 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; - -import java.util.Collections; -import java.util.List; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; /** * Stores only incoming edge as a {@link CharSequence} (a view onto the original key) rather than copying the @@ -28,6 +27,7 @@ */ public class CharSequenceNodeLeafNullValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -43,17 +43,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharSequence.charAt(0); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharSequence.length(); + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharSequence.charAt(index); + } + @Override public Object getValue() { return null; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { return null; } @@ -63,8 +73,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return Collections.emptyList(); + public NodeList getOutgoingEdges() { + return SimpleNodeList.EMPTY; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafVoidValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafVoidValue.java index 971aac7..a880378 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafVoidValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafVoidValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,15 +16,9 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; -import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; -import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; /** * Stores only incoming edge as a {@link CharSequence} (a view onto the original key) rather than copying the @@ -34,6 +28,7 @@ */ public class CharSequenceNodeLeafVoidValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -49,17 +44,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharSequence.charAt(0); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharSequence.length(); + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharSequence.charAt(index); + } + @Override public Object getValue() { return VoidValue.SINGLETON; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { return null; } @@ -69,8 +74,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return Collections.emptyList(); + public NodeList getOutgoingEdges() { + return SimpleNodeList.EMPTY; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafWithValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafWithValue.java index 5618f1c..f11eef4 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafWithValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafWithValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,14 +16,8 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; -import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; -import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicReferenceArray; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; /** * Stores incoming edge as a {@link CharSequence} (a view onto the original key) rather than copying the @@ -33,6 +27,7 @@ */ public class CharSequenceNodeLeafWithValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -54,17 +49,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharSequence.charAt(0); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharSequence.length(); + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharSequence.charAt(index); + } + @Override public Object getValue() { return value; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { return null; } @@ -74,8 +79,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return Collections.emptyList(); + public NodeList getOutgoingEdges() { + return SimpleNodeList.EMPTY; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafNullValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafNullValue.java index be43710..cdeb351 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafNullValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafNullValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,12 +16,12 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; +import com.googlecode.concurrenttrees.radix.node.NodeList; +import com.googlecode.concurrenttrees.radix.node.util.AtomicNodeReferenceArray; import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; import java.util.Arrays; -import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; /** @@ -33,6 +33,7 @@ */ public class CharSequenceNodeNonLeafNullValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -41,18 +42,14 @@ public class CharSequenceNodeNonLeafNullValue implements Node { // References to child nodes representing outgoing edges from this node. // Once assigned we never add or remove references, but we do update existing references to point to new child // nodes provided new edges start with the same first character... - private final AtomicReferenceArray outgoingEdges; - - // A read-only List wrapper around the outgoingEdges AtomicReferenceArray... - private final List outgoingEdgesAsList; + private final AtomicNodeReferenceArray outgoingEdges; - public CharSequenceNodeNonLeafNullValue(CharSequence edgeCharSequence, List outgoingEdges) { - Node[] childNodeArray = outgoingEdges.toArray(new Node[outgoingEdges.size()]); + public CharSequenceNodeNonLeafNullValue(CharSequence edgeCharSequence, NodeList outgoingEdges) { + Node[] childNodeArray = outgoingEdges.toArray(); // Sort the child nodes... - Arrays.sort(childNodeArray, new NodeCharacterComparator()); - this.outgoingEdges = new AtomicReferenceArray(childNodeArray); + Arrays.sort(childNodeArray, NodeCharacterComparator.SINGLETON); + this.outgoingEdges = new AtomicNodeReferenceArray(childNodeArray); this.incomingEdgeCharSequence = edgeCharSequence; - this.outgoingEdgesAsList = new AtomicReferenceArrayListAdapter(this.outgoingEdges); } @Override @@ -61,17 +58,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharSequence.charAt(0); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharSequence.length(); + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharSequence.charAt(index); + } + @Override public Object getValue() { return null; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { // 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... @@ -98,8 +105,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return outgoingEdgesAsList; + public NodeList getOutgoingEdges() { + return outgoingEdges; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafVoidValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafVoidValue.java index b320440..51c97a8 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafVoidValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafVoidValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,13 +16,13 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; -import com.googlecode.concurrenttrees.radix.node.util.AtomicReferenceArrayListAdapter; +import com.googlecode.concurrenttrees.radix.node.util.AtomicNodeReferenceArray; import com.googlecode.concurrenttrees.radix.node.util.NodeCharacterComparator; import com.googlecode.concurrenttrees.radix.node.util.NodeUtil; import java.util.Arrays; -import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; /** @@ -34,6 +34,7 @@ */ public class CharSequenceNodeNonLeafVoidValue implements Node { + private static final long serialVersionUID = 1L; // Characters in the edge arriving at this node from a parent node. // Once assigned, we never modify this... @@ -42,18 +43,14 @@ public class CharSequenceNodeNonLeafVoidValue implements Node { // References to child nodes representing outgoing edges from this node. // Once assigned we never add or remove references, but we do update existing references to point to new child // nodes provided new edges start with the same first character... - private final AtomicReferenceArray outgoingEdges; - - // A read-only List wrapper around the outgoingEdges AtomicReferenceArray... - private final List outgoingEdgesAsList; + private final AtomicNodeReferenceArray outgoingEdges; - public CharSequenceNodeNonLeafVoidValue(CharSequence edgeCharSequence, List outgoingEdges) { - Node[] childNodeArray = outgoingEdges.toArray(new Node[outgoingEdges.size()]); + public CharSequenceNodeNonLeafVoidValue(CharSequence edgeCharSequence, NodeList outgoingEdges) { + Node[] childNodeArray = outgoingEdges.toArray(); // Sort the child nodes... - Arrays.sort(childNodeArray, new NodeCharacterComparator()); - this.outgoingEdges = new AtomicReferenceArray(childNodeArray); + Arrays.sort(childNodeArray, NodeCharacterComparator.SINGLETON); + this.outgoingEdges = new AtomicNodeReferenceArray(childNodeArray); this.incomingEdgeCharSequence = edgeCharSequence; - this.outgoingEdgesAsList = new AtomicReferenceArrayListAdapter(this.outgoingEdges); } @Override @@ -62,17 +59,27 @@ public CharSequence getIncomingEdge() { } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return incomingEdgeCharSequence.charAt(0); } + @Override + public int getIncomingEdgeLength() { + return incomingEdgeCharSequence.length(); + } + + @Override + public char getIncomingEdgeCharacterAt(int index) { + return incomingEdgeCharSequence.charAt(index); + } + @Override public Object getValue() { return VoidValue.SINGLETON; } @Override - public Node getOutgoingEdge(Character edgeFirstCharacter) { + public Node getOutgoingEdge(char edgeFirstCharacter) { // 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... @@ -99,8 +106,8 @@ public void updateOutgoingEdge(Node childNode) { } @Override - public List getOutgoingEdges() { - return outgoingEdgesAsList; + public NodeList getOutgoingEdges() { + return outgoingEdges; } @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/voidvalue/VoidValue.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/voidvalue/VoidValue.java index 6cfffbe..2355fce 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/voidvalue/VoidValue.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/concrete/voidvalue/VoidValue.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/AtomicNodeReferenceArray.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/AtomicNodeReferenceArray.java new file mode 100644 index 0000000..e1ade3e --- /dev/null +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/AtomicNodeReferenceArray.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-2013 Niall Gallagher + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.googlecode.concurrenttrees.radix.node.util; + +import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicReferenceArray; + +public class AtomicNodeReferenceArray extends AtomicReferenceArray implements NodeList { + + private static final long serialVersionUID = 1L; + + public AtomicNodeReferenceArray(Node[] array) { + super(array); + } + + @Override + public int size() { + return length(); + } + + @Override + public boolean isEmpty() { + return length() == 0; + } + + @Override + public boolean contains(Node node) { + for (int index = 0; index < length(); index++) { + if (node == null && get(index) == null || node != null && node.equals(get(index))) { + return true; + } + } + return false; + } + + @Override + public void addTo(Collection nodes) { + for (int index = 0; index < length(); index++) { + nodes.add(get(index)); + } + } + + @Override + public Node[] toArray() { + Node[] nodes = new Node[length()]; + for (int index = 0; index < nodes.length; index++) { + nodes[index] = get(index); + } + return nodes; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (int index = 0; index < length(); index++) { + if (index > 0) { + sb.append(", "); + } + sb.append(get(index)); + } + sb.append(']'); + return sb.toString(); + } +} diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/AtomicReferenceArrayListAdapter.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/AtomicReferenceArrayListAdapter.java deleted file mode 100644 index 26d2567..0000000 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/AtomicReferenceArrayListAdapter.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright 2012-2013 Niall Gallagher - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.googlecode.concurrenttrees.radix.node.util; - -import java.io.Serializable; -import java.util.AbstractList; -import java.util.concurrent.atomic.AtomicReferenceArray; - -/** - * Wraps an {@link AtomicReferenceArray} to implement read-only methods of the {@link java.util.List} interface. - *

- * This enables binary search of an {@link AtomicReferenceArray}, using - * {@link java.util.Collections#binarySearch(java.util.List, Object)}. - * - * @author Niall Gallagher - */ -public class AtomicReferenceArrayListAdapter extends AbstractList implements Serializable { - - private final AtomicReferenceArray atomicReferenceArray; - - public AtomicReferenceArrayListAdapter(AtomicReferenceArray atomicReferenceArray) { - this.atomicReferenceArray = atomicReferenceArray; - } - - @Override - public T get(int index) { - return atomicReferenceArray.get(index); - } - - @Override - public int size() { - return atomicReferenceArray.length(); - } -} diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterComparator.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterComparator.java index fb7b91f..eaf6429 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterComparator.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterComparator.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,8 +25,13 @@ */ public class NodeCharacterComparator implements Comparator { + NodeCharacterComparator() { + } + @Override public int compare(NodeCharacterProvider o1, NodeCharacterProvider o2) { - return o1.getIncomingEdgeFirstCharacter().compareTo(o2.getIncomingEdgeFirstCharacter()); + return o1.getIncomingEdgeFirstCharacter() - o2.getIncomingEdgeFirstCharacter(); } + + public static final Comparator SINGLETON = new NodeCharacterComparator(); } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterKey.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterKey.java index e909005..b15d391 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterKey.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterKey.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,21 +16,21 @@ package com.googlecode.concurrenttrees.radix.node.util; /** - * A lightweight object which simply wraps a {@link Character} and implements {@link NodeCharacterProvider}, which + * A lightweight object which simply wraps a {@code char} and implements {@link NodeCharacterProvider}, which * can be used as a key to locate a node having the same edge first character in a list of nodes using binary search. * * @author Niall Gallagher */ public class NodeCharacterKey implements NodeCharacterProvider { - private final Character character; + private final char character; - public NodeCharacterKey(Character character) { + public NodeCharacterKey(char character) { this.character = character; } @Override - public Character getIncomingEdgeFirstCharacter() { + public char getIncomingEdgeFirstCharacter() { return character; } } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterProvider.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterProvider.java index dd503f7..45f6097 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterProvider.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeCharacterProvider.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,5 +27,5 @@ */ public interface NodeCharacterProvider { - Character getIncomingEdgeFirstCharacter(); + char getIncomingEdgeFirstCharacter(); } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeUtil.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeUtil.java index b180a03..7e26e60 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeUtil.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/NodeUtil.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +16,7 @@ package com.googlecode.concurrenttrees.radix.node.util; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.NodeList; import java.util.*; import java.util.concurrent.atomic.AtomicReferenceArray; @@ -60,7 +61,7 @@ public class NodeUtil { * @return The index of the node representing the indicated edge, or a value < 0 if no such node exists in the * array */ - public static int binarySearchForEdge(AtomicReferenceArray childNodes, Character edgeFirstCharacter) { + public static int binarySearchForEdge(AtomicReferenceArray childNodes, char edgeFirstCharacter) { // inspired by Collections#indexedBinarySearch() int low = 0; int high = childNodes.length() - 1; @@ -68,7 +69,7 @@ public static int binarySearchForEdge(AtomicReferenceArray childNodes, Cha while (low <= high) { int mid = (low + high) >>> 1; Node midVal = childNodes.get(mid); - int cmp = midVal.getIncomingEdgeFirstCharacter().compareTo(edgeFirstCharacter); + int cmp = midVal.getIncomingEdgeFirstCharacter() - edgeFirstCharacter; if (cmp < 0) low = mid + 1; @@ -81,19 +82,17 @@ else if (cmp > 0) } /** - * Throws an exception if any nodes in the given list represent edges having the same first character. + * Checks if any nodes in the given list represent edges having the same first character. * * @param nodes The list of nodes to validate - * @throws IllegalStateException If a duplicate edge is detected + * @return {@code true} if the supplied edges are free of duplicates. */ - public static void ensureNoDuplicateEdges(List nodes) { + public static boolean hasNoDuplicateEdges(NodeList nodes) { // Sanity check that no two nodes specify an edge with the same first character... Set uniqueChars = new HashSet(nodes.size()); - for (Node node : nodes) { - uniqueChars.add(node.getIncomingEdgeFirstCharacter()); - } - if (nodes.size() != uniqueChars.size()) { - throw new IllegalStateException("Duplicate edge detected in list of nodes supplied: " + nodes); + for (int index = 0; index < nodes.size(); index++) { + uniqueChars.add(nodes.get(index).getIncomingEdgeFirstCharacter()); } + return nodes.size() == uniqueChars.size(); } } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/PrettyPrintable.java b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/PrettyPrintable.java index 3fe1af0..4506602 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/PrettyPrintable.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radix/node/util/PrettyPrintable.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,5 +24,5 @@ * @author Niall Gallagher */ public interface PrettyPrintable { - public Node getNode(); + Node getNode(); } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radixinverted/ConcurrentInvertedRadixTree.java b/code/src/main/java/com/googlecode/concurrenttrees/radixinverted/ConcurrentInvertedRadixTree.java index 89e3ff5..bbaad83 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radixinverted/ConcurrentInvertedRadixTree.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radixinverted/ConcurrentInvertedRadixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,8 +37,12 @@ */ public class ConcurrentInvertedRadixTree implements InvertedRadixTree, PrettyPrintable, Serializable { + private static final long serialVersionUID = 1L; + static class ConcurrentInvertedRadixTreeImpl extends ConcurrentRadixTree { + private static final long serialVersionUID = 1L; + public ConcurrentInvertedRadixTreeImpl(NodeFactory nodeFactory) { super(nodeFactory); } @@ -80,14 +84,13 @@ protected KeyValuePair computeNext() { } currentNode = nextNode; - CharSequence currentNodeEdgeCharacters = currentNode.getIncomingEdge(); - final int numCharsInEdge = currentNodeEdgeCharacters.length(); + final int numCharsInEdge = currentNode.getIncomingEdgeLength(); if (numCharsInEdge + charsMatched > documentLength) { // This node can't be a match because it is too long... return endOfData(); } for (int i = 0; i < numCharsInEdge; i++) { - if (currentNodeEdgeCharacters.charAt(i) != input.charAt(charsMatched + i)) { + if (currentNode.getIncomingEdgeCharacterAt(i) != input.charAt(charsMatched + i)) { // Found a difference between a character in the input // and a character in the edge represented by current node, // current node is a dead end... @@ -138,14 +141,13 @@ protected KeyValuePair scanForLongestKeyAtStartOfInput(final CharSequence inp } currentNode = nextNode; - CharSequence currentNodeEdgeCharacters = currentNode.getIncomingEdge(); - final int numCharsInEdge = currentNodeEdgeCharacters.length(); + final int numCharsInEdge = currentNode.getIncomingEdgeLength(); if (numCharsInEdge + charsMatched > documentLength) { // This node can't be a match because it is too long... break; } for (int i = 0; i < numCharsInEdge; i++) { - if (currentNodeEdgeCharacters.charAt(i) != input.charAt(charsMatched + i)) { + if (currentNode.getIncomingEdgeCharacterAt(i) != input.charAt(charsMatched + i)) { // Found a difference between a character in the input // and a character in the edge represented by current node, // current node is a dead end... @@ -266,7 +268,7 @@ public Iterable getKeysPrefixing(final CharSequence document) { @Override public Iterator iterator() { return new LazyIterator() { - Iterator> matchesForCurrentSuffix = radixTree.scanForKeysAtStartOfInput(document).iterator(); + final Iterator> matchesForCurrentSuffix = radixTree.scanForKeysAtStartOfInput(document).iterator(); @Override protected CharSequence computeNext() { @@ -291,7 +293,7 @@ public Iterable getValuesForKeysPrefixing(final CharSequence document) { @Override public Iterator iterator() { return new LazyIterator() { - Iterator> matchesForCurrentSuffix = radixTree.scanForKeysAtStartOfInput(document).iterator(); + final Iterator> matchesForCurrentSuffix = radixTree.scanForKeysAtStartOfInput(document).iterator(); @Override protected O computeNext() { @@ -316,7 +318,7 @@ public Iterable> getKeyValuePairsForKeysPrefixing(final CharSequ @Override public Iterator> iterator() { return new LazyIterator>() { - Iterator> matchesForCurrentSuffix = radixTree.scanForKeysAtStartOfInput(document).iterator(); + final Iterator> matchesForCurrentSuffix = radixTree.scanForKeysAtStartOfInput(document).iterator(); @Override protected KeyValuePair computeNext() { @@ -368,7 +370,7 @@ public Iterable getKeysContainedIn(final CharSequence document) { @Override public Iterator iterator() { return new LazyIterator() { - Iterator documentSuffixes = CharSequences.generateSuffixes(document).iterator(); + final Iterator documentSuffixes = CharSequences.generateSuffixes(document).iterator(); Iterator> matchesForCurrentSuffix = Collections.>emptyList().iterator(); @Override @@ -398,7 +400,7 @@ public Iterable getValuesForKeysContainedIn(final CharSequence document) { @Override public Iterator iterator() { return new LazyIterator() { - Iterator documentSuffixes = CharSequences.generateSuffixes(document).iterator(); + final Iterator documentSuffixes = CharSequences.generateSuffixes(document).iterator(); Iterator> matchesForCurrentSuffix = Collections.>emptyList().iterator(); @Override @@ -428,7 +430,7 @@ public Iterable> getKeyValuePairsForKeysContainedIn(final CharSe @Override public Iterator> iterator() { return new LazyIterator>() { - Iterator documentSuffixes = CharSequences.generateSuffixes(document).iterator(); + final Iterator documentSuffixes = CharSequences.generateSuffixes(document).iterator(); Iterator> matchesForCurrentSuffix = Collections.>emptyList().iterator(); @Override diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radixinverted/InvertedRadixTree.java b/code/src/main/java/com/googlecode/concurrenttrees/radixinverted/InvertedRadixTree.java index 3c43b5f..455e390 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radixinverted/InvertedRadixTree.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radixinverted/InvertedRadixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -113,7 +113,7 @@ public interface InvertedRadixTree extends RadixTree { * @return The longest key in the tree which is a prefix of the given document, or null if no such key is * contained in the tree */ - public CharSequence getLongestKeyPrefixing(CharSequence document); + CharSequence getLongestKeyPrefixing(CharSequence document); /** * Returns the value associated with the longest key in the tree which is a prefix of the given document. @@ -122,7 +122,7 @@ public interface InvertedRadixTree extends RadixTree { * @return The value associated with longest key in the tree which is a prefix of the given document, or null if * no such key is contained in the tree */ - public O getValueForLongestKeyPrefixing(CharSequence document); + O getValueForLongestKeyPrefixing(CharSequence document); /** * Returns the {@link KeyValuePair} for the longest key in the tree which is a prefix of the given document. @@ -131,7 +131,7 @@ public interface InvertedRadixTree extends RadixTree { * @return The {@link KeyValuePair} for the longest key in the tree which is a prefix of the given document, * or null if no such key is contained in the tree */ - public KeyValuePair getKeyValuePairForLongestKeyPrefixing(CharSequence document); + KeyValuePair getKeyValuePairForLongestKeyPrefixing(CharSequence document); /** * Returns a lazy iterable which returns the set of keys in the tree which are contained in the given document. diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radixreversed/ConcurrentReversedRadixTree.java b/code/src/main/java/com/googlecode/concurrenttrees/radixreversed/ConcurrentReversedRadixTree.java index b312186..018e64d 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radixreversed/ConcurrentReversedRadixTree.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radixreversed/ConcurrentReversedRadixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,7 +35,11 @@ */ public class ConcurrentReversedRadixTree implements ReversedRadixTree, PrettyPrintable, Serializable { - class ConcurrentReverseRadixTreeImpl extends ConcurrentRadixTree { + private static final long serialVersionUID = 1L; + + static class ConcurrentReverseRadixTreeImpl extends ConcurrentRadixTree { + + private static final long serialVersionUID = 1L; public ConcurrentReverseRadixTreeImpl(NodeFactory nodeFactory) { super(nodeFactory); diff --git a/code/src/main/java/com/googlecode/concurrenttrees/radixreversed/ReversedRadixTree.java b/code/src/main/java/com/googlecode/concurrenttrees/radixreversed/ReversedRadixTree.java index 85ecdb4..c821097 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/radixreversed/ReversedRadixTree.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/radixreversed/ReversedRadixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/main/java/com/googlecode/concurrenttrees/solver/LCSubstringSolver.java b/code/src/main/java/com/googlecode/concurrenttrees/solver/LCSubstringSolver.java index 72e8d8a..9a63c02 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/solver/LCSubstringSolver.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/solver/LCSubstringSolver.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +16,7 @@ package com.googlecode.concurrenttrees.solver; import com.googlecode.concurrenttrees.common.CharSequences; +import com.googlecode.concurrenttrees.common.SetFromMap; import com.googlecode.concurrenttrees.radix.ConcurrentRadixTree; import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; @@ -36,6 +37,8 @@ public class LCSubstringSolver { class ConcurrentSuffixTreeImpl extends ConcurrentRadixTree { + private static final long serialVersionUID = 1L; + public ConcurrentSuffixTreeImpl(NodeFactory nodeFactory) { super(nodeFactory); } @@ -211,6 +214,6 @@ public CharSequence getLongestCommonSubstring() { } protected Set createSetForOriginalKeys() { - return Collections.newSetFromMap(new ConcurrentHashMap()); + return new SetFromMap(new ConcurrentHashMap()); } } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/suffix/ConcurrentSuffixTree.java b/code/src/main/java/com/googlecode/concurrenttrees/suffix/ConcurrentSuffixTree.java index 950d41e..6b739b5 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/suffix/ConcurrentSuffixTree.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/suffix/ConcurrentSuffixTree.java @@ -18,6 +18,7 @@ import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.common.KeyValuePair; import com.googlecode.concurrenttrees.common.LazyIterator; +import com.googlecode.concurrenttrees.common.SetFromMap; import com.googlecode.concurrenttrees.radix.ConcurrentRadixTree; import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; @@ -38,7 +39,11 @@ */ public class ConcurrentSuffixTree implements SuffixTree, PrettyPrintable, Serializable { - class ConcurrentSuffixTreeImpl extends ConcurrentRadixTree { + private static final long serialVersionUID = 1L; + + static class ConcurrentSuffixTreeImpl extends ConcurrentRadixTree { + + private static final long serialVersionUID = 1L; public ConcurrentSuffixTreeImpl(NodeFactory nodeFactory) { super(nodeFactory); @@ -197,7 +202,7 @@ void removeSuffixesFromRadixTree(String keyAsString) { * @return A new {@link Set} in which original keys from which a suffix was generated can be stored */ protected Set createSetForOriginalKeys() { - return Collections.newSetFromMap(new ConcurrentHashMap()); + return new SetFromMap(new ConcurrentHashMap()); } /** @@ -234,7 +239,7 @@ public Iterable getValuesForKeysEndingWith(final CharSequence suffix) { @Override public Iterator iterator() { return new LazyIterator() { - Iterator originalKeys = nullSafeIterator(radixTree.getValueForExactKey(suffix)); + final Iterator originalKeys = nullSafeIterator(radixTree.getValueForExactKey(suffix)); @Override protected O computeNext() { @@ -262,7 +267,7 @@ public Iterable> getKeyValuePairsForKeysEndingWith(final CharSeq @Override public Iterator> iterator() { return new LazyIterator>() { - Iterator originalKeys = nullSafeIterator(radixTree.getValueForExactKey(suffix)); + final Iterator originalKeys = nullSafeIterator(radixTree.getValueForExactKey(suffix)); @Override protected KeyValuePair computeNext() { @@ -292,12 +297,12 @@ public Iterable getKeysContaining(final CharSequence fragment) { public Iterator iterator() { return new LazyIterator() { - Iterator> originalKeysSets = radixTree.getValuesForKeysStartingWith(fragment).iterator(); + final Iterator> originalKeysSets = radixTree.getValuesForKeysStartingWith(fragment).iterator(); Iterator keyIterator = Collections.emptyList().iterator(); // A given fragment can be contained many times within the same key, so track keys processed // so far, so that we can avoid re-processing the same key multiple times... - Set keysAlreadyProcessed = new HashSet(); + final Set keysAlreadyProcessed = new HashSet(); @Override protected CharSequence computeNext() { @@ -332,12 +337,12 @@ public Iterable getValuesForKeysContaining(final CharSequence fragment) { public Iterator iterator() { return new LazyIterator() { - Iterator> originalKeysSets = radixTree.getValuesForKeysStartingWith(fragment).iterator(); + final Iterator> originalKeysSets = radixTree.getValuesForKeysStartingWith(fragment).iterator(); Iterator keyIterator = Collections.emptyList().iterator(); // A given fragment can be contained many times within the same key, so track keys processed // so far, so that we can avoid re-processing the same key multiple times... - Set keysAlreadyProcessed = new HashSet(); + final Set keysAlreadyProcessed = new HashSet(); @Override protected O computeNext() { @@ -376,12 +381,12 @@ public Iterable> getKeyValuePairsForKeysContaining(final CharSeq public Iterator> iterator() { return new LazyIterator>() { - Iterator> originalKeysSets = radixTree.getValuesForKeysStartingWith(fragment).iterator(); + final Iterator> originalKeysSets = radixTree.getValuesForKeysStartingWith(fragment).iterator(); Iterator keyIterator = Collections.emptyList().iterator(); // A given fragment can be contained many times within the same key, so track keys processed // so far, so that we can avoid re-processing the same key multiple times... - Set keysAlreadyProcessed = new HashSet(); + final Set keysAlreadyProcessed = new HashSet(); @Override protected KeyValuePair computeNext() { @@ -422,7 +427,6 @@ public int size() { /** * Utility method to return an iterator for the given iterable, or an empty iterator if the iterable is null. */ - @SuppressWarnings({"JavaDoc"}) static Iterator nullSafeIterator(Iterable iterable) { return iterable == null ? Collections.emptyList().iterator() : iterable.iterator(); } diff --git a/code/src/main/java/com/googlecode/concurrenttrees/suffix/SuffixTree.java b/code/src/main/java/com/googlecode/concurrenttrees/suffix/SuffixTree.java index 250e946..d1df4b5 100644 --- a/code/src/main/java/com/googlecode/concurrenttrees/suffix/SuffixTree.java +++ b/code/src/main/java/com/googlecode/concurrenttrees/suffix/SuffixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/common/CharSequencesTest.java b/code/src/test/java/com/googlecode/concurrenttrees/common/CharSequencesTest.java index 1dc4241..6d2d088 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/common/CharSequencesTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/common/CharSequencesTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/common/IterablesTest.java b/code/src/test/java/com/googlecode/concurrenttrees/common/IterablesTest.java index 87386e6..9744015 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/common/IterablesTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/common/IterablesTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/common/LazyIteratorTest.java b/code/src/test/java/com/googlecode/concurrenttrees/common/LazyIteratorTest.java index 4b43bba..2d02be9 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/common/LazyIteratorTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/common/LazyIteratorTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/common/PrettyPrinterTest.java b/code/src/test/java/com/googlecode/concurrenttrees/common/PrettyPrinterTest.java index c287e24..9030258 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/common/PrettyPrinterTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/common/PrettyPrinterTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,14 +17,13 @@ import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import com.googlecode.concurrenttrees.radix.node.concrete.DefaultCharArrayNodeFactory; import com.googlecode.concurrenttrees.radix.node.util.PrettyPrintable; import org.junit.Assert; import org.junit.Test; import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; /** * @author Niall Gallagher @@ -110,14 +109,14 @@ static Node getHandBuiltTestTree() { // └── ○ DANA (4) final Node n1, n2, n3, n4, n5, n6; - n6 = nodeFactory.createNode("A", 6, Collections.emptyList(), false); - n5 = nodeFactory.createNode("AN", 5, Arrays.asList(n6), false); - n4 = nodeFactory.createNode("DANA", 4, Collections.emptyList(), false); - n3 = nodeFactory.createNode("N", 3, Arrays.asList(n4, n5), false); // note: it should sort these such that n5 is first - n2 = nodeFactory.createNode("A", 2, Arrays.asList(n3), false); - n1 = nodeFactory.createNode("B", 1, Arrays.asList(n2), false); + n6 = nodeFactory.createNode("A", 6, SimpleNodeList.EMPTY, false); + n5 = nodeFactory.createNode("AN", 5, new SimpleNodeList(n6), false); + n4 = nodeFactory.createNode("DANA", 4, SimpleNodeList.EMPTY, false); + n3 = nodeFactory.createNode("N", 3, new SimpleNodeList(n4, n5), false); // note: it should sort these such that n5 is first + n2 = nodeFactory.createNode("A", 2, new SimpleNodeList(n3), false); + n1 = nodeFactory.createNode("B", 1, new SimpleNodeList(n2), false); //noinspection NullableProblems - return nodeFactory.createNode("", null, Arrays.asList(n1), true); // root + return nodeFactory.createNode("", null, new SimpleNodeList(n1), true); // root } PrettyPrintable wrapNodeForPrinting(final Node node) { diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/ConcurrentRadixTreeInMemoryFileSystem.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/ConcurrentRadixTreeInMemoryFileSystem.java index 592cbbf..9448064 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/ConcurrentRadixTreeInMemoryFileSystem.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/ConcurrentRadixTreeInMemoryFileSystem.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/InMemoryFileSystem.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/InMemoryFileSystem.java index 6684ef2..3696445 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/InMemoryFileSystem.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/InMemoryFileSystem.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/InMemoryFileSystemUsage.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/InMemoryFileSystemUsage.java index 1c50265..c406706 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/InMemoryFileSystemUsage.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/filesystem/InMemoryFileSystemUsage.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareSinglePlaySuffixTree.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareSinglePlaySuffixTree.java index daff253..c2af06c 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareSinglePlaySuffixTree.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareSinglePlaySuffixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareTragediesSuffixTree.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareTragediesSuffixTree.java index e080369..9511cf7 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareTragediesSuffixTree.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareTragediesSuffixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareWordRadixTree.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareWordRadixTree.java index 93a95d7..c4f9d3c 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareWordRadixTree.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareWordRadixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareWordSuffixTree.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareWordSuffixTree.java index e269c31..54454d3 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareWordSuffixTree.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/BuildShakespeareWordSuffixTree.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/FindLongestCommonSubstring.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/FindLongestCommonSubstring.java index adeba2a..7c2d8ea 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/FindLongestCommonSubstring.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/FindLongestCommonSubstring.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/util/IOUtil.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/util/IOUtil.java index 60e215d..771ec8c 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/util/IOUtil.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/shakespeare/util/IOUtil.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/InvertedRadixTreeUsage.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/InvertedRadixTreeUsage.java index 70f9c11..3f5e5c8 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/InvertedRadixTreeUsage.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/InvertedRadixTreeUsage.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/IterablesUsage.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/IterablesUsage.java index 0fca12c..23b89a5 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/IterablesUsage.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/IterablesUsage.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/LCSubstringSolverUsage.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/LCSubstringSolverUsage.java index b094fe2..117ddec 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/LCSubstringSolverUsage.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/LCSubstringSolverUsage.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/RadixTreeUsage.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/RadixTreeUsage.java index 33e7448..4404d4c 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/RadixTreeUsage.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/RadixTreeUsage.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/ReversedRadixTreeUsage.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/ReversedRadixTreeUsage.java index 5314656..e51ae9d 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/ReversedRadixTreeUsage.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/ReversedRadixTreeUsage.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/SuffixTreeUsage.java b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/SuffixTreeUsage.java index 3891a0c..69c9701 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/SuffixTreeUsage.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/examples/usage/SuffixTreeUsage.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/ConcurrentRadixTreeTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/ConcurrentRadixTreeTest.java index ef38e28..82f4cf4 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/ConcurrentRadixTreeTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/ConcurrentRadixTreeTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,25 +15,19 @@ */ package com.googlecode.concurrenttrees.radix; -import com.googlecode.concurrenttrees.common.CharSequences; import com.googlecode.concurrenttrees.common.Iterables; import com.googlecode.concurrenttrees.common.KeyValuePair; import com.googlecode.concurrenttrees.common.PrettyPrinter; import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import com.googlecode.concurrenttrees.radix.node.concrete.DefaultCharArrayNodeFactory; import com.googlecode.concurrenttrees.radix.node.concrete.DefaultCharSequenceNodeFactory; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; import com.googlecode.concurrenttrees.radix.node.util.PrettyPrintable; import com.googlecode.concurrenttrees.testutil.TestUtility; -import junit.framework.Assert; import org.junit.Test; -import java.io.*; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import static org.junit.Assert.*; /** * @author Niall Gallagher @@ -59,14 +53,14 @@ public void testBuildTreeByHand() { // └── ○ DANA (4) final Node root, n1, n2, n3, n4, n5, n6; - n6 = getNodeFactory().createNode("A", 6, Collections.emptyList(), false); - n5 = getNodeFactory().createNode("AN", 5, Arrays.asList(n6), false); - n4 = getNodeFactory().createNode("DANA", 4, Collections.emptyList(), false); - n3 = getNodeFactory().createNode("N", 3, Arrays.asList(n4, n5), false); // note: it should sort alphabetically such that n5 is first - n2 = getNodeFactory().createNode("A", 2, Arrays.asList(n3), false); - n1 = getNodeFactory().createNode("B", 1, Arrays.asList(n2), false); + n6 = getNodeFactory().createNode("A", 6, SimpleNodeList.EMPTY, false); + n5 = getNodeFactory().createNode("AN", 5, new SimpleNodeList(n6), false); + n4 = getNodeFactory().createNode("DANA", 4, SimpleNodeList.EMPTY, false); + n3 = getNodeFactory().createNode("N", 3, new SimpleNodeList(n4, n5), false); // note: it should sort alphabetically such that n5 is first + n2 = getNodeFactory().createNode("A", 2, new SimpleNodeList(n3), false); + n1 = getNodeFactory().createNode("B", 1, new SimpleNodeList(n2), false); //noinspection NullableProblems - root = getNodeFactory().createNode("", null, Arrays.asList(n1), true); + root = getNodeFactory().createNode("", null, new SimpleNodeList(n1), true); String expected = "○\n" + @@ -282,6 +276,9 @@ protected Classification classify(CharSequence key, Node nodeFound, int charsMat } // Override searchTree() to return the InvalidSearchResult... ConcurrentRadixTree tree = new ConcurrentRadixTree(getNodeFactory()) { + + private static final long serialVersionUID = 1L; + @Override SearchResult searchTree(CharSequence key) { return new InvalidSearchResult("FOO", root, 4, 4, null, null); @@ -850,14 +847,14 @@ public void testSearchTree() { // └── ○ DANA (4) final Node root, n1, n2, n3, n4, n5, n6; - n6 = getNodeFactory().createNode("A", 6, Collections.emptyList(), false); - n5 = getNodeFactory().createNode("AN", 5, Arrays.asList(n6), false); - n4 = getNodeFactory().createNode("DANA", 4, Collections.emptyList(), false); - n3 = getNodeFactory().createNode("N", 3, Arrays.asList(n4, n5), false); // note: it should sort these such that n5 is first - n2 = getNodeFactory().createNode("A", 2, Arrays.asList(n3), false); - n1 = getNodeFactory().createNode("B", 1, Arrays.asList(n2), false); + n6 = getNodeFactory().createNode("A", 6, SimpleNodeList.EMPTY, false); + n5 = getNodeFactory().createNode("AN", 5, new SimpleNodeList(n6), false); + n4 = getNodeFactory().createNode("DANA", 4, SimpleNodeList.EMPTY, false); + n3 = getNodeFactory().createNode("N", 3, new SimpleNodeList(n4, n5), false); // note: it should sort these such that n5 is first + n2 = getNodeFactory().createNode("A", 2, new SimpleNodeList(n3), false); + n1 = getNodeFactory().createNode("B", 1, new SimpleNodeList(n2), false); //noinspection NullableProblems - root = getNodeFactory().createNode("", null, Arrays.asList(n1), true); + root = getNodeFactory().createNode("", null, new SimpleNodeList(n1), true); // Overwrite the tree's default root with the one built by hand... tree.root = root; @@ -951,7 +948,7 @@ public void testSearchResult_FailureToClassify1() { @Test(expected = IllegalStateException.class) public void testSearchResult_FailureToClassify2() { // Testing the various (unlikely) ways to fall through classification to have the exception thrown... - Node dummyNodeFound = getNodeFactory().createNode("DUMMY", 1, Collections.emptyList(), false); + Node dummyNodeFound = getNodeFactory().createNode("DUMMY", 1, SimpleNodeList.EMPTY, false); new ConcurrentRadixTree.SearchResult("DUMMY", dummyNodeFound, 5, 70, null, null); } @@ -959,7 +956,7 @@ public void testSearchResult_FailureToClassify2() { @Test(expected = IllegalStateException.class) public void testSearchResult_FailureToClassify3() { // Testing the various (unlikely) ways to fall through classification to have the exception thrown... - Node dummyNodeFound = getNodeFactory().createNode("DUMMY", 1, Collections.emptyList(), false); + Node dummyNodeFound = getNodeFactory().createNode("DUMMY", 1, SimpleNodeList.EMPTY, false); new ConcurrentRadixTree.SearchResult("DUMMY", dummyNodeFound, 4, 70, null, null); } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultByteArrayNodeFactoryTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultByteArrayNodeFactoryTest.java index 61074f5..a703cff 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultByteArrayNodeFactoryTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultByteArrayNodeFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,30 +16,43 @@ package com.googlecode.concurrenttrees.radix.node.concrete; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; +import org.junit.Before; import org.junit.Test; import java.util.Collections; +import static junit.framework.Assert.assertTrue; + /** * @author Niall Gallagher */ public class DefaultByteArrayNodeFactoryTest { + private boolean assertions; + + @Before + public void setUp() { + assert assertions = true; + } - @Test(expected = IllegalStateException.class) + @Test(expected = AssertionError.class) public void testCreateNode_NullEdge() throws Exception { + assertTrue(assertions); //noinspection NullableProblems - new DefaultByteArrayNodeFactory().createNode(null, 1, Collections.emptyList(), false); + new DefaultByteArrayNodeFactory().createNode(null, 1, SimpleNodeList.EMPTY, false); } - @Test(expected = IllegalStateException.class) + @Test(expected = AssertionError.class) public void testCreateNode_EmptyEdgeNonRoot() throws Exception { + assertTrue(assertions); //noinspection NullableProblems - new DefaultByteArrayNodeFactory().createNode("", 1, Collections.emptyList(), false); + new DefaultByteArrayNodeFactory().createNode("", 1, SimpleNodeList.EMPTY, false); } - @Test(expected = IllegalStateException.class) + @Test(expected = AssertionError.class) public void testCreateNode_NullEdges() throws Exception { + assertTrue(assertions); //noinspection NullableProblems new DefaultByteArrayNodeFactory().createNode("FOO", 1, null, false); } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharArrayNodeFactoryTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharArrayNodeFactoryTest.java index e7ff1c9..50030b7 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharArrayNodeFactoryTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharArrayNodeFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,30 +16,43 @@ package com.googlecode.concurrenttrees.radix.node.concrete; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; +import org.junit.Before; import org.junit.Test; import java.util.Collections; +import static junit.framework.Assert.assertTrue; + /** * @author Niall Gallagher */ public class DefaultCharArrayNodeFactoryTest { + private boolean assertions; + + @Before + public void setUp() { + assert assertions = true; + } - @Test(expected = IllegalStateException.class) + @Test(expected = AssertionError.class) public void testCreateNode_NullEdge() throws Exception { + assertTrue(assertions); //noinspection NullableProblems - new DefaultCharArrayNodeFactory().createNode(null, 1, Collections.emptyList(), false); + new DefaultCharArrayNodeFactory().createNode(null, 1, SimpleNodeList.EMPTY, false); } - @Test(expected = IllegalStateException.class) + @Test(expected = AssertionError.class) public void testCreateNode_EmptyEdgeNonRoot() throws Exception { + assertTrue(assertions); //noinspection NullableProblems - new DefaultCharArrayNodeFactory().createNode("", 1, Collections.emptyList(), false); + new DefaultCharArrayNodeFactory().createNode("", 1, SimpleNodeList.EMPTY, false); } - @Test(expected = IllegalStateException.class) + @Test(expected = AssertionError.class) public void testCreateNode_NullEdges() throws Exception { + assertTrue(assertions); //noinspection NullableProblems new DefaultCharArrayNodeFactory().createNode("FOO", 1, null, false); } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharSequenceNodeFactoryTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharSequenceNodeFactoryTest.java index c9a69bd..072c77e 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharSequenceNodeFactoryTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/DefaultCharSequenceNodeFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,29 +16,43 @@ package com.googlecode.concurrenttrees.radix.node.concrete; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; +import org.junit.Before; import org.junit.Test; import java.util.Collections; +import static junit.framework.Assert.assertTrue; + /** * @author Niall Gallagher */ public class DefaultCharSequenceNodeFactoryTest { - @Test(expected = IllegalStateException.class) + private boolean assertions; + + @Before + public void setUp() { + assert assertions = true; + } + + @Test(expected = AssertionError.class) public void testCreateNode_NullEdge() throws Exception { + assertTrue(assertions); //noinspection NullableProblems - new DefaultCharSequenceNodeFactory().createNode(null, 1, Collections.emptyList(), false); + new DefaultCharSequenceNodeFactory().createNode(null, 1, SimpleNodeList.EMPTY, false); } - @Test(expected = IllegalStateException.class) + @Test(expected = AssertionError.class) public void testCreateNode_EmptyEdgeNonRoot() throws Exception { + assertTrue(assertions); //noinspection NullableProblems - new DefaultCharSequenceNodeFactory().createNode("", 1, Collections.emptyList(), false); + new DefaultCharSequenceNodeFactory().createNode("", 1, SimpleNodeList.EMPTY, false); } - @Test(expected = IllegalStateException.class) + @Test(expected = AssertionError.class) public void testCreateNode_NullEdges() throws Exception { + assertTrue(assertions); //noinspection NullableProblems new DefaultCharSequenceNodeFactory().createNode("FOO", 1, null, false); } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/SmartArrayBasedNodeFactoryTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/SmartArrayBasedNodeFactoryTest.java index b2eef36..bb7151c 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/SmartArrayBasedNodeFactoryTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/SmartArrayBasedNodeFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,14 +16,13 @@ package com.googlecode.concurrenttrees.radix.node.concrete; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import com.googlecode.concurrenttrees.radix.node.concrete.bytearray.ByteArrayNodeLeafVoidValue; import com.googlecode.concurrenttrees.radix.node.concrete.chararray.CharArrayNodeLeafVoidValue; import com.googlecode.concurrenttrees.radix.node.concrete.voidvalue.VoidValue; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -33,13 +32,13 @@ public class SmartArrayBasedNodeFactoryTest { @Test public void testCreateNode_CompatibleCharacters() throws Exception { - Node node = smartNodeFactory.createNode("FOOBAR", VoidValue.SINGLETON, Collections.emptyList(), false); + Node node = smartNodeFactory.createNode("FOOBAR", VoidValue.SINGLETON, SimpleNodeList.EMPTY, false); Assert.assertEquals(ByteArrayNodeLeafVoidValue.class, node.getClass()); } @Test public void testCreateNode_IncompatibleCharacters() throws Exception { - Node node = smartNodeFactory.createNode("FOOBAR○", VoidValue.SINGLETON, Collections.emptyList(), false); + Node node = smartNodeFactory.createNode("FOOBAR○", VoidValue.SINGLETON, SimpleNodeList.EMPTY, false); Assert.assertEquals(CharArrayNodeLeafVoidValue.class, node.getClass()); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayCharSequenceTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayCharSequenceTest.java index 964ac7b..2b1b6ef 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayCharSequenceTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayCharSequenceTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeDefaultTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeDefaultTest.java index 70eebd9..e529bed 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeDefaultTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeDefaultTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,10 +16,9 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -27,7 +26,7 @@ public class ByteArrayNodeDefaultTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { - Node node = new ByteArrayNodeDefault("FOO", null, Collections.emptyList()); - node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR", null, Collections.emptyList())); + Node node = new ByteArrayNodeDefault("FOO", null, SimpleNodeList.EMPTY); + node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafNullValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafNullValueTest.java index 5672c7e..2eaf397 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafNullValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafNullValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,7 +28,7 @@ public class ByteArrayNodeLeafNullValueTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge() throws Exception { Node node = new ByteArrayNodeLeafNullValue("FOO"); - node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR", null, Collections.emptyList())); + node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } @Test @@ -41,6 +40,6 @@ public void testToString() throws Exception { @Test public void testGetIncomingEdgeFirstCharacter() throws Exception { Node node = new ByteArrayNodeLeafNullValue("FOO"); - Assert.assertEquals(Character.valueOf('F'), node.getIncomingEdgeFirstCharacter()); + Assert.assertEquals('F', node.getIncomingEdgeFirstCharacter()); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafVoidValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafVoidValueTest.java index 1da516b..923e893 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafVoidValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafVoidValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,7 +28,7 @@ public class ByteArrayNodeLeafVoidValueTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge() throws Exception { Node node = new ByteArrayNodeLeafVoidValue("FOO"); - node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR", null, Collections.emptyList())); + node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } @Test diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafWithValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafWithValueTest.java index abe35f0..79dc507 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafWithValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeLeafWithValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,7 +28,7 @@ public class ByteArrayNodeLeafWithValueTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge() throws Exception { Node node = new ByteArrayNodeLeafWithValue("FOO", 1); - node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR", null, Collections.emptyList())); + node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } @Test diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafNullValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafNullValueTest.java index 7289d90..453ddc3 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafNullValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafNullValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,12 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,19 +27,19 @@ public class ByteArrayNodeNonLeafNullValueTest { @Test public void testUpdateOutgoingEdge() throws Exception { - Node node = new ByteArrayNodeNonLeafNullValue("FOO", Arrays.asList((Node)new ByteArrayNodeDefault("BAR1", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR2", null, Collections.emptyList())); + Node node = new ByteArrayNodeNonLeafNullValue("FOO", new SimpleNodeList(new ByteArrayNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR2", null, SimpleNodeList.EMPTY)); } @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { - Node node = new ByteArrayNodeNonLeafNullValue("FOO", Arrays.asList((Node)new ByteArrayNodeDefault("BAR", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new ByteArrayNodeDefault("CAR", null, Collections.emptyList())); + Node node = new ByteArrayNodeNonLeafNullValue("FOO", new SimpleNodeList(new ByteArrayNodeDefault("BAR", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new ByteArrayNodeDefault("CAR", null, SimpleNodeList.EMPTY)); } @Test public void testToString() throws Exception { - Node node = new ByteArrayNodeNonLeafNullValue("FOO", Collections.emptyList()); + Node node = new ByteArrayNodeNonLeafNullValue("FOO", SimpleNodeList.EMPTY); Assert.assertEquals("Node{edge=FOO, value=null, edges=[]}", node.toString()); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafVoidValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafVoidValueTest.java index 00b2b7c..7de33ae 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafVoidValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/ByteArrayNodeNonLeafVoidValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,12 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.bytearray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,32 +27,32 @@ public class ByteArrayNodeNonLeafVoidValueTest { @Test public void testUpdateOutgoingEdge() throws Exception { - Node node = new ByteArrayNodeNonLeafVoidValue("FOO", Arrays.asList((Node) new ByteArrayNodeDefault("BAR1", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR2", null, Collections.emptyList())); + Node node = new ByteArrayNodeNonLeafVoidValue("FOO", new SimpleNodeList(new ByteArrayNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new ByteArrayNodeDefault("BAR2", null, SimpleNodeList.EMPTY)); } @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { - Node node = new ByteArrayNodeNonLeafVoidValue("FOO", Arrays.asList((Node)new ByteArrayNodeDefault("BAR", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new ByteArrayNodeDefault("CAR", null, Collections.emptyList())); + Node node = new ByteArrayNodeNonLeafVoidValue("FOO", new SimpleNodeList(new ByteArrayNodeDefault("BAR", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new ByteArrayNodeDefault("CAR", null, SimpleNodeList.EMPTY)); } @Test public void testToString() throws Exception { - Node node = new ByteArrayNodeNonLeafVoidValue("FOO", Collections.emptyList()); + Node node = new ByteArrayNodeNonLeafVoidValue("FOO", SimpleNodeList.EMPTY); Assert.assertEquals("Node{edge=FOO, value=-, edges=[]}", node.toString()); } @Test public void testGetOutgoingEdge() throws Exception { - Node node = new ByteArrayNodeNonLeafVoidValue("FOO", Arrays.asList((Node) new ByteArrayNodeDefault("BAR1", 1, Collections.emptyList()))); + Node node = new ByteArrayNodeNonLeafVoidValue("FOO", new SimpleNodeList(new ByteArrayNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); Assert.assertNotNull(node.getOutgoingEdge('B')); Assert.assertEquals(1, node.getOutgoingEdge('B').getValue()); } @Test public void testGetOutgoingEdge_NonExistent() throws Exception { - Node node = new ByteArrayNodeNonLeafVoidValue("FOO", Arrays.asList((Node) new ByteArrayNodeDefault("BAR1", 1, Collections.emptyList()))); + Node node = new ByteArrayNodeNonLeafVoidValue("FOO", new SimpleNodeList(new ByteArrayNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); Assert.assertNull(node.getOutgoingEdge('C')); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_InvertedRadixTreeTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_InvertedRadixTreeTest.java index d510d8d..b8a62ad 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_InvertedRadixTreeTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_InvertedRadixTreeTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_RadixTreeTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_RadixTreeTest.java index 76cd67d..00ad050 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_RadixTreeTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_RadixTreeTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_ReversedRadixTreeTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_ReversedRadixTreeTest.java index c538c09..b15cc8c 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_ReversedRadixTreeTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_ReversedRadixTreeTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_SuffixTreeTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_SuffixTreeTest.java index 7cc0669..c31eb4a 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_SuffixTreeTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/bytearray/functional/ByteArrayNodeFactory_SuffixTreeTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeDefaultTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeDefaultTest.java index 1f9710d..c57f847 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeDefaultTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeDefaultTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,9 @@ package com.googlecode.concurrenttrees.radix.node.concrete.chararray; import com.googlecode.concurrenttrees.radix.node.Node; -import com.googlecode.concurrenttrees.radix.node.concrete.chararray.CharArrayNodeDefault; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -28,7 +26,7 @@ public class CharArrayNodeDefaultTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { - Node node = new CharArrayNodeDefault("FOO", null, Collections.emptyList()); - node.updateOutgoingEdge(new CharArrayNodeDefault("BAR", null, Collections.emptyList())); + Node node = new CharArrayNodeDefault("FOO", null, SimpleNodeList.EMPTY); + node.updateOutgoingEdge(new CharArrayNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafNullValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafNullValueTest.java index d98b8d9..0cd57e9 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafNullValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafNullValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.chararray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,7 +28,7 @@ public class CharArrayNodeLeafNullValueTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge() throws Exception { Node node = new CharArrayNodeLeafNullValue("FOO"); - node.updateOutgoingEdge(new CharArrayNodeDefault("BAR", null, Collections.emptyList())); + node.updateOutgoingEdge(new CharArrayNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } @Test diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafVoidValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafVoidValueTest.java index 258c7ff..62ce0ff 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafVoidValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafVoidValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.chararray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,7 +28,7 @@ public class CharArrayNodeLeafVoidValueTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge() throws Exception { Node node = new CharArrayNodeLeafVoidValue("FOO"); - node.updateOutgoingEdge(new CharArrayNodeDefault("BAR", null, Collections.emptyList())); + node.updateOutgoingEdge(new CharArrayNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } @Test diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafWithValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafWithValueTest.java index dce199a..011f348 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafWithValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeLeafWithValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.chararray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,7 +28,7 @@ public class CharArrayNodeLeafWithValueTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge() throws Exception { Node node = new CharArrayNodeLeafWithValue("FOO", 1); - node.updateOutgoingEdge(new CharArrayNodeDefault("BAR", null, Collections.emptyList())); + node.updateOutgoingEdge(new CharArrayNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } @Test diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafNullValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafNullValueTest.java index 9810914..27eb9b9 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafNullValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafNullValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,12 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.chararray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,19 +27,19 @@ public class CharArrayNodeNonLeafNullValueTest { @Test public void testUpdateOutgoingEdge() throws Exception { - Node node = new CharArrayNodeNonLeafNullValue("FOO", Arrays.asList((Node)new CharArrayNodeDefault("BAR1", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new CharArrayNodeDefault("BAR2", null, Collections.emptyList())); + Node node = new CharArrayNodeNonLeafNullValue("FOO", new SimpleNodeList(new CharArrayNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new CharArrayNodeDefault("BAR2", null, SimpleNodeList.EMPTY)); } @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { - Node node = new CharArrayNodeNonLeafNullValue("FOO", Arrays.asList((Node)new CharArrayNodeDefault("BAR", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new CharArrayNodeDefault("CAR", null, Collections.emptyList())); + Node node = new CharArrayNodeNonLeafNullValue("FOO", new SimpleNodeList(new CharArrayNodeDefault("BAR", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new CharArrayNodeDefault("CAR", null, SimpleNodeList.EMPTY)); } @Test public void testToString() throws Exception { - Node node = new CharArrayNodeNonLeafNullValue("FOO", Collections.emptyList()); + Node node = new CharArrayNodeNonLeafNullValue("FOO", SimpleNodeList.EMPTY); Assert.assertEquals("Node{edge=FOO, value=null, edges=[]}", node.toString()); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafVoidValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafVoidValueTest.java index 71720dc..213e828 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafVoidValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/chararray/CharArrayNodeNonLeafVoidValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,12 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.chararray; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,32 +27,32 @@ public class CharArrayNodeNonLeafVoidValueTest { @Test public void testUpdateOutgoingEdge() throws Exception { - Node node = new CharArrayNodeNonLeafVoidValue("FOO", Arrays.asList((Node) new CharArrayNodeDefault("BAR1", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new CharArrayNodeDefault("BAR2", null, Collections.emptyList())); + Node node = new CharArrayNodeNonLeafVoidValue("FOO", new SimpleNodeList(new CharArrayNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new CharArrayNodeDefault("BAR2", null, SimpleNodeList.EMPTY)); } @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { - Node node = new CharArrayNodeNonLeafVoidValue("FOO", Arrays.asList((Node)new CharArrayNodeDefault("BAR", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new CharArrayNodeDefault("CAR", null, Collections.emptyList())); + Node node = new CharArrayNodeNonLeafVoidValue("FOO", new SimpleNodeList(new CharArrayNodeDefault("BAR", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new CharArrayNodeDefault("CAR", null, SimpleNodeList.EMPTY)); } @Test public void testToString() throws Exception { - Node node = new CharArrayNodeNonLeafVoidValue("FOO", Collections.emptyList()); + Node node = new CharArrayNodeNonLeafVoidValue("FOO", SimpleNodeList.EMPTY); Assert.assertEquals("Node{edge=FOO, value=-, edges=[]}", node.toString()); } @Test public void testGetOutgoingEdge() throws Exception { - Node node = new CharArrayNodeNonLeafVoidValue("FOO", Arrays.asList((Node) new CharArrayNodeDefault("BAR1", 1, Collections.emptyList()))); + Node node = new CharArrayNodeNonLeafVoidValue("FOO", new SimpleNodeList(new CharArrayNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); Assert.assertNotNull(node.getOutgoingEdge('B')); Assert.assertEquals(1, node.getOutgoingEdge('B').getValue()); } @Test public void testGetOutgoingEdge_NonExistent() throws Exception { - Node node = new CharArrayNodeNonLeafVoidValue("FOO", Arrays.asList((Node) new CharArrayNodeDefault("BAR1", 1, Collections.emptyList()))); + Node node = new CharArrayNodeNonLeafVoidValue("FOO", new SimpleNodeList(new CharArrayNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); Assert.assertNull(node.getOutgoingEdge('C')); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafNullValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafNullValueTest.java index 721fb4a..ebac4fa 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafNullValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafNullValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,7 +28,7 @@ public class CharSequenceNodeLeafNullValueTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge() throws Exception { Node node = new CharSequenceNodeLeafNullValue("FOO"); - node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR", null, Collections.emptyList())); + node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } @Test @@ -41,6 +40,6 @@ public void testToString() throws Exception { @Test public void testGetIncomingEdgeFirstCharacter() { Node node = new CharSequenceNodeLeafNullValue("FOO"); - Assert.assertEquals(Character.valueOf('F'), node.getIncomingEdgeFirstCharacter()); + Assert.assertEquals('F', node.getIncomingEdgeFirstCharacter()); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafVoidValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafVoidValueTest.java index 32db579..d4d01e1 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafVoidValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafVoidValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,7 +28,7 @@ public class CharSequenceNodeLeafVoidValueTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge() throws Exception { Node node = new CharSequenceNodeLeafVoidValue("FOO"); - node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR", null, Collections.emptyList())); + node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } @Test diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafWithValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafWithValueTest.java index e5c1aaf..2c0b8cc 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafWithValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeLeafWithValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,7 +28,7 @@ public class CharSequenceNodeLeafWithValueTest { @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge() throws Exception { Node node = new CharSequenceNodeLeafWithValue("FOO", 1); - node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR", null, Collections.emptyList())); + node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } @Test diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafNullValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafNullValueTest.java index 6476135..3782b36 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafNullValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafNullValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,12 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,19 +27,19 @@ public class CharSequenceNodeNonLeafNullValueTest { @Test public void testUpdateOutgoingEdge() throws Exception { - Node node = new CharSequenceNodeNonLeafNullValue("FOO", Arrays.asList((Node)new CharSequenceNodeDefault("BAR1", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR2", null, Collections.emptyList())); + Node node = new CharSequenceNodeNonLeafNullValue("FOO", new SimpleNodeList(new CharSequenceNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR2", null, SimpleNodeList.EMPTY)); } @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { - Node node = new CharSequenceNodeNonLeafNullValue("FOO", Arrays.asList((Node)new CharSequenceNodeDefault("BAR", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new CharSequenceNodeDefault("CAR", null, Collections.emptyList())); + Node node = new CharSequenceNodeNonLeafNullValue("FOO", new SimpleNodeList(new CharSequenceNodeDefault("BAR", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new CharSequenceNodeDefault("CAR", null, SimpleNodeList.EMPTY)); } @Test public void testToString() throws Exception { - Node node = new CharSequenceNodeNonLeafNullValue("FOO", Collections.emptyList()); + Node node = new CharSequenceNodeNonLeafNullValue("FOO", SimpleNodeList.EMPTY); Assert.assertEquals("Node{edge=FOO, value=null, edges=[]}", node.toString()); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafVoidValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafVoidValueTest.java index da0b1c3..67a0603 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafVoidValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/CharSequenceNodeNonLeafVoidValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,12 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,32 +27,32 @@ public class CharSequenceNodeNonLeafVoidValueTest { @Test public void testUpdateOutgoingEdge() throws Exception { - Node node = new CharSequenceNodeNonLeafVoidValue("FOO", Arrays.asList((Node) new CharSequenceNodeDefault("BAR1", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR2", null, Collections.emptyList())); + Node node = new CharSequenceNodeNonLeafVoidValue("FOO", new SimpleNodeList(new CharSequenceNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR2", null, SimpleNodeList.EMPTY)); } @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { - Node node = new CharSequenceNodeNonLeafVoidValue("FOO", Arrays.asList((Node)new CharSequenceNodeDefault("BAR", 1, Collections.emptyList()))); - node.updateOutgoingEdge(new CharSequenceNodeDefault("CAR", null, Collections.emptyList())); + Node node = new CharSequenceNodeNonLeafVoidValue("FOO", new SimpleNodeList(new CharSequenceNodeDefault("BAR", 1, SimpleNodeList.EMPTY))); + node.updateOutgoingEdge(new CharSequenceNodeDefault("CAR", null, SimpleNodeList.EMPTY)); } @Test public void testToString() throws Exception { - Node node = new CharSequenceNodeNonLeafVoidValue("FOO", Collections.emptyList()); + Node node = new CharSequenceNodeNonLeafVoidValue("FOO", SimpleNodeList.EMPTY); Assert.assertEquals("Node{edge=FOO, value=-, edges=[]}", node.toString()); } @Test public void testGetOutgoingEdge() throws Exception { - Node node = new CharSequenceNodeNonLeafVoidValue("FOO", Arrays.asList((Node) new CharSequenceNodeDefault("BAR1", 1, Collections.emptyList()))); + Node node = new CharSequenceNodeNonLeafVoidValue("FOO", new SimpleNodeList(new CharSequenceNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); Assert.assertNotNull(node.getOutgoingEdge('B')); Assert.assertEquals(1, node.getOutgoingEdge('B').getValue()); } @Test public void testGetOutgoingEdge_NonExistent() throws Exception { - Node node = new CharSequenceNodeNonLeafVoidValue("FOO", Arrays.asList((Node) new CharSequenceNodeDefault("BAR1", 1, Collections.emptyList()))); + Node node = new CharSequenceNodeNonLeafVoidValue("FOO", new SimpleNodeList(new CharSequenceNodeDefault("BAR1", 1, SimpleNodeList.EMPTY))); Assert.assertNull(node.getOutgoingEdge('C')); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/DefaultCharSequenceNodeTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/DefaultCharSequenceNodeTest.java index 87620a9..b5baeed 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/DefaultCharSequenceNodeTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/charsequence/DefaultCharSequenceNodeTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,12 +16,10 @@ package com.googlecode.concurrenttrees.radix.node.concrete.charsequence; import com.googlecode.concurrenttrees.radix.node.Node; -import com.googlecode.concurrenttrees.radix.node.concrete.charsequence.CharSequenceNodeDefault; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import org.junit.Assert; import org.junit.Test; -import java.util.Collections; - /** * @author Niall Gallagher */ @@ -29,14 +27,14 @@ public class DefaultCharSequenceNodeTest { @Test public void testToString() throws Exception { - Node node = new CharSequenceNodeDefault("FOO", null, Collections.emptyList()); + Node node = new CharSequenceNodeDefault("FOO", null, SimpleNodeList.EMPTY); Assert.assertEquals("Node{edge=FOO, value=null, edges=[]}", node.toString()); } @Test(expected = IllegalStateException.class) public void testUpdateOutgoingEdge_NonExistentEdge() throws Exception { - Node node = new CharSequenceNodeDefault("FOO", null, Collections.emptyList()); - node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR", null, Collections.emptyList())); + Node node = new CharSequenceNodeDefault("FOO", null, SimpleNodeList.EMPTY); + node.updateOutgoingEdge(new CharSequenceNodeDefault("BAR", null, SimpleNodeList.EMPTY)); } } diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/voidvalue/VoidValueTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/voidvalue/VoidValueTest.java index 72ea803..c8a896b 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/voidvalue/VoidValueTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/concrete/voidvalue/VoidValueTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/util/NodeUtilTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/util/NodeUtilTest.java index e131b77..808d78f 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radix/node/util/NodeUtilTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radix/node/util/NodeUtilTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,6 +17,7 @@ import com.googlecode.concurrenttrees.radix.node.Node; import com.googlecode.concurrenttrees.radix.node.NodeFactory; +import com.googlecode.concurrenttrees.radix.node.SimpleNodeList; import com.googlecode.concurrenttrees.radix.node.concrete.DefaultCharArrayNodeFactory; import org.junit.Assert; import org.junit.Test; @@ -26,6 +27,8 @@ import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; +import static junit.framework.Assert.assertFalse; + /** * @author Niall Gallagher */ @@ -36,9 +39,9 @@ public class NodeUtilTest { public void testBinarySearchForEdge() throws Exception { NodeFactory nodeFactory = new DefaultCharArrayNodeFactory(); Node[] nodes = new Node[] { - nodeFactory.createNode("A", null, Collections.emptyList(), false), - nodeFactory.createNode("B", null, Collections.emptyList(), false), - nodeFactory.createNode("C", null, Collections.emptyList(), false) + nodeFactory.createNode("A", null, SimpleNodeList.EMPTY, false), + nodeFactory.createNode("B", null, SimpleNodeList.EMPTY, false), + nodeFactory.createNode("C", null, SimpleNodeList.EMPTY, false) }; AtomicReferenceArray atomicReferenceArray = new AtomicReferenceArray(nodes); Assert.assertEquals(0, NodeUtil.binarySearchForEdge(atomicReferenceArray, 'A')); @@ -52,9 +55,9 @@ public void testBinarySearchForEdge() throws Exception { public void testEnsureNoDuplicateEdges_Positive() throws Exception { NodeFactory nodeFactory = new DefaultCharArrayNodeFactory(); List nodes = Arrays.asList( - nodeFactory.createNode("A", null, Collections.emptyList(), false), - nodeFactory.createNode("B", null, Collections.emptyList(), false), - nodeFactory.createNode("C", null, Collections.emptyList(), false) + nodeFactory.createNode("A", null, SimpleNodeList.EMPTY, false), + nodeFactory.createNode("B", null, SimpleNodeList.EMPTY, false), + nodeFactory.createNode("C", null, SimpleNodeList.EMPTY, false) ); } @@ -62,19 +65,13 @@ public void testEnsureNoDuplicateEdges_Positive() throws Exception { @SuppressWarnings({"NullableProblems"}) public void testEnsureNoDuplicateEdges_Negative() throws Exception { NodeFactory nodeFactory = new DefaultCharArrayNodeFactory(); - List nodes = Arrays.asList( - nodeFactory.createNode("A", null, Collections.emptyList(), false), - nodeFactory.createNode("B", null, Collections.emptyList(), false), - nodeFactory.createNode("B", null, Collections.emptyList(), false), - nodeFactory.createNode("C", null, Collections.emptyList(), false) + SimpleNodeList nodes = new SimpleNodeList( + nodeFactory.createNode("A", null, SimpleNodeList.EMPTY, false), + nodeFactory.createNode("B", null, SimpleNodeList.EMPTY, false), + nodeFactory.createNode("B", null, SimpleNodeList.EMPTY, false), + nodeFactory.createNode("C", null, SimpleNodeList.EMPTY, false) ); - try { - NodeUtil.ensureNoDuplicateEdges(nodes); - Assert.fail("Should throw exception"); - } - catch (IllegalStateException expected) { - // Expected - } + assertFalse(NodeUtil.hasNoDuplicateEdges(nodes)); } @Test diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radixinverted/ConcurrentInvertedRadixTreeTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radixinverted/ConcurrentInvertedRadixTreeTest.java index 155a9b8..ee53de5 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radixinverted/ConcurrentInvertedRadixTreeTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radixinverted/ConcurrentInvertedRadixTreeTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/radixreversed/ConcurrentReversedRadixTreeTest.java b/code/src/test/java/com/googlecode/concurrenttrees/radixreversed/ConcurrentReversedRadixTreeTest.java index 5bbcb2f..7f4469b 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/radixreversed/ConcurrentReversedRadixTreeTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/radixreversed/ConcurrentReversedRadixTreeTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/solver/LCSubstringSolverTest.java b/code/src/test/java/com/googlecode/concurrenttrees/solver/LCSubstringSolverTest.java index b0cc40c..4367185 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/solver/LCSubstringSolverTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/solver/LCSubstringSolverTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/code/src/test/java/com/googlecode/concurrenttrees/suffix/ConcurrentSuffixTreeTest.java b/code/src/test/java/com/googlecode/concurrenttrees/suffix/ConcurrentSuffixTreeTest.java index cfb69eb..8bc7268 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/suffix/ConcurrentSuffixTreeTest.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/suffix/ConcurrentSuffixTreeTest.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,11 +17,13 @@ import com.googlecode.concurrenttrees.common.Iterables; import com.googlecode.concurrenttrees.common.PrettyPrinter; +import com.googlecode.concurrenttrees.common.SetFromMap; import com.googlecode.concurrenttrees.radix.node.NodeFactory; import com.googlecode.concurrenttrees.radix.node.concrete.DefaultCharArrayNodeFactory; import com.googlecode.concurrenttrees.testutil.TestUtility; import org.junit.Test; +import java.lang.reflect.Field; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -435,10 +437,14 @@ public void testGetKeyValuePairsForKeysContaining() throws Exception { } @Test - public void testCreateSetForOriginalKeys() { - // Test the default (production) implementation of this method, should return a set based on ConcurrentHashMap... + public void testCreateSetForOriginalKeys() throws Exception { + // Test the default (production) implementation of this method, should return a SetFromMap wrapper for a ConcurrentHashMap... ConcurrentSuffixTree tree = new ConcurrentSuffixTree(getNodeFactory()); - assertTrue(tree.createSetForOriginalKeys().getClass().equals(Collections.newSetFromMap(new ConcurrentHashMap()).getClass())); + Set setForOriginalKeys = tree.createSetForOriginalKeys(); + assertEquals(setForOriginalKeys.getClass(), SetFromMap.class); + Field delegate = setForOriginalKeys.getClass().getDeclaredField("delegate"); + delegate.setAccessible(true); + assertEquals(delegate.get(setForOriginalKeys).getClass(), ConcurrentHashMap.class); } /** @@ -449,6 +455,9 @@ public void testCreateSetForOriginalKeys() { @SuppressWarnings({"JavaDoc"}) ConcurrentSuffixTree newConcurrentSuffixTreeForUnitTests() { return new ConcurrentSuffixTree(getNodeFactory()) { + + private static final long serialVersionUID = 1L; + // Override this method to return a set which has consistent iteration order, for unit testing... @Override protected Set createSetForOriginalKeys() { @@ -474,6 +483,9 @@ public void testSerialization() { * Note that ordering of original keys is an internal implementation detail and is externally not defined. */ static class ConcurrentSuffixTreeTestImpl extends ConcurrentSuffixTree { + + private static final long serialVersionUID = 1L; + public ConcurrentSuffixTreeTestImpl(NodeFactory nodeFactory) { super(nodeFactory); } @Override protected Set createSetForOriginalKeys() { diff --git a/code/src/test/java/com/googlecode/concurrenttrees/testutil/TestUtility.java b/code/src/test/java/com/googlecode/concurrenttrees/testutil/TestUtility.java index f05173f..44e6b7a 100644 --- a/code/src/test/java/com/googlecode/concurrenttrees/testutil/TestUtility.java +++ b/code/src/test/java/com/googlecode/concurrenttrees/testutil/TestUtility.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2012-2013 Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License");