diff options
Diffstat (limited to 'src/cli/runtime/PersistentTreeMap.cs')
-rw-r--r-- | src/cli/runtime/PersistentTreeMap.cs | 869 |
1 files changed, 0 insertions, 869 deletions
diff --git a/src/cli/runtime/PersistentTreeMap.cs b/src/cli/runtime/PersistentTreeMap.cs deleted file mode 100644 index 743cb06d..00000000 --- a/src/cli/runtime/PersistentTreeMap.cs +++ /dev/null @@ -1,869 +0,0 @@ -/** - * 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 */ - -using System;
-using System.Collections;
-using System.Collections.Specialized;
- -namespace clojure.lang
-{ - -/** - * Persistent Red Black Tree - * Note that instances of this class are constant values - * i.e. add/remove etc return new values - * <p/> - * See Okasaki, Kahrs, Larsen et al - */ - -public class PersistentTreeMap : APersistentMap{ - -public readonly IComparer comp; -public readonly Node tree; -public readonly int _count; - -public PersistentTreeMap():this(null){ -} - -public PersistentTreeMap(IComparer comp){ - this.comp = comp; - tree = null; - _count = 0; -} - -override public int count(){ - return _count; - } - -override public bool contains(Object key){ - return find(key) != null; -}
-
-override public IPersistentMap assocEx(Object key,Object val){ - Box found = new Box(null); - Node t = add(tree, key, val, found); - if(t == null) //null == already contains key - { - throw new Exception("Key already present");
- } - return new PersistentTreeMap(comp, t.blacken(), _count + 1, _meta); -} - -override public Associative assoc(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 PersistentTreeMap(comp, replace(tree, key, val), _count, _meta); - }
- return new PersistentTreeMap(comp, t.blacken(), _count + 1, _meta); -} - - -override public IPersistentMap without(Object key){ - Box found = new Box(null); - Node t = remove(tree, key, found); - if(t == null) - { - if(found.val == null)//null == doesn't contain key - return this; - //empty
- PersistentTreeMap ret = new PersistentTreeMap(comp);
- ret._meta = _meta;
- return ret;
- }
- return new PersistentTreeMap(comp, t.blacken(), _count - 1, _meta); -} - -override public ISeq seq() {
- if(_count > 0)
- return Seq.create(tree, true,_count);
- return null;
-} - -public ISeq rseq() {
- if(_count > 0)
- return Seq.create(tree, false,_count);
- return null;
-} - -override public IEnumerator GetEnumerator(){ - return new NodeIEnumerator(tree, true); -} - -public NodeIEnumerator reverseIEnumerator(){ - return new NodeIEnumerator(tree, false); -} - -public IEnumerator keys(){
-return keys((NodeIEnumerator)GetEnumerator()); -} - -public IEnumerator vals(){
-return vals((NodeIEnumerator)GetEnumerator()); -} - -public IEnumerator keys(NodeIEnumerator it){ - return new KeyIEnumerator(it); -} - -public IEnumerator vals(NodeIEnumerator it){ - return new ValIEnumerator(it); -} - -public Object minKey(){ - Node t = min(); - return t!=null?t._key:null; -} - -public Node min(){ - Node t = tree; - if(t != null) - { - while(t.left() != null) - t = t.left(); - } - return t; -} - -public Object maxKey(){ - Node t = max(); - return t!=null?t._key:null; -} - -public Node max(){ - Node t = tree; - if(t != null) - { - while(t.right() != null) - t = t.right(); - } - return t; -} - -public int depth(){ - return depth(tree); -} - -int depth(Node t){ - if(t == null) - return 0; - return 1 + Math.Max(depth(t.left()), depth(t.right())); -} - -override public Object get(Object key){ - Node n = (Node)find(key); - return (n != null) ? n.val() : null; -} - -override public IMapEntry find(Object key){ - Node t = tree; - while(t != null) - { - int c = compare(key, t._key); - if(c == 0) - return t; - else if(c < 0) - t = t.left(); - else - t = t.right(); - } - return t; -} - -int compare(Object k1, Object k2){ - if(comp != null) - return comp.Compare(k1, k2); - return ((IComparable) k1).CompareTo(k2); -} - -Node add(Node t, Object key, Object val, Box found){ - if(t == null) - { - 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, val, found) : add(t.right(), key, val, found); - if(ins == null) //found below - return null; - if(c < 0) - return t.addLeft(ins); - return t.addRight(ins); -} - -Node remove(Node t, Object key, Box found){ - if(t == null) - return null; //not found indicator - int c = compare(key, t._key); - if(c == 0) - { - found.val = t; - return append(t.left(), t.right()); - } - Node del = c < 0 ? remove(t.left(), key, found) : remove(t.right(), key, found); - if(del == null && found.val == null) //not found below - return null; - if(c < 0) - { - if(t.left() is Black) - return balanceLeftDel(t._key, t.val(), del, t.right()); - else - return red(t._key, t.val(), del, t.right()); - } - if(t.right() is Black) - return balanceRightDel(t._key, t.val(), t.left(), del); - return red(t._key, t.val(), t.left(), del); -// return t.removeLeft(del); -// return t.removeRight(del); -} - -static Node append(Node left, Node right){ - if(left == null) - return right; - else if(right == null) - return left; - else if(left is Red) - { - if(right is Red) - { - Node app = append(left.right(), right.left()); - if(app is Red) - return red(app._key, app.val(), - red(left._key, left.val(), left.left(), app.left()), - red(right._key, right.val(), app.right(), right.right())); - else - return red(left._key, left.val(), left.left(), red(right._key, right.val(), app, right.right())); - } - else - return red(left._key, left.val(), left.left(), append(left.right(), right)); - } - else if(right is Red) - return red(right._key, right.val(), append(left, right.left()), right.right()); - else //black/black - { - Node app = append(left.right(), right.left()); - if(app is Red) - return red(app._key, app.val(), - black(left._key, left.val(), left.left(), app.left()), - black(right._key, right.val(), app.right(), right.right())); - else - return balanceLeftDel(left._key, left.val(), left.left(), black(right._key, right.val(), app, right.right())); - } -} - -static Node balanceLeftDel(Object key, Object val, Node del, Node right){ - if(del is Red) - return red(key, val, del.blacken(), right); - else if(right is Black) - return rightBalance(key, val, del, right.redden()); - else if(right is Red && right.left() is Black) - return red(right.left()._key, right.left().val(), - black(key, val, del, right.left().left()), - rightBalance(right._key, right.val(), right.left().right(), right.right().redden())); - else - throw new InvalidOperationException("Invariant violation"); -} - -static Node balanceRightDel(Object key, Object val, Node left, Node del){ - if(del is Red) - return red(key, val, left, del.blacken()); - else if(left is Black) - return leftBalance(key, val, left.redden(), del); - else if(left is Red && left.right() is Black) - return red(left.right()._key, left.right().val(), - leftBalance(left._key, left.val(), left.left().redden(), left.right().left()), - black(key, val, left.right().right(), del)); - else - throw new InvalidOperationException("Invariant violation"); -} - -static Node leftBalance(Object key, Object val, Node ins, Node right){ - if(ins is Red && ins.left() is Red) - return red(ins._key, ins.val(), ins.left().blacken(), black(key, val, ins.right(), right)); - else if(ins is Red && ins.right() is Red) - return red(ins.right()._key, ins.right().val(), - black(ins._key, ins.val(), ins.left(), ins.right().left()), - black(key, val, ins.right().right(), right)); - else - return black(key, val, ins, right); -} - - -static Node rightBalance(Object key, Object val, Node left, Node ins){ - if(ins is Red && ins.right() is Red) - return red(ins._key, ins.val(), black(key, val, left, ins.left()), ins.right().blacken()); - else if(ins is Red && ins.left() is Red) - return red(ins.left()._key, ins.left().val(), - black(key, val, left, ins.left().left()), - black(ins._key, ins.val(), ins.left().right(), ins.right())); - else - return black(key, val, left, 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()); -} - -PersistentTreeMap(IComparer comp, Node tree, int count,IPersistentMap meta){ - this.comp = comp; - this.tree = tree; - this._count = count; - this._meta = meta; -} - -static Red red(Object key, Object val, Node left, Node right){ - if(left == null && right == null) - { - if(val == null) - return new Red(key); - return new RedVal(key, val); - } - 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(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); -} - - -public abstract class Node : IMapEntry{ - internal readonly Object _key; - - internal Node(Object key){ - this._key = key; - } - - public Object key(){ - return _key; - } - - virtual public Object val(){ - return null; - }
-
- internal virtual Node left()
- { - return null; - }
-
- internal virtual Node right()
- { - return null; - } - - internal abstract Node addLeft(Node ins);
-
- internal abstract Node addRight(Node ins);
-
- internal abstract Node removeLeft(Node del);
-
- internal abstract Node removeRight(Node del);
-
- internal abstract Node blacken();
-
- internal abstract Node redden();
-
- internal virtual Node balanceLeft(Node parent)
- { - return black(parent._key, parent.val(), this, parent.right()); - }
-
- internal virtual Node balanceRight(Node parent)
- { - return black(parent._key, parent.val(), parent.left(), this); - }
-
- internal abstract Node replace(Object key, Object val, Node left, Node right); -} - -class Black : Node{ - public Black(Object key):base(key){ - } - - internal override Node addLeft(Node ins){ - return ins.balanceLeft(this); - }
-
- internal override Node addRight(Node ins)
- { - return ins.balanceRight(this); - }
-
- internal override Node removeLeft(Node del)
- { - return balanceLeftDel(_key, val(), del, right()); - }
-
- internal override Node removeRight(Node del)
- { - return balanceRightDel(_key, val(), left(), del); - }
-
- internal override Node blacken()
- { - return this; - }
-
- internal override Node redden()
- { - return new Red(_key); - }
-
- internal override Node replace(Object key, Object val, Node left, Node right)
- { - return black(key, val, left, right); - } -} - -class BlackVal : Black{ - readonly Object _val; - - public BlackVal(Object key, Object val):base(key){ - this._val = val; - } - - override public Object val(){ - return _val; - }
-
- internal override Node redden()
- { - return new RedVal(_key, _val); - } - -} - -class BlackBranch : Black{ - internal readonly Node _left; - internal readonly Node _right; - - public BlackBranch(Object key, Node left, Node right):base(key){ - this._left = left; - this._right = right; - }
-
- internal override Node left()
- { - return _left; - }
-
- internal override Node right()
- { - return _right; - }
-
- internal override Node redden()
- { - return new RedBranch(_key, _left, _right); - } - -} - -class BlackBranchVal : BlackBranch{ - readonly Object _val; - - public BlackBranchVal(Object key, Object val, Node left, Node right): base(key, left, right){ - this._val = val; - } - - override public Object val(){ - return _val; - }
-
- internal override Node redden()
- { - return new RedBranchVal(_key, _val, _left, _right); - } - -} - -class Red : Node{ - public Red(Object key):base(key){ - }
-
- internal override Node addLeft(Node ins)
- { - return red(_key, val(), ins, right()); - }
-
- internal override Node addRight(Node ins)
- { - return red(_key, val(), left(), ins); - }
-
- internal override Node removeLeft(Node del)
- { - return red(_key, val(), del, right()); - }
-
- internal override Node removeRight(Node del)
- { - return red(_key, val(), left(), del); - }
-
- internal override Node blacken()
- { - return new Black(_key); - }
-
- internal override Node redden()
- { - throw new InvalidOperationException("Invariant violation"); - }
-
- internal override Node replace(Object key, Object val, Node left, Node right)
- { - return red(key, val, left, right); - } -} - -class RedVal : Red{ - readonly Object _val; - - public RedVal(Object key, Object val):base(key){ - this._val = val; - } - - override public Object val(){ - return _val; - }
-
- internal override Node blacken()
- { - return new BlackVal(_key, _val); - } -} - -class RedBranch : Red{ - internal readonly Node _left; - internal readonly Node _right; - - public RedBranch(Object key, Node left, Node right):base(key){ - this._left = left; - this._right = right; - }
-
- internal override Node left()
- { - return _left; - }
-
- internal override Node right()
- { - return _right; - }
-
- internal override Node balanceLeft(Node parent)
- { - if(_left is Red) - return red(_key, val(), _left.blacken(), black(parent._key, parent.val(), _right, parent.right())); - else if(_right is Red) - return red(_right._key, _right.val(), black(_key, val(), _left, _right.left()), - black(parent._key, parent.val(), _right.right(), parent.right())); - else - return base.balanceLeft(parent); - - }
-
- internal override Node balanceRight(Node parent)
- { - if(_right is Red) - return red(_key, val(), black(parent._key, parent.val(), parent.left(), _left), _right.blacken()); - else if(_left is Red) - return red(_left._key, _left.val(), black(parent._key, parent.val(), parent.left(), _left.left()), - black(_key, val(), _left.right(), _right)); - else - return base.balanceRight(parent); - }
-
- internal override Node blacken()
- { - return new BlackBranch(_key, _left, _right); - } -} - -class RedBranchVal : RedBranch{ - readonly Object _val; - - public RedBranchVal(Object key, Object val, Node left, Node right):base(key, left, right){ - - this._val = val; - } - - override public Object val(){ - return _val; - }
-
- internal override Node blacken()
- { - return new BlackBranchVal(_key, _val, _left, _right); - } -} - -public class Seq : ASeq{
- readonly ISeq stack;
- readonly bool asc;
- readonly int cnt;
-
- Seq(ISeq stack, bool asc, int cnt) {
- this.stack = stack;
- this.asc = asc;
- this.cnt = cnt;
- }
-
- internal static Seq create(Node t, bool asc,int cnt){
- return new Seq(push(t, null, asc),asc,cnt);
- }
-
- static ISeq push(Node t, ISeq stack, bool asc){
- while(t != null)
- {
- stack = RT.cons(t,stack);
- t = asc ? t.left() : t.right();
- }
- return stack;
- }
-
- override public Object first() {
- return stack.first();
- }
-
- override public ISeq rest() {
- Node t = (Node)stack.first();
- ISeq nextstack = push(asc ? t.right() : t.left(), stack.rest(), asc);
- if(nextstack != null)
- {
- return new Seq(nextstack,asc,cnt-1);
- }
- return null;
- }
-
- public override int count()
- {
- return cnt;
- }
-}
- - -public class NodeIEnumerator : IEnumerator{ - Stack stack = new Stack(); - bool asc;
- object curr; - - internal NodeIEnumerator(Node t, bool asc){ - this.asc = asc; - push(t); - } - - void push(Node t){ - while(t != null) - { - stack.Push(t); - t = asc ? t.left() : t.right(); - } - } - - bool hasNext(){ - return !(stack.Count == 0); - } - - Object next(){ - Node t = (Node) stack.Pop(); - push(asc ? t.right() : t.left()); - return t; - } - - public void remove(){ - throw new InvalidOperationException(); - }
-
-#region IEnumerator Members
-
-public object Current
- {
- get { return curr; }
- }
-
-public bool MoveNext()
- {
- if (hasNext())
- {
- curr = next();
- return true;
- }
- return false;
- }
-
-public void Reset()
- {
- throw new Exception("The method or operation is not implemented.");
- }
-
-#endregion
- } - -class KeyIEnumerator : IEnumerator{ - NodeIEnumerator it; - - internal KeyIEnumerator(NodeIEnumerator it){ - this.it = it; - } -
-#region IEnumerator Members
-
-public object Current
-{
-get { return ((Node)it.Current)._key; }
-}
-
-public bool MoveNext()
-{
-return it.MoveNext();
-}
-
-public void Reset()
-{
- throw new Exception("The method or operation is not implemented.");
-}
-
-#endregion
-} - -class ValIEnumerator : IEnumerator{ - NodeIEnumerator it; - - internal ValIEnumerator(NodeIEnumerator it){ - this.it = it; - }
-
-#region IEnumerator Members
-
-public object Current
- {
- get { return ((Node)it.Current).val(); }
- }
-
-public bool MoveNext()
- {
- return it.MoveNext();
- }
-
-public void Reset()
- {
- throw new Exception("The method or operation is not implemented.");
- }
-
-#endregion
- } - - //*
- [STAThread] -static public void Main(String[] args){ - if(args.Length != 1)
- Console.Error.WriteLine("Usage: PersistentTree n"); - int n = Int32.Parse(args[0]); - Object[] ints = new Object[n]; - for(int i = 0; i < ints.Length; i++) - { - ints[i] = i; - } - //Collections.shuffle(Arrays.asList(ints));
- Array.Reverse(ints); - Console.WriteLine("Building set");
- //IPersistentMap set = new PersistentTree();
- //IPersistentMap set = new PersistentArrayMap();
- //IPersistentMap set = new PersistentListMap();
- IPersistentMap set = new PersistentHashtableMap(1001);
- //IPersistentMap set = new PersistentHybridMap(1001); - //for(int i = 0; i < ints.Length; i++) - // { - // Object anInt = ints[i]; - // set = set.add(anInt); - // }
- DateTime start = DateTime.Now;
- for (int i = 0; i < ints.Length; i++) - { - Object anInt = ints[i]; - set = (IPersistentMap) set.assoc(anInt, anInt); - }
-
- foreach(IMapEntry e in set) - { - if(!set.contains(e.key())) - Console.Error.WriteLine("Can't find: " + e.key()); - //else if(n < 2000) - // Console.Write(e.key().ToString() + ","); - } - - for(int i = 0; i < ints.Length/2; i++) - { - Object anInt = ints[i]; - set = set.without(anInt); - }
-
- Console.WriteLine("Time: " + (DateTime.Now - start));
- Console.Error.WriteLine("count = " + set.count());
-
- Console.WriteLine("Building Hashtable");
- Hashtable od = Hashtable.Synchronized(new Hashtable(1001));
- start = DateTime.Now;
- for (int i = 0; i < ints.Length; i++)
- {
- Object anInt = ints[i];
- od.Add(anInt, anInt);
- }
-
- foreach (DictionaryEntry e in od)
- {
- if (!od.Contains(e.Key))
- Console.Error.WriteLine("Can't find: " + e.Key);
- //else if (n < 2000)
- // Console.Write(e.key().ToString() + ",");
- }
-
- for (int i = 0; i < ints.Length / 2; i++)
- {
- Object anInt = ints[i];
- od.Remove(anInt);
- }
-
- Console.WriteLine("Time: " + (DateTime.Now - start));
- Console.Error.WriteLine("count = " + od.Count);
- -} - //*/ -} - } |