diff --git a/src/main/java/com/redhat/trie/NodePair.java b/src/main/java/com/redhat/trie/NodePair.java index 8a3cec4..1178434 100644 --- a/src/main/java/com/redhat/trie/NodePair.java +++ b/src/main/java/com/redhat/trie/NodePair.java @@ -28,6 +28,10 @@ public class NodePair implements Comparable { return this.name; } + public long getId() { + return this.getConnection().getId(); + } + public PathNode getConnection() { return this.connection; } diff --git a/src/main/java/com/redhat/trie/PathNode.java b/src/main/java/com/redhat/trie/PathNode.java index 6836adc..3da0871 100644 --- a/src/main/java/com/redhat/trie/PathNode.java +++ b/src/main/java/com/redhat/trie/PathNode.java @@ -17,6 +17,8 @@ package com.redhat.trie; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.HashSet; import java.util.Collections; public class PathNode { @@ -46,6 +48,26 @@ public class PathNode { this.children.add(cp); } + public Set getAllNodes() { + return getAllNodes(this); + } + + /** + * return the unique set of PathNodes in a given node. + * + * @param node a "root" PathNode. Which can all be a matter of perspective. + * @return the unique Set of Nodes + */ + public Set getAllNodes(PathNode node) { + Set nodes = new HashSet(); + nodes.add(node); + for (NodePair np : node.getChildren()) { + nodes.addAll(getAllNodes(np.getConnection())); + } + return nodes; + } + + public void addParent(PathNode cp) { if (!parents.contains(cp)) { this.parents.add(cp); @@ -71,6 +93,45 @@ public class PathNode { } } + public String getName() { + String name = ""; + for (NodePair child : this.getParents().get(0).getChildren()) { + if (child.getConnection().getId() == this.getId()) { + return child.getName(); + } + } + return name; + } + + public PathNode getStartNode() { + return getStartNode(this); + } + + public PathNode getStartNode(PathNode node) { + if (node.getParents().size() == 0) { + return node; // this is the end! + } + + for (PathNode parent : node.getParents()) { + return node.getStartNode(parent); + } + return node; // when in doubt, return yourself + } + + public PathNode getEndNode() { + return getEndNode(this); + } + + public PathNode getEndNode(PathNode node) { + if (node.getChildren().size() == 0) { + return node; // this is the end! + } + for (NodePair child : node.getChildren()) { + return node.getEndNode(child.getConnection()); + } + return node; // when in doubt, return yourself + } + /* * same number of children with the same names for child nodes */ @@ -142,7 +203,7 @@ public class PathNode { parentList += ": " + parent.getId(); } parentList += ""; - return "ID: " + id + ", Parents" + parentList + ", Children: " + children; + return "ID: " + id + ", Name: " + this.getName() + ", Parents" + parentList + ", Children: " + children; } } diff --git a/src/main/java/com/redhat/trie/PathTree.java b/src/main/java/com/redhat/trie/PathTree.java index 2230d3d..2a39b3b 100644 --- a/src/main/java/com/redhat/trie/PathTree.java +++ b/src/main/java/com/redhat/trie/PathTree.java @@ -396,13 +396,24 @@ public class PathTree { * @return is the same object as the parent param */ public static PathNode makePathTree(List contents, PathNode parent) { - PathNode endMarker = new PathNode(new NodeContext()); + // find the end node + PathNode endMarker = parent.getEndNode(); + // unless it is the parent + if (endMarker == parent) { + endMarker = new PathNode(parent.getContext()); + } + for (String path : contents) { StringTokenizer st = new StringTokenizer(path, "/"); PathTree.makePathForURL(st, parent, endMarker); } - //log.debug("would run condenseSubTreeNodes()"); - //this.condenseSubTreeNodes(endMarker); + /* XXX I am convinced, that this is not needed + * + * If you feel otherwise, then fix it's broken logic. + * + * -- vbatts + */ + //condenseSubTreeNodes(endMarker); return parent; } @@ -726,7 +737,7 @@ public class PathTree { List result = new ArrayList(); // walk tree to make string map - Set nodes = getPathNodes(treeRoot); + Set nodes = treeRoot.getAllNodes(); for (PathNode pn : nodes) { int count = pn.getParents().size(); if (nodes.size() == 0) { @@ -746,21 +757,6 @@ public class PathTree { return result; } - /** - * return the unique set of PathNodes in a given treeRoot. - * - * @param treeRoot a "root" PathNode. Which can all be a matter of perspective. - * @return the unique Set of Nodes - */ - private Set getPathNodes(PathNode treeRoot) { - Set nodes = new HashSet(); - nodes.add(treeRoot); - for (NodePair np : treeRoot.getChildren()) { - nodes.addAll(getPathNodes(np.getConnection())); - } - return nodes; - } - private String findHuffPath(HuffNode trie, Object need) { HuffNode left = trie.getLeft(); HuffNode right = trie.getRight(); @@ -851,35 +847,31 @@ public class PathTree { (byte) value}; } - private void condenseSubTreeNodes(PathNode location) { + private static void condenseSubTreeNodes(PathNode location) { // "equivalent" parents are merged List parentResult = new ArrayList(); parentResult.addAll(location.getParents()); + //log.debug(location); for (PathNode parent1 : location.getParents()) { if (!parentResult.contains(parent1)) { continue; } for (PathNode parent2 : location.getParents()) { - if (!parentResult.contains(parent2) || + if (!parentResult.contains(parent2) || parent2.getId() == parent1.getId()) { continue; } if (parent1.isEquivalentTo(parent2)) { // we merge them into smaller Id - PathNode merged = parent1.getId() < parent2.getId() ? - parent1 : parent2; - PathNode toRemove = parent1.getId() < parent2.getId() ? - parent2 : parent1; + PathNode merged; + PathNode toRemove; - // track down the name of the string in the grandparent - // that points to parent - String name = ""; - PathNode oneParent = toRemove.getParents().get(0); - for (NodePair child : oneParent.getChildren()) { - if (child.getConnection().getId() == toRemove.getId()) { - name = child.getName(); - break; - } + if (parent1.getId() < parent2.getId()) { + merged = parent2; + toRemove = parent1; + } else { + merged = parent1; + toRemove = parent2; } // copy grandparents to merged parent node. @@ -889,8 +881,8 @@ public class PathTree { // all grandparents with name now point to merged node for (PathNode pn : toRemove.getParents()) { for (NodePair child : pn.getChildren()) { - if (child.getName().equals(name)) { - child.setConnection(merged); + if (child.getConnection() == toRemove) { + child.setConnection(merged); // FIXME This is where the breakage is } } } diff --git a/src/test/java/com/redhat/trie/TestPathTree.java b/src/test/java/com/redhat/trie/TestPathTree.java index a0af0bf..ec3a776 100644 --- a/src/test/java/com/redhat/trie/TestPathTree.java +++ b/src/test/java/com/redhat/trie/TestPathTree.java @@ -113,8 +113,12 @@ public class TestPathTree { public void testThereAndBackAgainCS() { PathTree pt0 = new PathTree(); PathTree pt1; + PathTree pt2 = new PathTree(); + PathTree pt3; List contents0 = loadContents("contents.list"); List contents1; + List contents2; + List contents3; byte[] bytes; @@ -130,31 +134,27 @@ public class TestPathTree { pt1 = new PathTree(bytes); contents1 = pt1.toList(); + // FIXME These next two fail assertTrue(cmpStrings(contents0, contents1)); assertEquals(contents0.size(), contents1.size()); - //System.out.println(contents0.size()); - //System.out.println(contents1.size()); - //Collections.sort(contents0); - //Collections.sort(contents1); - - /* - System.out.println("Originals, not in New"); - for (String thisS : contents0) { - if (! contents1.contains(thisS)) { - System.out.println(thisS); - } + // LET'S DO THE TIME WARP AGAIN!! + try { + pt2 = new PathTree(contents1); + } catch (PayloadException ex) { + fail(ex.toString()); } + contents2 = pt2.toList(); - System.out.println("New, not in Original"); - for (String thisS : contents1) { - if (! contents0.contains(thisS)) { - System.out.println(thisS); - } - } - */ + assertTrue(cmpStrings(contents1, contents2)); + assertEquals(contents1.size(), contents2.size()); + pt3 = new PathTree(pt2.getPayload()); + contents3 = pt3.toList(); + + assertTrue(cmpStrings(contents2, contents3)); + assertEquals(contents2.size(), contents3.size()); }