summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-05-20 22:09:13 +0000
committerRich Hickey <richhickey@gmail.com>2006-05-20 22:09:13 +0000
commit83ad2c71e2c6f5c929c3d632f4eb4e0b694b74f5 (patch)
tree2b7eea24e577ce6c212c5521481767650d77f460
parent9f7e2632e8c9d13a5bff7d028cad692e34466032 (diff)
interim checkin
-rw-r--r--src/org/clojure/runtime/RBSet.java151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/org/clojure/runtime/RBSet.java b/src/org/clojure/runtime/RBSet.java
new file mode 100644
index 00000000..24c6aa71
--- /dev/null
+++ b/src/org/clojure/runtime/RBSet.java
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) Rich Hickey. All rights reserved.
+ * The use and distribution terms for this software are covered by the
+ * Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
+ * which can be found in the file CPL.TXT at the root of this distribution.
+ * By using this software in any fashion, you are agreeing to be bound by
+ * the terms of this license.
+ * You must not remove this notice, or any other, from this software.
+ **/
+
+/* rich May 20, 2006 */
+
+package org.clojure.runtime;
+
+import java.util.Comparator;
+
+public class RBSet{
+
+public final Comparator comp;
+public final Node tree;
+public final int count;
+
+public RBSet(Comparator comp)
+ {
+ this.comp = comp;
+ tree = null;
+ count = 0;
+ }
+
+public boolean contains(Object x)
+ {
+ return treeContains(tree,x);
+ }
+
+public RBSet add(Object x)
+ {
+ Node t = treeInsert(tree,x);
+ if(t == null) //null == already contains x
+ return this;
+ return new RBSet(comp, t, count + 1);
+ }
+
+Node treeInsert(Node t, Object x)
+ {
+ if(t == null)
+ return red(x, null, null);
+ int c = comp.compare(t.key,x);
+ if(c == 0)
+ return null;
+ Node ins = c < 0 ? treeInsert(t.left, x) : treeInsert(t.right, x);
+ if(ins == null) //found below
+ return null;
+ if(t instanceof Black)
+ {
+ if(c < 0)
+ return leftBalance(x, ins, t.right);
+ return rightBalance(x, t.left, ins);
+ }
+ else //Red
+ {
+ if(c < 0)
+ return red(x, ins, t.right);
+ return red(x, t.left, ins);
+ }
+ }
+
+Node leftBalance(Object x, Node left, Node right)
+ {
+ if(left instanceof Red && left.left instanceof Red)
+ return red(left.key, blacken(left.left), black(x, left.right, right));
+ else if(left instanceof Red && left.right instanceof Red)
+ return red(left.right.key, black(left.key,left.left, left.right.left), black(x, left.right.right, right));
+ else
+ return black(x, left, right);
+ }
+
+Node rightBalance(Object x, Node left, Node right)
+ {
+ if(right instanceof Red && right.right instanceof Red)
+ return red(right.key, black(x, left, right.left), blacken(right.right));
+ else if(right instanceof Red && right.left instanceof Red)
+ return red(right.right.key, black(x, left, right.left.left), black(right.key, right.left.right, right));
+ else
+ return black(x, left, right);
+ }
+
+
+Node blacken(Node n)
+ {
+ return black(n.key, n.left, n.right);
+ }
+
+boolean treeContains(Node t,Object x)
+ {
+ if(t == null)
+ return false;
+ int c = comp.compare(t.key,x);
+ if(c == 0)
+ return true;
+ else if(c < 0)
+ return treeContains(t.left, x);
+ return treeContains(t.right, x);
+ }
+
+RBSet(Comparator comp, Node tree, int count)
+ {
+ this.comp = comp;
+ this.tree = tree;
+ this.count = count;
+ }
+
+static Red red(Object key,Node left,Node right)
+ {
+ return new Red(key, left, right);
+ }
+
+static Black black(Object key,Node left,Node right)
+ {
+ return new Black(key, left, right);
+ }
+
+static public class Node{
+ public Object key;
+ public Node left;
+ public Node right;
+ public Node(Object key,Node left,Node right)
+ {
+ this.key = key;
+ this.left = left;
+ this.right = right;
+ }
+}
+
+static public class Red extends Node{
+ public Red(Object key,Node left,Node right)
+ {
+ super(key, left, right);
+ }
+
+}
+
+static public class Black extends Node{
+ public Black(Object key,Node left,Node right)
+ {
+ super(key, left, right);
+ }
+
+}
+
+
+}