cleanup, and consolidation
This commit is contained in:
parent
21730d6942
commit
348bf9d377
9 changed files with 235 additions and 151 deletions
10
build.xml
10
build.xml
|
@ -1,9 +1,10 @@
|
|||
<project name="trie" default="dist" basedir=".">
|
||||
<project name="PathPacker" default="dist" basedir=".">
|
||||
<description>
|
||||
simple example build file
|
||||
simple build file, for the PathPacker trie library.
|
||||
http://github.com/vbatts/PathPacker/
|
||||
</description>
|
||||
<!-- 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="dist.dir" location="dist"/>
|
||||
<property name="doc.dir" location="doc"/>
|
||||
|
@ -22,6 +23,7 @@
|
|||
<classpath>
|
||||
<pathelement path="${classpath}"/>
|
||||
<pathelement location="lib/bcprov-jdk16-1.46.jar"/>
|
||||
<pathelement location="lib/log4j-1.2.15.jar"/>
|
||||
</classpath>
|
||||
</javac>
|
||||
</target>
|
||||
|
@ -29,7 +31,7 @@
|
|||
<target name="dist" depends="compile"
|
||||
description="generate the distribution" >
|
||||
<!-- 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>
|
||||
<attribute name="Main-Class" value="com.hashbangbash.trie.App"/>
|
||||
</manifest>
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -2,7 +2,7 @@
|
|||
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>
|
||||
<groupId>org.redhat.trie</groupId>
|
||||
<artifactId>trie</artifactId>
|
||||
<artifactId>PathPacker</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
|
|
7
run.sh
7
run.sh
|
@ -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
|
||||
|
|
@ -15,15 +15,18 @@ import java.io.FileOutputStream;
|
|||
import java.io.FileNotFoundException;
|
||||
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.Util;
|
||||
import com.redhat.trie.PayloadException;
|
||||
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
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;
|
||||
|
||||
|
||||
|
@ -35,6 +38,92 @@ import org.bouncycastle.x509.extension.X509ExtensionUtil;
|
|||
*/
|
||||
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 {
|
||||
InputStream is = new FileInputStream(file);
|
||||
|
||||
|
@ -72,7 +161,7 @@ public class App {
|
|||
|
||||
|
||||
public static List<String> hydrateFromBytes(byte[] compressedBlob) {
|
||||
return Util.hydrateContentPackage(compressedBlob);
|
||||
return hydrateContentPackage(compressedBlob);
|
||||
}
|
||||
|
||||
public static List<String> hydrateFromFile(String filename) {
|
||||
|
@ -157,7 +246,7 @@ public class App {
|
|||
PathTree pt;
|
||||
try {
|
||||
pt = new PathTree(contentList);
|
||||
Util.printTree(pt.getRootPathNode(), 0);
|
||||
printTree(pt.getRootPathNode(), 0);
|
||||
} catch (PayloadException ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
|
@ -166,7 +255,7 @@ public class App {
|
|||
public static ASN1Encodable objectFromCertOid(String certFilename, String oid) {
|
||||
X509Certificate cert;
|
||||
cert = certFromFile(certFilename);
|
||||
return Util.objectFromOid(cert,oid);
|
||||
return objectFromOid(cert,oid);
|
||||
}
|
||||
|
||||
public static X509Certificate certFromFile(String certFilename) {
|
||||
|
|
|
@ -40,14 +40,12 @@ import org.apache.log4j.Logger;
|
|||
* PathTree
|
||||
*
|
||||
* An efficient means by which to check the content sets.
|
||||
*
|
||||
* TODO - this is a prototype stub
|
||||
*/
|
||||
public class PathTree {
|
||||
private static org.apache.log4j.Logger log = Logger.getLogger(PathTree.class);
|
||||
private List<HuffNode> nodeDictionary;
|
||||
private List<HuffNode> pathDictionary;
|
||||
private StringBuffer nodeBits; // TODO make a smart getter for this
|
||||
private StringBuffer nodeBits;
|
||||
|
||||
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) {
|
||||
StringTokenizer st = new StringTokenizer(contentPath, "/");
|
||||
|
@ -339,10 +340,6 @@ public class PathTree {
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean matches(PathNode pn, StringTokenizer st) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* consume the list of content sets, and operate the same way.
|
||||
*
|
||||
|
@ -585,9 +582,6 @@ public class PathTree {
|
|||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private List<HuffNode> getStringNodeList(List<String> pathStrings) {
|
||||
List<HuffNode> nodes = new ArrayList<HuffNode>();
|
||||
int idx = 1;
|
||||
|
@ -598,9 +592,6 @@ public class PathTree {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private List<HuffNode> getPathNodeNodeList(List<PathNode> pathNodes) {
|
||||
List<HuffNode> nodes = new ArrayList<HuffNode>();
|
||||
int idx = 0;
|
||||
|
@ -847,6 +838,11 @@ public class PathTree {
|
|||
(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) {
|
||||
// "equivalent" parents are merged
|
||||
List<PathNode> parentResult = new ArrayList<PathNode>();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import java.io.IOException;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Test;
|
||||
|
@ -51,6 +52,32 @@ public class TestPathTree {
|
|||
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
|
||||
public void testRootNode() {
|
||||
PathTree pt = new PathTree();
|
||||
|
|
88
tools/handy.rb
Executable file
88
tools/handy.rb
Executable 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
9
tools/run.sh
Executable 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
|
||||
|
Loading…
Reference in a new issue