double the speed of building the PathTree

java-i2p-warning
Zlatin Balevsky 2022-08-29 21:16:10 +01:00
parent ab983dbf57
commit 69739b4b55
No known key found for this signature in database
GPG Key ID: A72832072D525E41
1 changed files with 22 additions and 16 deletions

View File

@ -10,9 +10,7 @@ import java.util.function.Function
*/ */
class PathTree<T,I> { class PathTree<T,I> {
private final Node[] EMPTY_CHILDREN = new Node[0] private final Node root = new Node(null, null)
private final Node root = new Node()
private final Map<Path, Node> pathNodeMap = new HashMap<>() private final Map<Path, Node> pathNodeMap = new HashMap<>()
private final Function<Path, I> function private final Function<Path, I> function
@ -31,9 +29,7 @@ class PathTree<T,I> {
Path subPath = path.subpath(0, i + 1) Path subPath = path.subpath(0, i + 1)
Node newNode = pathNodeMap[subPath] Node newNode = pathNodeMap[subPath]
if (newNode == null) { if (newNode == null) {
newNode = new Node() newNode = new Node(parent, subPath)
newNode.path = subPath
newNode.parent = parent
if (function != null) if (function != null)
newNode.interimValue = function.apply(newNode.path) newNode.interimValue = function.apply(newNode.path)
parent.addChild(newNode) parent.addChild(newNode)
@ -56,7 +52,7 @@ class PathTree<T,I> {
} }
private synchronized void doTraverse(Node from, PathTreeCallback<T,I> cb) { private synchronized void doTraverse(Node from, PathTreeCallback<T,I> cb) {
if (from.children.length == 0) { if (from.children.isEmpty()) {
cb.onLeaf(from.path, from.value) cb.onLeaf(from.path, from.value)
return return
} }
@ -77,7 +73,7 @@ class PathTree<T,I> {
node = pathNodeMap[from] node = pathNodeMap[from]
for (Node child : node.children) { for (Node child : node.children) {
if (child.children.length == 0) if (child.children.isEmpty())
cb.onLeaf(child.path, child.value) cb.onLeaf(child.path, child.value)
else else
cb.onDirectory(child.path, child.interimValue) cb.onDirectory(child.path, child.interimValue)
@ -85,14 +81,25 @@ class PathTree<T,I> {
} }
private class Node { private class Node {
Node parent final Node parent
Path path final Path path
final int hashcode
T value T value
I interimValue I interimValue
Node[] children = EMPTY_CHILDREN Set<Node> children = Collections.emptySet()
Node(Node parent, Path path) {
this.parent = parent
this.path = path
if (path != null)
hashcode = path.hashCode()
else
hashcode = 0
}
int hashCode() { int hashCode() {
Objects.hash(path) hashcode
} }
boolean equals(Object o) { boolean equals(Object o) {
@ -103,10 +110,9 @@ class PathTree<T,I> {
} }
private void addChild(Node child) { private void addChild(Node child) {
Set<Node> unique = new HashSet<>() if (children == Collections.emptySet())
unique.addAll(children) children = new HashSet<>()
unique.add(child) children.add(child)
children = unique.toArray(children)
} }
} }