From 279dd21d4b919496c8fb54c3135f2b82cc36f5c2 Mon Sep 17 00:00:00 2001 From: Rich Hickey Date: Sat, 5 Aug 2006 16:44:23 +0000 Subject: added cons to IPersistentCollection --- src/cli/runtime/APersistentMap.cs | 6 +++++ src/cli/runtime/AnArray.cs | 7 ++++++ src/cli/runtime/Cons.cs | 2 +- src/cli/runtime/IPersistentCollection.cs | 1 + src/cli/runtime/PerisistentArrayList.cs | 10 ++++---- src/cli/runtime/PersistentArray.cs | 13 +++++++++- src/cli/runtime/PersistentArrayMap.cs | 26 ++++++++------------ src/cli/runtime/PersistentHashtableMap.cs | 29 +++++++++------------- src/cli/runtime/PersistentListMap.cs | 40 +++++++++---------------------- src/cli/runtime/PersistentTreeMap.cs | 31 ++++++++---------------- 10 files changed, 74 insertions(+), 91 deletions(-) (limited to 'src/cli/runtime') diff --git a/src/cli/runtime/APersistentMap.cs b/src/cli/runtime/APersistentMap.cs index 4e39acb7..99ca0ea4 100644 --- a/src/cli/runtime/APersistentMap.cs +++ b/src/cli/runtime/APersistentMap.cs @@ -61,6 +61,12 @@ public abstract class APersistentMap : Obj, IPersistentMap{ abstract public ISeq seq(); + public IPersistentCollection cons(Object o) + { + IMapEntry e = (IMapEntry)o; + return (IPersistentCollection)assoc(e.key(), e.val()); + } + #endregion } diff --git a/src/cli/runtime/AnArray.cs b/src/cli/runtime/AnArray.cs index b586d6f5..b02f7c65 100644 --- a/src/cli/runtime/AnArray.cs +++ b/src/cli/runtime/AnArray.cs @@ -15,6 +15,13 @@ namespace clojure.lang { public abstract class AnArray : Obj, IArray { +public virtual IPersistentCollection cons(Object o) { + PersistentArrayList ret = new PersistentArrayList(this, this.count() + 10); + ret = (PersistentArrayList)ret.cons(o); + ret._meta = _meta; + return ret; +} + public override Obj withMeta(IPersistentMap meta) { if(_meta == meta) diff --git a/src/cli/runtime/Cons.cs b/src/cli/runtime/Cons.cs index cd5291db..f4361e07 100644 --- a/src/cli/runtime/Cons.cs +++ b/src/cli/runtime/Cons.cs @@ -15,7 +15,7 @@ using System; namespace clojure.lang { -public class Cons : ISeq, IPersistentCollection +public class Cons : ISeq { private readonly Object _first; diff --git a/src/cli/runtime/IPersistentCollection.cs b/src/cli/runtime/IPersistentCollection.cs index 6746240b..929a419e 100644 --- a/src/cli/runtime/IPersistentCollection.cs +++ b/src/cli/runtime/IPersistentCollection.cs @@ -20,5 +20,6 @@ namespace clojure.lang ISeq seq(); + IPersistentCollection cons(Object o); } } diff --git a/src/cli/runtime/PerisistentArrayList.cs b/src/cli/runtime/PerisistentArrayList.cs index 07e65f5e..6753f4f1 100644 --- a/src/cli/runtime/PerisistentArrayList.cs +++ b/src/cli/runtime/PerisistentArrayList.cs @@ -33,6 +33,10 @@ PersistentArrayList(int size, Object defaultVal, float loadFactor, int count):ba this._count = count; } +public PersistentArrayList(IArray init, int initialCapacity):base(init,initialCapacity){ + _count = Math.Min(init.count(),initialCapacity); +} + override public Object nth(int i) { if(i >= _count) throw new IndexOutOfRangeException(); @@ -55,11 +59,7 @@ override public int count(){ return _count; } -public int capacity(){ - return data.master.array.Length; -} - -public PersistentArrayList add(Object val) { +override public IPersistentCollection cons(Object val) { if(_count == data.master.array.Length) //full { lock(data.master){ diff --git a/src/cli/runtime/PersistentArray.cs b/src/cli/runtime/PersistentArray.cs index 3235eb44..f1e3fef5 100644 --- a/src/cli/runtime/PersistentArray.cs +++ b/src/cli/runtime/PersistentArray.cs @@ -253,6 +253,17 @@ public PersistentArray(IArray init) :this(init.length()) { data.master.load = load; } +public PersistentArray(IArray init, int size) :this(size) { + int load = 0; + for(int i=0;i < init.length() && i < size;i++) + { + data.master.array[i] = new Entry(0,init.nth(i)); + ++load; + } + + data.master.load = load; +} + override public int count(){ return data.master.array.Length; } @@ -500,7 +511,7 @@ static public void Main(String[] args){ { v.Add(0); //p = p.set(i, 0); - p = ((PersistentArrayList)p).add(0); + p = (IArray)((PersistentArrayList)p).cons(0); } Random rand; diff --git a/src/cli/runtime/PersistentArrayMap.cs b/src/cli/runtime/PersistentArrayMap.cs index 6c848685..e758c547 100644 --- a/src/cli/runtime/PersistentArrayMap.cs +++ b/src/cli/runtime/PersistentArrayMap.cs @@ -25,7 +25,7 @@ namespace clojure.lang * null keys and values are ok, but you won't be able to distinguish a null value via get - use contains/find */ -public class PersistentArrayMap : Obj, IPersistentMap, IPersistentCollection { +public class PersistentArrayMap : APersistentMap { internal readonly Object[] array; @@ -49,12 +49,6 @@ virtual internal IPersistentMap createHT(Object[] init){ return ret; } -public override Obj withMeta(IPersistentMap meta) - { - Obj ret = (Obj)MemberwiseClone(); - ret._meta = meta; - return ret; - } /** * This ctor captures/aliases the passed array, so do not modify later * @param init {key1,val1,key2,val2,...} @@ -63,22 +57,22 @@ public PersistentArrayMap(params Object[] init){ this.array = init; } -public int count() { +override public int count() { return array.Length/2; } -public bool contains(Object key){ +override public bool contains(Object key){ return indexOf(key) >= 0; } -public IMapEntry find(Object key) { +override public IMapEntry find(Object key) { int i = indexOf(key); if(i >= 0) return new Iter(array,i); return null; } -public IPersistentMap assocEx(Object key, Object val) { +override public IPersistentMap assocEx(Object key, Object val) { int i = indexOf(key); Object[] newArray; if(i >= 0) @@ -98,7 +92,7 @@ public IPersistentMap assocEx(Object key, Object val) { return create(newArray); } -public Associative assoc(Object key, Object val) { +override public Associative assoc(Object key, Object val) { int i = indexOf(key); Object[] newArray; if(i >= 0) //already have key, same-sized replacement @@ -121,7 +115,7 @@ public Associative assoc(Object key, Object val) { return create(newArray); } -public IPersistentMap without(Object key) { +override public IPersistentMap without(Object key) { int i = indexOf(key); if(i >= 0) //have key, will remove { @@ -152,7 +146,7 @@ virtual public IPersistentMap empty() { return ret; } -public Object get(Object key) { +override public Object get(Object key) { int i = indexOf(key); if(i >= 0) return array[i + 1]; @@ -178,11 +172,11 @@ internal virtual bool equalKey(Object k1,Object k2){ return k1.Equals(k2); } -public IEnumerator GetEnumerator() { +override public IEnumerator GetEnumerator() { return new Iter(array); } -public ISeq seq() { +override public ISeq seq() { if(array.Length > 0) return new Seq(array,0); return null; diff --git a/src/cli/runtime/PersistentHashtableMap.cs b/src/cli/runtime/PersistentHashtableMap.cs index 0bf8930b..52dea0ad 100644 --- a/src/cli/runtime/PersistentHashtableMap.cs +++ b/src/cli/runtime/PersistentHashtableMap.cs @@ -16,7 +16,7 @@ namespace clojure.lang { -public class PersistentHashtableMap : Obj, IPersistentMap { +public class PersistentHashtableMap : APersistentMap { static readonly float FILL_FACTOR = 0.75f; @@ -55,14 +55,7 @@ internal PersistentHashtableMap(int count,PersistentArray array,int growAt) { this._count = count; this.array = array; this.growAtCount = growAt; -} - -public override Obj withMeta(IPersistentMap meta) - { - Obj ret = (Obj)MemberwiseClone(); - ret._meta = meta; - return ret; - } +} int calcPrimeCapacity(int capacity) { // No .Net equivalent @@ -73,23 +66,23 @@ int calcPrimeCapacity(int capacity) { return ret; } -public int count() { +override public int count() { return _count; } -public bool contains(Object key) { +override public bool contains(Object key) { IPersistentMap entries = entriesFor(key); return entries != null && entries.contains(key); } -public IMapEntry find(Object key) { +override public IMapEntry find(Object key) { IPersistentMap entries = entriesFor(key); if(entries != null) return entries.find(key); return null; } -public IPersistentMap assocEx(Object key, Object val) { +override public IPersistentMap assocEx(Object key, Object val) { if(_count > growAtCount) return grow().assocEx(key, val); int i = bucketFor(key,array); @@ -98,7 +91,7 @@ public IPersistentMap assocEx(Object key, Object val) { return create(_count + incr, newArray, growAtCount); } -public Associative assoc(Object key, Object val) { +override public Associative assoc(Object key, Object val) { if(_count > growAtCount) return grow().assoc(key, val); int i = bucketFor(key,array); @@ -139,7 +132,7 @@ PersistentArray doAdd(int i,Object key,Object val,PersistentArray array) { return (PersistentArray)array.assocN(i, newEntries); } -public IPersistentMap without(Object key) { +override public IPersistentMap without(Object key) { int i = bucketFor(key,array); IPersistentMap entries = (IPersistentMap) array.nth(i); if (entries != null) @@ -152,7 +145,7 @@ public IPersistentMap without(Object key) { return this; } -public Object get(Object key) { +override public Object get(Object key) { IPersistentMap entries = entriesFor(key); if(entries != null) return entries.get(key); @@ -172,11 +165,11 @@ IPersistentMap grow(){ return create(_count,newArray); } -public virtual IEnumerator GetEnumerator() { +override public IEnumerator GetEnumerator() { return new Iter(array); } -public ISeq seq() { +override public ISeq seq() { return Seq.create(array); } diff --git a/src/cli/runtime/PersistentListMap.cs b/src/cli/runtime/PersistentListMap.cs index 714dfe38..f0c55492 100644 --- a/src/cli/runtime/PersistentListMap.cs +++ b/src/cli/runtime/PersistentListMap.cs @@ -27,7 +27,7 @@ namespace clojure.lang * * null keys and values are ok, but you won't be able to distinguish a null value via get - use contains/find */ -public class PersistentListMap : Obj, IPersistentMap, IMapEntry, ISeq, IPersistentCollection +public class PersistentListMap : APersistentMap, IMapEntry, ISeq { static public PersistentListMap EMPTY = new PersistentListMap(); @@ -35,13 +35,7 @@ static public PersistentListMap EMPTY = new PersistentListMap(); static public PersistentListMap create(Object key, Object val){ return new Tail(key, val,null); } - -public override Obj withMeta(IPersistentMap meta) - { - Obj ret = (Obj)MemberwiseClone(); - ret._meta = meta; - return ret; - } + public virtual Object key(){ return null; @@ -55,38 +49,34 @@ internal virtual PersistentListMap next(){ return this; } -public virtual int count(){ +override public int count(){ return 0; } -public virtual bool contains(Object key){ +override public bool contains(Object key){ return false; } -public virtual IMapEntry find(Object key){ +override public IMapEntry find(Object key){ return null; } -public virtual IPersistentMap assocEx(Object key, Object val){ +override public IPersistentMap assocEx(Object key, Object val){ return (IPersistentMap)assoc(key, val); } -public virtual Associative assoc(Object key, Object val){ +override public Associative assoc(Object key, Object val){ return new Tail(key, val, _meta); } -public virtual IPersistentMap without(Object key){ +override public IPersistentMap without(Object key){ return this; } -public virtual Object get(Object key){ +override public Object get(Object key){ return null; } -public virtual int capacity(){ - return 0; -} - virtual public Object first() { return null; @@ -97,7 +87,7 @@ virtual public ISeq rest() return null; } -virtual public ISeq seq() +override public ISeq seq() { return null; } @@ -136,7 +126,7 @@ public void Reset() #endregion } -public IEnumerator GetEnumerator(){ +override public IEnumerator GetEnumerator(){ return new Iter(this); } @@ -166,11 +156,6 @@ internal class Tail : PersistentListMap { return null; } - override public int capacity() - { - return 1; - } - override public Object key() { return _key; @@ -322,9 +307,6 @@ internal class Link : PersistentListMap { return null; } - override public int capacity(){ - return count(); - } override public Object first() { diff --git a/src/cli/runtime/PersistentTreeMap.cs b/src/cli/runtime/PersistentTreeMap.cs index b87e3754..f43555ee 100644 --- a/src/cli/runtime/PersistentTreeMap.cs +++ b/src/cli/runtime/PersistentTreeMap.cs @@ -25,7 +25,7 @@ namespace clojure.lang * See Okasaki, Kahrs, Larsen et al */ -public class PersistentTreeMap : Obj, IPersistentMap, IPersistentCollection{ +public class PersistentTreeMap : APersistentMap{ public readonly IComparer comp; public readonly Node tree; @@ -40,26 +40,15 @@ public PersistentTreeMap(IComparer comp){ _count = 0; } -public override Obj withMeta(IPersistentMap meta) - { - Obj ret = (Obj)MemberwiseClone(); - ret._meta = meta; - return ret; - } - -public int count(){ - return _count; - } - -public int capacity(){ +override public int count(){ return _count; } -public bool contains(Object key){ +override public bool contains(Object key){ return find(key) != null; } -public IPersistentMap assocEx(Object key,Object val){ +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 @@ -69,7 +58,7 @@ public IPersistentMap assocEx(Object key,Object val){ return new PersistentTreeMap(comp, t.blacken(), _count + 1, _meta); } -public Associative assoc(Object key, Object val){ +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 @@ -83,7 +72,7 @@ public Associative assoc(Object key, Object val){ } -public IPersistentMap without(Object key){ +override public IPersistentMap without(Object key){ Box found = new Box(null); Node t = remove(tree, key, found); if(t == null) @@ -98,7 +87,7 @@ public IPersistentMap without(Object key){ return new PersistentTreeMap(comp, t.blacken(), _count - 1, _meta); } -public ISeq seq() { +override public ISeq seq() { if(_count > 0) return Seq.create(tree, true); return null; @@ -110,7 +99,7 @@ public ISeq rseq() { return null; } -public IEnumerator GetEnumerator(){ +override public IEnumerator GetEnumerator(){ return new NodeIEnumerator(tree, true); } @@ -174,12 +163,12 @@ int depth(Node t){ return 1 + Math.Max(depth(t.left()), depth(t.right())); } -public Object get(Object key){ +override public Object get(Object key){ Node n = (Node)find(key); return (n != null) ? n.val() : null; } -public IMapEntry find(Object key){ +override public IMapEntry find(Object key){ Node t = tree; while(t != null) { -- cgit v1.2.3-70-g09d2