From 526f5470cfa19f27039e287434eb6d26a7671bdd Mon Sep 17 00:00:00 2001 From: Rich Hickey Date: Mon, 5 Jun 2006 17:25:36 +0000 Subject: distinguished inner/leaf entries --- src/cli/runtime/PersistentArray.cs | 66 +++++++++++++++++++--------- src/org/clojure/runtime/PersistentArray.java | 33 +++++++++++--- 2 files changed, 72 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/cli/runtime/PersistentArray.cs b/src/cli/runtime/PersistentArray.cs index f1b9b0ed..164afc2c 100644 --- a/src/cli/runtime/PersistentArray.cs +++ b/src/cli/runtime/PersistentArray.cs @@ -73,30 +73,54 @@ internal class Master{ } } - internal class Entry +internal class Entry + { + internal readonly int rev; + internal readonly Object val; + + internal Entry(int rev, Object val) { - internal readonly int rev; - internal readonly Object val; - internal readonly Entry rest; + this.rev = rev; + this.val = val; + } - internal Entry(int rev, Object val, Entry rest) - { - this.rev = rev; - this.val = val; - this.rest = rest; - } -} + internal virtual Entry rest() + { + return null; + } - internal class ValIter : IEnumerator + internal static Entry create(int rev, Object val, Entry rest) { - internal PersistentArray p; - internal int i; + if (rest == null) + return new Entry(rev, val); + return new EntryLink(rev, val, rest); + } + } - internal ValIter(PersistentArray p) - { - this.p = p; - this.i = -1; +internal class EntryLink : Entry + { + internal readonly Entry _rest; + + internal EntryLink(int rev, Object val, Entry rest) :base(rev,val) + { + this._rest = rest; + } + + override internal Entry rest(){ + return _rest; } +} + +internal class ValIter : IEnumerator + { + internal PersistentArray p; + internal int i; + + internal ValIter(PersistentArray p) + { + this.p = p; + this.i = -1; +} #region IEnumerator Members @@ -174,7 +198,7 @@ public PersistentArray resize(int newLength) Entry e = getEntry(i); if (e != null) { - ret.master.array[i] = new Entry(0, e.val, null); + ret.master.array[i] = Entry.create(0, e.val, null); ++ret.master.load; } } @@ -191,7 +215,7 @@ public PersistentArray isolate() } Entry getEntry(int i){ - for(Entry e = (Entry) master.array[i];e != null;e = e.rest) + for(Entry e = (Entry) master.array[i];e != null;e = e.rest()) { if(e.rev <= rev) { @@ -216,7 +240,7 @@ void doSet(int i, Object val){ lock(master.array) { oldEntry = (Entry) master.array[i]; - newEntry = new Entry(rev, val, oldEntry); + newEntry = Entry.create(rev, val, oldEntry); master.array[i] = newEntry; } Interlocked.Increment(ref master.load); diff --git a/src/org/clojure/runtime/PersistentArray.java b/src/org/clojure/runtime/PersistentArray.java index 30fd2636..9a0acc6d 100644 --- a/src/org/clojure/runtime/PersistentArray.java +++ b/src/org/clojure/runtime/PersistentArray.java @@ -74,13 +74,34 @@ static class Master{ static class Entry{ final int rev; final Object val; - final Entry rest; - Entry(int rev,Object val,Entry rest){ + Entry(int rev,Object val){ this.rev = rev; this.val = val; - this.rest = rest; } + + Entry rest(){ + return null; + } + + static Entry create(int rev,Object val,Entry rest){ + if(rest == null) + return new Entry(rev,val); + return new EntryLink(rev, val, rest); + } +} + +static class EntryLink extends Entry{ + final Entry _rest; + + EntryLink(int rev,Object val,Entry rest){ + super(rev,val); + this._rest = rest; + } + + Entry rest(){ + return _rest; + } } static class ValIter implements Iterator{ @@ -157,7 +178,7 @@ public PersistentArray resize(int newLength) { Entry e = getEntry(i); if(e != null) { - ret.master.array.set(i,new Entry(0,e.val, null)); + ret.master.array.set(i,Entry.create(0,e.val, null)); ++load; } } @@ -180,7 +201,7 @@ public PersistentArray isolate() { } Entry getEntry(int i){ - for(Entry e = (Entry) master.array.get(i);e != null;e = e.rest) + for(Entry e = (Entry) master.array.get(i);e != null;e = e.rest()) { if(e.rev <= rev) { @@ -205,7 +226,7 @@ void doSet(int i, Object val){ do { oldEntry = (Entry) master.array.get(i); - newEntry = new Entry(rev, val, oldEntry); + newEntry = Entry.create(rev, val, oldEntry); } while(!master.array.compareAndSet(i, oldEntry, newEntry)); master.load.incrementAndGet(); } -- cgit v1.2.3-70-g09d2