diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-07-27 22:06:52 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-07-27 22:06:52 +0000 |
commit | 3224d6ff2e2e28a6e283a3106992dc0545d4e1b6 (patch) | |
tree | 70a7099e2e9c4f212dc44eb5e4e4b05ebcb978e0 /src/cli/runtime/PerisistentArrayList.cs | |
parent | 2e0a542ba24109004ec523f5897418105f1fcd8c (diff) |
first pass at ArrayList
Diffstat (limited to 'src/cli/runtime/PerisistentArrayList.cs')
-rw-r--r-- | src/cli/runtime/PerisistentArrayList.cs | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/cli/runtime/PerisistentArrayList.cs b/src/cli/runtime/PerisistentArrayList.cs new file mode 100644 index 00000000..5fe1bc11 --- /dev/null +++ b/src/cli/runtime/PerisistentArrayList.cs @@ -0,0 +1,105 @@ +/**
+ * 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.
+ **/
+
+using System;
+using System.Threading;
+using System.Collections;
+
+namespace clojure.lang
+{
+public class PersistentArrayList : PersistentArray{
+
+int _count;
+
+public PersistentArrayList(int initialCapacity) : base(initialCapacity){
+
+ _count = 0;
+}
+
+PersistentArrayList(Master master,int rev,int baseline, BitArray history, int count):base(master,rev,baseline,history){
+
+ this._count = count;
+}
+
+PersistentArrayList(int size, Object defaultVal, float loadFactor, int count):base(size, defaultVal, loadFactor) {
+
+ this._count = count;
+}
+
+override public Object get(int i) {
+ if(i >= _count)
+ throw new IndexOutOfRangeException();
+
+ return base.get(i);
+}
+
+override public IArray set(int i,Object val) {
+ if(i >= _count)
+ throw new IndexOutOfRangeException();
+
+ return (PersistentArrayList) base.set(i, val);
+}
+
+override public int length(){
+ return _count;
+}
+
+public int count(){
+ return _count;
+}
+
+public int capacity(){
+ return data.master.array.Length;
+}
+
+public PersistentArrayList add(Object val) {
+ if(_count == data.master.array.Length) //full
+ {
+ lock(data.master){
+ if(_count == data.master.array.Length) //still full
+ grow();
+ }
+ }
+ PersistentArrayList ret = (PersistentArrayList) base.set(_count, val);
+ ret._count = _count + 1;
+ return ret;
+}
+
+public PersistentArrayList remove() {
+ if(_count == 0)
+ throw new InvalidOperationException();
+ return new PersistentArrayList(data.master, data.rev, data.baseline, data.history, _count - 1);
+}
+
+
+private void grow() {
+ //must be called inside lock of master
+ if(data.master.next != null) //this master has been trimmed, but this rev is not yet propagated
+ trim();
+
+ Master newMaster = new Master(data.master.array.Length * 2, data.master.defaultVal, data.master.loadFactor);
+ newMaster.rev = data.master.rev;
+ newMaster.load = data.master.load;
+ newMaster.basis = data.master.basis;
+ for(int i=0;i<data.master.array.Length;i++)
+ newMaster.array[i] = data.master.array[i];
+ data.master = newMaster;
+}
+
+override internal PersistentArray create(Master master,int rev,int baseline, BitArray history){
+ return new PersistentArrayList(data.master, rev, baseline, history,_count);
+}
+
+override internal PersistentArray create(int size, Object defaultVal, float loadFactor) {
+ return new PersistentArrayList(size, defaultVal, loadFactor,_count);
+}
+
+}
+}
|