closing in:

* bonding the PathNode and NodePair more closely together.
* NO LONGER USING THE condensePathNodes logic
* moar unit test to ensure the logic can go there, and back again
* cleanup of multiline ternary statements
This commit is contained in:
Vincent Batts 2012-11-08 09:14:43 -05:00
parent 5e76776e74
commit 21730d6942
4 changed files with 112 additions and 55 deletions

View File

@ -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;
}

View File

@ -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<PathNode> 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<PathNode> getAllNodes(PathNode node) {
Set<PathNode> nodes = new HashSet<PathNode>();
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;
}
}

View File

@ -396,13 +396,24 @@ public class PathTree {
* @return is the same object as the parent param
*/
public static PathNode makePathTree(List<String> 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<PathNode> result = new ArrayList<PathNode>();
// walk tree to make string map
Set<PathNode> nodes = getPathNodes(treeRoot);
Set<PathNode> 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<PathNode> getPathNodes(PathNode treeRoot) {
Set<PathNode> nodes = new HashSet<PathNode>();
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<PathNode> parentResult = new ArrayList<PathNode>();
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
}
}
}

View File

@ -113,8 +113,12 @@ public class TestPathTree {
public void testThereAndBackAgainCS() {
PathTree pt0 = new PathTree();
PathTree pt1;
PathTree pt2 = new PathTree();
PathTree pt3;
List<String> contents0 = loadContents("contents.list");
List<String> contents1;
List<String> contents2;
List<String> 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());
}