Skip to content

Commit

Permalink
Groups
Browse files Browse the repository at this point in the history
  • Loading branch information
pkriens committed Mar 21, 2011
1 parent cd4c24d commit 4e7e6b8
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 0 deletions.
22 changes: 22 additions & 0 deletions aQute.libg/src/aQute/lib/collections/Logic.java
@@ -0,0 +1,22 @@
package aQute.lib.collections;

import java.util.*;

public class Logic {

public static <T> Collection<T> retain( Collection<T> first, Collection<T> ... sets) {
Set<T> result = new HashSet<T>(first);
for ( Collection<T> set : sets ) {
result.retainAll(set);
}
return result;
}

public static <T> Collection<T> remove( Collection<T> first, Collection<T> ... sets) {
Set<T> result = new HashSet<T>(first);
for ( Collection<T> set : sets ) {
result.removeAll(set);
}
return result;
}
}
12 changes: 12 additions & 0 deletions aQute.libg/src/aQute/libg/filecheck/FileCheck.java
@@ -0,0 +1,12 @@
package aQute.libg.filecheck;


public class FileCheck {

public static void main(String args[] ) {
// File f = new File("/Ws/osgi/build").getAbsoluteFile();
// long now = System.currentTimeMillis();
// traverse(f);
// System.out.printf("")
}
}
108 changes: 108 additions & 0 deletions aQute.libg/src/aQute/libg/tarjan/Tarjan.java
@@ -0,0 +1,108 @@
package aQute.libg.tarjan;

import static java.lang.Math.*;

import java.util.*;

public class Tarjan<T> {

public class Node {
final T name;
final List<Node> adjacent = new ArrayList<Node>();
int low = -1;
int index = -1;

public Node(T name) {
this.name = name;
}

public String toString() {
return name + "{" + index + "," + low + "}";
}
}

private int index = 0;
private List<Node> stack = new ArrayList<Node>();
private Set<Set<T>> scc = new HashSet<Set<T>>();
private Node root = new Node(null);


// public ArrayList<ArrayList<Node>> tarjan(Node v, AdjacencyList list){
// v.index = index;
// v.lowlink = index;
// index++;
// stack.add(0, v);
// for(Edge e : list.getAdjacent(v)){
// Node n = e.to;
// if(n.index == -1){
// tarjan(n, list);
// v.lowlink = Math.min(v.lowlink, n.lowlink);
// }else if(stack.contains(n)){
// v.lowlink = Math.min(v.lowlink, n.index);
// }
// }
// if(v.lowlink == v.index){
// Node n;
// ArrayList<Node> component = new ArrayList<Node>();
// do{
// n = stack.remove(0);
// component.add(n);
// }while(n != v);
// SCC.add(component);
// }
// return SCC;
// }

void tarjan(Node v) {
v.index = index;
v.low = index;
index++;
stack.add(0, v);
for (Node n : v.adjacent) {
if (n.index == -1) {
// first time visit
tarjan(n);
v.low = min(v.low, n.low);
} else if (stack.contains(n)) {
v.low = min(v.low, n.index);
}
}

if (v!=root && v.low == v.index) {
Set<T> component = new HashSet<T>();
Node n;
do {
n = stack.remove(0);
component.add(n.name);
} while (n != v);
scc.add(component);
}
}

Set<Set<T>> getResult(Map<T, ? extends Collection<T>> graph) {
Map<T, Node> index = new HashMap<T, Node>();

for (Map.Entry<T, ? extends Collection<T>> entry : graph.entrySet()) {
Node node = getNode(index, entry.getKey());
root.adjacent.add(node);
for (T adj : entry.getValue())
node.adjacent.add(getNode(index, adj));
}
tarjan(root);
return scc;
}

private Node getNode(Map<T, Node> index, T key) {
Node node = index.get(key);
if (node == null) {
node = new Node(key);
index.put(key, node);
}
return node;
}

public static <T> Set<Set<T>> tarjan(Map<T, Set<T>> graph) {
Tarjan<T> tarjan = new Tarjan<T>();
return tarjan.getResult(graph);
}
}
52 changes: 52 additions & 0 deletions aQute.libg/src/test/TestTarjan.java
@@ -0,0 +1,52 @@
package test;

import java.util.*;

import junit.framework.*;
import aQute.lib.collections.*;
import aQute.libg.tarjan.*;

public class TestTarjan extends TestCase {

public void testTarjan() throws Exception {
MultiMap<String, String> g = mkGraph("A{BC}B{A}C{DE}D{C}E{D}");
System.out.println(g);

Set<Set<String>> scc = Tarjan.tarjan(g);

assertEquals(2, scc.size());
for ( Set<String> set : scc) {
if ( set.size()==3)
assertEquals( new HashSet<String>(Arrays.asList("E","C", "D")), set);
else if ( set.size()==2)
assertEquals( new HashSet<String>(Arrays.asList("B","A")), set);
else
fail();
}
}

private MultiMap<String, String> mkGraph(String string) {
MultiMap<String, String> map = new MultiMap<String, String>();

String key = null;

for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
switch (c) {
case '{':
break;
case '}':
key = null;
break;
default:
if (key == null) {
key = c + "";
map.put(key, new HashSet<String>());
}
else
map.add(key, c + "");
}
}
return map;
}
}
81 changes: 81 additions & 0 deletions biz.aQute.bndlib/src/test/GroupsTest.java
@@ -0,0 +1,81 @@
package test;

import java.io.*;
import java.util.*;

import junit.framework.*;
import aQute.lib.collections.*;
import aQute.lib.osgi.*;
import static aQute.lib.collections.Logic.*;

public class GroupsTest extends TestCase{

static class Group implements Comparable<Group>{
final Set<String> name;
final Set<String> refs;

public Group(Set<String> key, Set<String> value) {

name = key;
refs = value;
}

public int compareTo(Group o) {
int n = o.name.size()-name.size();
if ( n != 0)
return n;

n = o.refs.size() - refs.size();

if ( n != 0)
return n;

String s1 = name.iterator().next();
String s2 = o.name.iterator().next();
return s1.compareTo(s2);
}

public String toString() {
return name.toString();
}
}

public void testSimple() throws Exception {
Builder b = new Builder();
// b.addClasspath(new File("../biz.aQute.bnd/tmp/biz.aQute.bnd.jar"));
// b.addClasspath(new File("jar/spring.jar"));
b.addClasspath(new File("/Ws/aQute.old/aQute.google/lib/gwt-dev-windows.jar"));
b.setProperty("Private-Package", "*");
Jar build = b.build();

MultiMap<Set<String>, String> x = b.getGroups();
SortedSet<Group> groups = new TreeSet<Group>();

for ( Map.Entry<Set<String>,Set<String>> entry : x.entrySet()) {
groups.add( new Group(entry.getKey(), entry.getValue()));
}

Iterator<Group> i = groups.iterator();
Group main = i.next();
System.out.println("Main " + main);

while ( i.hasNext() ) {
Group g = i.next();
System.out.println("Trying " + g);
if ( !retain(main.refs,g.name).isEmpty()) {
Collection<String> newReferences = remove(g.refs, main.refs, main.name, g.name);
if ( newReferences.isEmpty()) {
System.out.println("merging " + g);
main.name.addAll(g.name);
i.remove();
}
else System.out.println(" would add " + newReferences);
}
else System.out.println(" main does not refer");
}

for ( Group g : groups) {
System.out.println(g);
}
}
}

0 comments on commit 4e7e6b8

Please sign in to comment.