summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cli/runtime/PersistentArray.cs66
-rw-r--r--src/org/clojure/runtime/PersistentArray.java33
2 files changed, 72 insertions, 27 deletions
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();
}