From 093ea7b07aea48b9f4b8aac3a8beddfe2e1226f7 Mon Sep 17 00:00:00 2001 From: Rich Hickey Date: Mon, 19 Jun 2006 20:43:04 +0000 Subject: added generational trimming --- src/cli/runtime/PersistentArray.cs | 180 ++++++++++++++++++++++++++++--------- 1 file changed, 139 insertions(+), 41 deletions(-) (limited to 'src/cli/runtime') diff --git a/src/cli/runtime/PersistentArray.cs b/src/cli/runtime/PersistentArray.cs index 2c0e2191..a9d81e5d 100644 --- a/src/cli/runtime/PersistentArray.cs +++ b/src/cli/runtime/PersistentArray.cs @@ -69,7 +69,9 @@ internal class Master{ internal int load; internal readonly int maxLoad; internal readonly float loadFactor; - + internal readonly int[] basis; + internal volatile Master next; + internal Master(int size,Object defaultVal, float loadFactor){ this.array = new Entry[size]; this.defaultVal = defaultVal; @@ -78,7 +80,19 @@ internal class Master{ this.maxLoad = (int)(size * loadFactor); this.loadFactor = loadFactor; } -} + internal Master(Master parent) + { + this.array = new Entry[parent.array.Length]; + this.defaultVal = parent.defaultVal; + this.rev = 0; + this.load = 0; + this.maxLoad = parent.maxLoad; + this.loadFactor = parent.loadFactor; + this.next = null; + + this.basis = new int[parent.array.Length]; + } + } internal class Entry { @@ -179,10 +193,21 @@ public void Reset() #endregion } +internal class Data{ internal readonly Master master; internal readonly int rev; internal readonly int baseline; internal readonly BitArray history; + public Data(Master master, int rev, int baseline, BitArray history) + { + this.master = master; + this.rev = rev; + this.baseline = baseline; + this.history = history; + } + } + +volatile Data data; public PersistentArray(int size) : this(size, (Object)null) @@ -195,51 +220,45 @@ public PersistentArray(int size, Object defaultVal) } public PersistentArray(int size, Object defaultVal, float loadFactor){ - this.master = new Master(size, defaultVal, loadFactor); - this.rev = 0; - this.baseline = 0; - this.history = null; + this.data = new Data(new Master(size, defaultVal, loadFactor), 0, 0, null); } internal PersistentArray(Master master, int rev, int baseline, BitArray history) { - this.master = master; - this.rev = rev; - this.baseline = baseline; - this.history = history; + this.data = new Data(master, rev, baseline, history); } public PersistentArray(int size, ISeq seq) : this(size){ int load = 0; for(int i=0;seq != null && i < size;i++, seq=seq.rest()) { - master.array[i] = new Entry(0,seq.first()); + data.master.array[i] = new Entry(0,seq.first()); ++load; } - master.load = load; + data.master.load = load; } public PersistentArray(IArray init) :this(init.length()) { int load = 0; for(int i=0;i < init.length();i++) { - master.array[i] = new Entry(0,init.get(i)); + data.master.array[i] = new Entry(0, init.get(i)); ++load; } - master.load = load; + data.master.load = load; } public int length(){ - return master.array.Length; +return data.master.array.Length; } public Object get(int i){ Entry e = getEntry(i); if(e != null) return e.val; - return master.defaultVal; + return data.master.defaultVal; } public bool has(int i){ @@ -248,35 +267,50 @@ public bool has(int i){ public PersistentArray resize(int newLength) { - PersistentArray ret = new PersistentArray(newLength, master.defaultVal, master.loadFactor); + PersistentArray ret = new PersistentArray(newLength, data.master.defaultVal, data.master.loadFactor); for (int i = 0; i < Math.Min(length(), newLength); i++) { Entry e = getEntry(i); if (e != null) { - ret.master.array[i] = Entry.create(0, e.val, null); - ++ret.master.load; + ret.data.master.array[i] = Entry.create(0, e.val, null); + ++ret.data.master.load; } } return ret; } public int load(){ - return master.load; +return data.master.load; } -public PersistentArray isolate() +public void isolate() { - return resize(length()); + lock(data.master) + { + Master nextMaster = new Master(data.master); + int load = 0; + for(int i=0;i= baseline - || (history != null && e.rev < history.Length && history.Get(e.rev))) + if (e.rev >= data.baseline + || (data.history != null && e.rev < data.history.Length && data.history.Get(e.rev))) return e; } } @@ -284,15 +318,77 @@ Entry getEntry(int i){ } public IArray set(int i,Object val) { - if(master.load >= master.maxLoad) - return isolate().set(i,val); - lock(master){ +//if (data.master.load >= data.master.maxLoad) +// { +// isolate(); +// //set(i,val); +// } + lock (data.master) + { + if (data.master.load >= data.master.maxLoad) + //isolate(); + trim(); PersistentArray ret = getSetArray(); ret.doSet(i, val); return ret; } } +private void trim(){ + //must be called inside lock of master + if (data.master.next == null) //this master has never been trimmed + { + Master nextMaster = new Master(data.master); + int load = 0; + for(int i=0;i= length()/2 || nextMaster.load + diff > nextMaster.maxLoad) + isolate(); + else + { + Data nextData; + lock(nextMaster){ + int rev = ++nextMaster.rev; + for(int i=0;i