summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-05-22 16:20:14 +0000
committerRich Hickey <richhickey@gmail.com>2006-05-22 16:20:14 +0000
commit7e7516821258dd51e411b51a8851c54320f64dc3 (patch)
tree439a480e0247329fb03702bb837f877b0c793314 /src
parent13c410d343b4898d6cc17cda6b60d6776f50bd36 (diff)
added typed nodes, vals, val and key iterators, put
Diffstat (limited to 'src')
-rw-r--r--src/org/clojure/runtime/RBSet.java488
1 files changed, 356 insertions, 132 deletions
diff --git a/src/org/clojure/runtime/RBSet.java b/src/org/clojure/runtime/RBSet.java
index bd35efa9..0c81c656 100644
--- a/src/org/clojure/runtime/RBSet.java
+++ b/src/org/clojure/runtime/RBSet.java
@@ -20,235 +20,454 @@ public final Comparator comp;
public final Node tree;
public final int count;
-public RBSet()
- {
+public RBSet(){
this(null);
- }
+}
-public RBSet(Comparator comp)
- {
+public RBSet(Comparator comp){
this.comp = comp;
tree = null;
count = 0;
- }
+}
-public boolean contains(Object key)
- {
+public boolean contains(Object key){
return find(key) != null;
- }
+}
-public RBSet add(Object key)
- {
- Node t = add(tree,key);
+public RBSet add(Object key){
+ return put(key, null);
+}
+
+public RBSet put(Object key,Object val){
+ Box found = new Box(null);
+ Node t = add(tree, key, val, found);
if(t == null) //null == already contains key
+ {
+ Node foundNode = (Node) found.val;
+ if(foundNode.val() == val) //note only get same collection on identity of val, not equals()
+ return this;
+ return new RBSet(comp, replace(tree,key,val), count);
+ }
+ return new RBSet(comp, t.blacken(), count + 1);
+}
+
+
+/*
+public RBSet remove(Object key){
+ Node t = remove(tree, key);
+ if(t == null) //null == doesn't contain key
return this;
if(t instanceof Red)
t = blacken(t);
- return new RBSet(comp, t, count + 1);
- }
-
-
+ return new RBSet(comp, t, count - 1);
+}
+*/
-public Iterator iterator()
- {
+public NodeIterator iterator(){
return new NodeIterator(tree, true);
- }
+}
-public Iterator reverseIterator()
- {
+public NodeIterator reverseIterator(){
return new NodeIterator(tree, false);
- }
+}
-public Object min()
- {
+public Iterator keys(){
+ return keys(iterator());
+}
+
+public Iterator vals(){
+ return vals(iterator());
+}
+
+public Iterator keys(NodeIterator it){
+ return new KeyIterator(it);
+}
+
+public Iterator vals(NodeIterator it){
+ return new ValIterator(it);
+}
+
+public Object min(){
Node t = tree;
if(t != null)
{
- while(t.left != null)
- t = t.left;
+ while(t.left() != null)
+ t = t.left();
}
return t != null ? t.key : null;
- }
+}
-public Object max()
- {
+public Object max(){
Node t = tree;
if(t != null)
{
- while(t.right != null)
- t = t.right;
+ while(t.right() != null)
+ t = t.right();
}
return t != null ? t.key : null;
- }
+}
-public int depth()
- {
+public int depth(){
return depth(tree);
- }
+}
-int depth(Node t)
- {
+int depth(Node t){
if(t == null)
return 0;
- return 1 + Math.max(depth(t.left), depth(t.right));
- }
+ return 1 + Math.max(depth(t.left()), depth(t.right()));
+}
-Node find(Object key)
- {
+Node find(Object key){
Node t = tree;
while(t != null)
{
- int c = compare(key,t.key);
+ int c = compare(key, t.key);
if(c == 0)
return t;
else if(c < 0)
- t = t.left;
+ t = t.left();
else
- t = t.right;
+ t = t.right();
}
return t;
- }
+}
-int compare(Object k1,Object k2)
- {
+int compare(Object k1, Object k2){
if(comp != null)
return comp.compare(k1, k2);
return ((Comparable) k1).compareTo(k2);
- }
+}
-Node add(Node t, Object key)
- {
+Node add(Node t, Object key, Object val, Box found){
if(t == null)
- return red(key, null, null);
- int c = compare(key,t.key);
+ {
+ if(val == null)
+ return new Red(key);
+ return new RedVal(key,val);
+ }
+ int c = compare(key, t.key);
if(c == 0)
+ {
+ found.val = t;
return null;
- Node ins = c < 0 ? add(t.left, key) : add(t.right, key);
+ }
+ Node ins = c < 0 ? add(t.left(), key, val, found) : add(t.right(), key, val, found);
if(ins == null) //found below
return null;
- if(t instanceof Black)
+ if(c < 0)
+ return t.addLeft(ins);
+ return t.addRight(ins);
+}
+
+Node replace(Node t, Object key, Object val){
+ int c = compare(key, t.key);
+ return t.replace(t.key,
+ c==0?val:t.val(),
+ c<0?replace(t.left(),key,val):t.left(),
+ c>0?replace(t.right(),key,val):t.right());
+}
+
+RBSet(Comparator comp, Node tree, int count){
+ this.comp = comp;
+ this.tree = tree;
+ this.count = count;
+}
+
+static Red red(Object key, Object val, Node left, Node right){
+ if(left == null && right == null)
{
- if(c < 0)
- return leftBalance(t.key, ins, t.right);
- return rightBalance(t.key, t.left, ins);
+ if(val == null)
+ return new Red(key);
+ return new RedVal(key, val);
}
- else //Red
+ if(val == null)
+ return new RedBranch(key, left, right);
+ return new RedBranchVal(key, val, left, right);
+}
+
+static Black black(Object key, Object val, Node left, Node right){
+ if(left == null && right == null)
{
- if(c < 0)
- return red(t.key, ins, t.right);
- return red(t.key, t.left, ins);
+ if(val == null)
+ return new Black(key);
+ return new BlackVal(key, val);
}
+ if(val == null)
+ return new BlackBranch(key, left, right);
+ return new BlackBranchVal(key, val, left, right);
+}
+
+
+static abstract class Node{
+ final Object key;
+
+ Node(Object key){
+ this.key = key;
}
-Node leftBalance(Object key, Node ins, Node right)
- {
- if(ins instanceof Red && ins.left instanceof Red)
- return red(ins.key, blacken(ins.left), black(key, ins.right, right));
- else if(ins instanceof Red && ins.right instanceof Red)
- return red(ins.right.key, black(ins.key,ins.left, ins.right.left), black(key, ins.right.right, right));
- else
- return black(key, ins, right);
+ public Object key(){
+ return key;
}
-Node rightBalance(Object key, Node left, Node ins)
- {
- if(ins instanceof Red && ins.right instanceof Red)
- return red(ins.key, black(key, left, ins.left), blacken(ins.right));
- else if(ins instanceof Red && ins.left instanceof Red)
- return red(ins.left.key, black(key, left, ins.left.left), black(ins.key, ins.left.right, ins.right));
- else
- return black(key, left, ins);
+ public Object val(){
+ return null;
}
-Node blacken(Node n)
- {
- return black(n.key, n.left, n.right);
+ Node left(){
+ return null;
}
-RBSet(Comparator comp, Node tree, int count)
- {
- this.comp = comp;
- this.tree = tree;
- this.count = count;
+ Node right(){
+ return null;
+ }
+
+ abstract Node addLeft(Node ins);
+
+ abstract Node addRight(Node ins);
+
+ abstract Node blacken();
+
+ Node balanceLeft(Node parent){
+ return black(parent.key, parent.val(), this, parent.right());
+ }
+
+ Node balanceRight(Node parent){
+ return black(parent.key, parent.val(), parent.left(), this);
}
-static Red red(Object key,Node left,Node right)
- {
- return new Red(key, left, right);
+ abstract Node replace(Object key, Object val, Node left, Node right);
+}
+
+static class Black extends Node{
+ public Black(Object key){
+ super(key);
}
-static Black black(Object key,Node left,Node right)
- {
- return new Black(key, left, right);
+ Node addLeft(Node ins){
+ return ins.balanceLeft(this);
}
-static class Node{
- public final Object key;
- public final Node left;
- public final Node right;
+ Node addRight(Node ins){
+ return ins.balanceRight(this);
+ }
- public Node(Object key,Node left,Node right)
- {
- this.key = key;
+ Node blacken(){
+ return this;
+ }
+
+ Node replace(Object key, Object val, Node left, Node right){
+ return black(key, val, left, right);
+ }
+}
+
+static class BlackVal extends Black{
+ final Object val;
+ public BlackVal(Object key,Object val){
+ super(key);
+ this.val = val;
+ }
+
+ public Object val(){
+ return val;
+ }
+}
+
+static class BlackBranch extends Black{
+ final Node left;
+ final Node right;
+ public BlackBranch(Object key,Node left,Node right){
+ super(key);
this.left = left;
this.right = right;
}
+
+ public Node left(){
+ return left;
+ }
+
+ public Node right(){
+ return right;
+ }
}
-static class Red extends Node{
- public Red(Object key,Node left,Node right)
- {
+static class BlackBranchVal extends BlackBranch{
+ final Object val;
+ public BlackBranchVal(Object key,Object val,Node left,Node right){
super(key, left, right);
- }
+ this.val = val;
+ }
+ public Object val(){
+ return val;
+ }
}
-static class Black extends Node{
- public Black(Object key,Node left,Node right)
- {
- super(key, left, right);
+static class Red extends Node{
+ public Red(Object key){
+ super(key);
+ }
+
+ Node addLeft(Node ins){
+ return red(key, val(), ins, right());
+ }
+
+ Node addRight(Node ins){
+ return red(key, val(), left(), ins);
+ }
+
+ Node blacken(){
+ return new Black(key);
+ }
+
+ Node replace(Object key, Object val, Node left, Node right){
+ return red(key, val, left, right);
+ }
+}
+
+static class RedVal extends Red{
+ final Object val;
+ public RedVal(Object key,Object val){
+ super(key);
+ this.val = val;
+ }
+
+ public Object val(){
+ return val;
+ }
+
+ Node blacken(){
+ return new BlackVal(key, val);
+ }
+}
+
+static class RedBranch extends Red{
+ final Node left;
+ final Node right;
+ public RedBranch(Object key,Node left,Node right){
+ super(key);
+ this.left = left;
+ this.right = right;
}
+
+ public Node left(){
+ return left;
+ }
+
+ public Node right(){
+ return right;
+ }
+
+ Node balanceLeft(Node parent){
+ if(left instanceof Red)
+ return red(key, val(), left.blacken(), black(parent.key, parent.val(), right, parent.right()));
+ else if(right instanceof Red)
+ return red(right.key, right.val(),black(key, val(), left, right.left()),
+ black(parent.key, parent.val(), right.right(), parent.right()));
+ else
+ return super.balanceLeft(parent);
+
+ }
+
+ Node balanceRight(Node parent){
+ if(right instanceof Red)
+ return red(key, val(), black(parent.key, parent.val(), parent.left(), left), right.blacken());
+ else if(left instanceof Red)
+ return red(left.key, left.val(), black(parent.key, parent.val(), parent.left(), left.left()),
+ black(key, val(), left.right(), right));
+ else
+ return super.balanceRight(parent);
+ }
+
+ Node blacken(){
+ return new BlackBranch(key, left, right);
+ }
}
+static class RedBranchVal extends RedBranch{
+ final Object val;
+ public RedBranchVal(Object key,Object val,Node left,Node right){
+ super(key, left, right);
+ this.val = val;
+ }
+ public Object val(){
+ return val;
+ }
+
+ Node blacken(){
+ return new BlackBranchVal(key, val, left, right);
+ }
+}
-static class NodeIterator implements Iterator{
+static public class NodeIterator implements Iterator{
Stack stack = new Stack();
boolean asc;
- NodeIterator(Node t,boolean asc)
- {
+ NodeIterator(Node t, boolean asc){
this.asc = asc;
push(t);
- }
+ }
- void push(Node t)
- {
+ void push(Node t){
while(t != null)
{
stack.push(t);
- t = asc ? t.left:t.right;
+ t = asc ? t.left() : t.right();
}
- }
+ }
- public boolean hasNext()
- {
+ public boolean hasNext(){
return !stack.isEmpty();
- }
+ }
- public Object next()
- {
+ public Object next(){
Node t = (Node) stack.pop();
- push(asc ? t.right:t.left);
- return t.key;
- }
+ push(asc ? t.right() : t.left());
+ return t;
+ }
- public void remove()
- {
+ public void remove(){
throw new UnsupportedOperationException();
- }
+ }
+}
+
+static class KeyIterator implements Iterator{
+ NodeIterator it;
+ KeyIterator(NodeIterator it){
+ this.it = it;
+ }
+
+ public boolean hasNext(){
+ return it.hasNext();
+ }
+
+ public Object next(){
+ return ((Node)it.next()).key;
+ }
+
+ public void remove(){
+ throw new UnsupportedOperationException();
+ }
}
-static public void main(String args[])
- {
+static class ValIterator implements Iterator{
+ NodeIterator it;
+ ValIterator(NodeIterator it){
+ this.it = it;
+ }
+
+ public boolean hasNext(){
+ return it.hasNext();
+ }
+
+ public Object next(){
+ return ((Node)it.next()).val();
+ }
+
+ public void remove(){
+ throw new UnsupportedOperationException();
+ }
+}
+
+static public void main(String args[]){
if(args.length != 1)
System.err.println("Usage: RBSet n");
int n = Integer.parseInt(args[0]);
@@ -265,16 +484,21 @@ static public void main(String args[])
Integer anInt = ints[i];
set = set.add(anInt);
}
+ for(int i = 0; i < ints.length; i++)
+ {
+ Integer anInt = ints[i];
+ set = set.put(anInt,anInt);
+ }
System.out.println("count = " + set.count + ", min: " + set.min() + ", max: " + set.max()
+ ", depth: " + set.depth());
- Iterator it = set.iterator();
+ Iterator it = set.keys();
while(it.hasNext())
{
- Object o = it.next();
+ Object o = it.next();
if(!set.contains(o))
System.err.println("Can't find: " + o);
- else
- System.out.print(o.toString()+",");
+ else if(n < 2000)
+ System.out.print(o.toString() + ",");
}
- }
+}
}