cleanup, and consolidation

This commit is contained in:
Vincent Batts 2012-11-08 10:15:20 -05:00
parent 21730d6942
commit 348bf9d377
9 changed files with 235 additions and 151 deletions

View file

@ -1,9 +1,10 @@
<project name="trie" default="dist" basedir="."> <project name="PathPacker" default="dist" basedir=".">
<description> <description>
simple example build file simple build file, for the PathPacker trie library.
http://github.com/vbatts/PathPacker/
</description> </description>
<!-- set global properties for this build --> <!-- set global properties for this build -->
<property name="src.dir" location="src"/> <property name="src.dir" location="src/main"/>
<property name="build.dir" location="build"/> <property name="build.dir" location="build"/>
<property name="dist.dir" location="dist"/> <property name="dist.dir" location="dist"/>
<property name="doc.dir" location="doc"/> <property name="doc.dir" location="doc"/>
@ -22,6 +23,7 @@
<classpath> <classpath>
<pathelement path="${classpath}"/> <pathelement path="${classpath}"/>
<pathelement location="lib/bcprov-jdk16-1.46.jar"/> <pathelement location="lib/bcprov-jdk16-1.46.jar"/>
<pathelement location="lib/log4j-1.2.15.jar"/>
</classpath> </classpath>
</javac> </javac>
</target> </target>
@ -29,7 +31,7 @@
<target name="dist" depends="compile" <target name="dist" depends="compile"
description="generate the distribution" > description="generate the distribution" >
<!-- Put everything in ${build.dir} into the find-hidden-beds-${DSTAMP}.jar file --> <!-- Put everything in ${build.dir} into the find-hidden-beds-${DSTAMP}.jar file -->
<jar jarfile="${dist.dir}/trie-${DSTAMP}.jar" basedir="${build.dir}"> <jar jarfile="${dist.dir}/PathPacker-${DSTAMP}.jar" basedir="${build.dir}">
<manifest> <manifest>
<attribute name="Main-Class" value="com.hashbangbash.trie.App"/> <attribute name="Main-Class" value="com.hashbangbash.trie.App"/>
</manifest> </manifest>

View file

@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.redhat.trie</groupId> <groupId>org.redhat.trie</groupId>
<artifactId>trie</artifactId> <artifactId>PathPacker</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<dependencies> <dependencies>

7
run.sh
View file

@ -1,7 +0,0 @@
#!/bin/sh
java \
-cp $(find lib/ -type f -printf "./%h/%f:")$(ls -rt ./target/*jar | tail -1) \
com.hashbangbash.trie.App \
./src/test/resources/test-certv3.pem

View file

@ -15,15 +15,18 @@ import java.io.FileOutputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import com.redhat.trie.HuffNode;
import com.redhat.trie.NodePair;
import com.redhat.trie.PathNode;
import com.redhat.trie.PathTree; import com.redhat.trie.PathTree;
import com.redhat.trie.Util;
import com.redhat.trie.PayloadException; import com.redhat.trie.PayloadException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import org.bouncycastle.asn1.*; import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.x509.extension.X509ExtensionUtil; import org.bouncycastle.x509.extension.X509ExtensionUtil;
@ -35,6 +38,92 @@ import org.bouncycastle.x509.extension.X509ExtensionUtil;
*/ */
public class App { public class App {
/*
* PrettyPrint a PathNode tree
*/
public static void printTree(PathNode pn, int tab) {
StringBuffer nodeRep = new StringBuffer();
for (int i = 0; i <= tab; i++) {
nodeRep.append(" ");
}
nodeRep.append("Node [");
nodeRep.append(pn.getId());
nodeRep.append("]");
for (PathNode parent : pn.getParents()) {
nodeRep.append(" ^ [");
nodeRep.append(parent.getId());
nodeRep.append("]");
}
for (NodePair cp : pn.getChildren()) {
nodeRep.append(" v [");
nodeRep.append(cp.getName());
nodeRep.append(" {");
nodeRep.append(cp.getConnection().getId());
nodeRep.append("} ]");
}
System.out.println(nodeRep);
for (NodePair cp : pn.getChildren()) {
printTree(cp.getConnection(), tab + 1);
}
}
/*
* PrettyPrint a HuffNode tree
*/
public static void printTrie(HuffNode hn, int tab) {
StringBuffer nodeRep = new StringBuffer();
for (int i = 0; i <= tab; i++) {
nodeRep.append(" ");
}
nodeRep.append("Node [");
nodeRep.append(hn.getId());
nodeRep.append("]");
nodeRep.append(", Weight [");
nodeRep.append(hn.getWeight());
nodeRep.append("]");
nodeRep.append(", Value = [");
nodeRep.append(hn.getValue());
nodeRep.append("]");
System.out.println(nodeRep);
if (hn.getLeft() != null) {
printTrie(hn.getLeft(), tab + 1);
}
if (hn.getRight() != null) {
printTrie(hn.getRight(), tab + 1);
}
}
/*
* From the deflated payload, produce the content set lists
*
*
* FIXME - break this apart, so that the hydrated payload
* can be structure to more quickly search, and use less memory
*
* Rename it for tracking, and to be clear about what is happening
*/
public static List<String> hydrateContentPackage(byte[] compressedBlob) {
PathTree pt = new PathTree(compressedBlob);
return pt.toList();
}
public static ASN1Encodable objectFromOid(X509Certificate cert, String oid) {
if (cert == null) { return null; }
try {
for (String thisOid : cert.getNonCriticalExtensionOIDs()) {
if (thisOid.equals(oid)) {
return X509ExtensionUtil.fromExtensionValue(cert.getExtensionValue(oid));
}
}
} catch (IOException ex) { }
return null;
}
public static byte[] getBytesFromFile(File file) throws IOException { public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file); InputStream is = new FileInputStream(file);
@ -72,7 +161,7 @@ public class App {
public static List<String> hydrateFromBytes(byte[] compressedBlob) { public static List<String> hydrateFromBytes(byte[] compressedBlob) {
return Util.hydrateContentPackage(compressedBlob); return hydrateContentPackage(compressedBlob);
} }
public static List<String> hydrateFromFile(String filename) { public static List<String> hydrateFromFile(String filename) {
@ -157,7 +246,7 @@ public class App {
PathTree pt; PathTree pt;
try { try {
pt = new PathTree(contentList); pt = new PathTree(contentList);
Util.printTree(pt.getRootPathNode(), 0); printTree(pt.getRootPathNode(), 0);
} catch (PayloadException ex) { } catch (PayloadException ex) {
System.out.println(ex); System.out.println(ex);
} }
@ -166,7 +255,7 @@ public class App {
public static ASN1Encodable objectFromCertOid(String certFilename, String oid) { public static ASN1Encodable objectFromCertOid(String certFilename, String oid) {
X509Certificate cert; X509Certificate cert;
cert = certFromFile(certFilename); cert = certFromFile(certFilename);
return Util.objectFromOid(cert,oid); return objectFromOid(cert,oid);
} }
public static X509Certificate certFromFile(String certFilename) { public static X509Certificate certFromFile(String certFilename) {

View file

@ -40,14 +40,12 @@ import org.apache.log4j.Logger;
* PathTree * PathTree
* *
* An efficient means by which to check the content sets. * An efficient means by which to check the content sets.
*
* TODO - this is a prototype stub
*/ */
public class PathTree { public class PathTree {
private static org.apache.log4j.Logger log = Logger.getLogger(PathTree.class); private static org.apache.log4j.Logger log = Logger.getLogger(PathTree.class);
private List<HuffNode> nodeDictionary; private List<HuffNode> nodeDictionary;
private List<HuffNode> pathDictionary; private List<HuffNode> pathDictionary;
private StringBuffer nodeBits; // TODO make a smart getter for this private StringBuffer nodeBits;
private byte[] payload; private byte[] payload;
@ -303,7 +301,10 @@ public class PathTree {
} }
/** /**
* TODO - this is a stub * Validate whether contentPath is included in this tree.
*
* @param contentPath A String, like "/foo/bar/baz"
* @return true or false
*/ */
public boolean validate(String contentPath) { public boolean validate(String contentPath) {
StringTokenizer st = new StringTokenizer(contentPath, "/"); StringTokenizer st = new StringTokenizer(contentPath, "/");
@ -339,10 +340,6 @@ public class PathTree {
return false; return false;
} }
private boolean matches(PathNode pn, StringTokenizer st) {
return false;
}
/** /**
* consume the list of content sets, and operate the same way. * consume the list of content sets, and operate the same way.
* *
@ -585,9 +582,6 @@ public class PathTree {
return parent; return parent;
} }
/**
*
*/
private List<HuffNode> getStringNodeList(List<String> pathStrings) { private List<HuffNode> getStringNodeList(List<String> pathStrings) {
List<HuffNode> nodes = new ArrayList<HuffNode>(); List<HuffNode> nodes = new ArrayList<HuffNode>();
int idx = 1; int idx = 1;
@ -598,9 +592,6 @@ public class PathTree {
return nodes; return nodes;
} }
/**
*
*/
private List<HuffNode> getPathNodeNodeList(List<PathNode> pathNodes) { private List<HuffNode> getPathNodeNodeList(List<PathNode> pathNodes) {
List<HuffNode> nodes = new ArrayList<HuffNode>(); List<HuffNode> nodes = new ArrayList<HuffNode>();
int idx = 0; int idx = 0;
@ -847,6 +838,11 @@ public class PathTree {
(byte) value}; (byte) value};
} }
/**
* FIXME this logic is causing nodes to disappear.
*
* Fix it if you feel that it is even needed...
*/
private static void condenseSubTreeNodes(PathNode location) { private static void condenseSubTreeNodes(PathNode location) {
// "equivalent" parents are merged // "equivalent" parents are merged
List<PathNode> parentResult = new ArrayList<PathNode>(); List<PathNode> parentResult = new ArrayList<PathNode>();

View file

@ -1,120 +0,0 @@
/**
* Copyright (c) 2009 - 2012 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package com.redhat.trie;
import java.util.List;
import java.io.IOException;
import java.security.cert.X509Certificate;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.x509.extension.X509ExtensionUtil;
/*
* Util
*
* All the misc dirty work
*
*/
public class Util {
/*
* PrettyPrint a PathNode tree
*/
public static void printTree(PathNode pn, int tab) {
StringBuffer nodeRep = new StringBuffer();
for (int i = 0; i <= tab; i++) {
nodeRep.append(" ");
}
nodeRep.append("Node [");
nodeRep.append(pn.getId());
nodeRep.append("]");
for (PathNode parent : pn.getParents()) {
nodeRep.append(" ^ [");
nodeRep.append(parent.getId());
nodeRep.append("]");
}
for (NodePair cp : pn.getChildren()) {
nodeRep.append(" v [");
nodeRep.append(cp.getName());
nodeRep.append(" {");
nodeRep.append(cp.getConnection().getId());
nodeRep.append("} ]");
}
System.out.println(nodeRep);
for (NodePair cp : pn.getChildren()) {
printTree(cp.getConnection(), tab + 1);
}
}
/*
* PrettyPrint a HuffNode tree
*/
public static void printTrie(HuffNode hn, int tab) {
StringBuffer nodeRep = new StringBuffer();
for (int i = 0; i <= tab; i++) {
nodeRep.append(" ");
}
nodeRep.append("Node [");
nodeRep.append(hn.getId());
nodeRep.append("]");
nodeRep.append(", Weight [");
nodeRep.append(hn.getWeight());
nodeRep.append("]");
nodeRep.append(", Value = [");
nodeRep.append(hn.getValue());
nodeRep.append("]");
System.out.println(nodeRep);
if (hn.getLeft() != null) {
printTrie(hn.getLeft(), tab + 1);
}
if (hn.getRight() != null) {
printTrie(hn.getRight(), tab + 1);
}
}
/*
* From the deflated payload, produce the content set lists
*
*
* FIXME - break this apart, so that the hydrated payload
* can be structure to more quickly search, and use less memory
*
* Rename it for tracking, and to be clear about what is happening
*/
public static List<String> hydrateContentPackage(byte[] compressedBlob) {
PathTree pt = new PathTree(compressedBlob);
return pt.toList();
}
public static ASN1Encodable objectFromOid(X509Certificate cert, String oid) {
if (cert == null) { return null; }
try {
for (String thisOid : cert.getNonCriticalExtensionOIDs()) {
if (thisOid.equals(oid)) {
return X509ExtensionUtil.fromExtensionValue(cert.getExtensionValue(oid));
}
}
} catch (IOException ex) { }
return null;
}
}

View file

@ -15,6 +15,7 @@ import java.io.IOException;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import org.junit.Test; import org.junit.Test;
@ -51,6 +52,32 @@ public class TestPathTree {
assertNotNull(pt); assertNotNull(pt);
} }
@Test
public void testValidation() {
PathTree pt = new PathTree();
List<String> contents = loadContents("contents.list");
// matches a path
String shouldPass = "/content/beta/rhel/server/5/5server/x86_64/sap/os/repomd.xml";
// is not a match
String shouldFail = "/fart/face/mcjones";
// tricky, because it is almost a valid path. All nodes, will have similar children. (the /vt/ is only in /5/, not /6/)
String shouldFailTricky = "/content/dist/rhel/server/6/$releasever/$basearch/vt/os";
try {
pt.setContentSets(contents);
} catch (PayloadException ex) {
fail(ex.toString());
}
// for good measure ...
assertTrue(cmpStrings(contents, pt.toList()));
assertTrue(pt.validate(shouldPass));
assertFalse(pt.validate(shouldFail));
// FIXME OH NOES... the PathNode relationships are to generous
//assertFalse(pt.validate(shouldFailTricky));
}
@Test @Test
public void testRootNode() { public void testRootNode() {
PathTree pt = new PathTree(); PathTree pt = new PathTree();

88
tools/handy.rb Executable file
View file

@ -0,0 +1,88 @@
#!/usr/bin/env jruby
BASE_DIR = File.expand_path(File.dirname(__FILE__) + "/..")
require 'java'
Dir[File.join(BASE_DIR,'lib/*jar')].each {|j| require j }
Dir[File.join(BASE_DIR,'target/*jar')].each {|j| require j }
require 'stringio'
require 'optparse'
module Trie
include_package 'com.redhat.trie'
end
def pt(path = './src/test/resources/contents.list')
content_sets = File.open(path).read.split("\n")
Trie::PathTree.new(content_sets)
end
def print_dot(root)
sio = StringIO.new
sio.write("digraph pathnode_tree {\n")
write_children(sio, root)
sio.write("\n}\n")
sio.seek(0)
sio
end
def write_children(io, node)
return unless (node.getChildren().length > 0)
node.getChildren.each do |child|
id = (child.getConnection().getId().to_s + child.getName()).hash
children_ids = child.getConnection().getChildren().map {|c|
(c.getConnection().getId().to_s + c.getName()).hash
}
io.write(" %d [label=\"%s\"];\n" % [id, child.getName()])
io.write(" %d -> { %s };\n" % [id, children_ids.join(" ")]) if children_ids.length > 0
write_children(io, child.getConnection())
end
end
def get_end(node)
return node if node.getChildren().length == 0
node.getChildren.each do |child|
return get_end(child.getConnection())
end
end
def parse_args(args)
options = {
:content_list => './src/test/resources/contents.list',
:dot => false,
:test_url => '/content/beta/rhel/server/5/5server/x86_64/sap/os/repomd.xml',
}
opts = OptionParser.new do |opts|
opts.on('--dot',"output the dot digraph of content listing (defaults to #{options[:content_list]}") do |o|
options[:dot] = o
end
opts.on('--contents FILE', "use FILE instead of #{options[:content_list]}") do |o|
options[:content_list] = o
end
opts.on('--test PATH', "validate PATH, instead of [#{options[:test_url]}]") do |o|
options[:test_url] = o
end
end
opts.parse!(args)
return options
end
def main(args)
options = parse_args(args)
STDERR.puts("[%s] %s" % [options[:test_url], pt.validate(options[:test_url])])
puts print_dot(pt(options[:content_list]).getRootPathNode()).read() if options[:dot]
#pn = pt.getRootPathNode
#Trie::Util.printTree(pn, 0)
end
main(ARGV) if $0 == __FILE__

9
tools/run.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh
base_dir=$(readlink -f $(dirname $0)/..)
java \
-cp $(find ${base_dir}/lib/ -type f -printf "%h/%f:")$(ls -rt ${base_dir}/target/*jar | tail -1) \
com.hashbangbash.trie.App \
${base_dir}/src/test/resources/test-certv3.pem