1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
/**
* 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, IPersistentList{
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;
}
public PersistentArrayList(IPersistentArray init, int initialCapacity):base(init,initialCapacity){
_count = Math.Min(init.count(),initialCapacity);
}
override public Object nth(int i) {
if(i >= _count)
throw new IndexOutOfRangeException();
return base.nth(i);
}
override public IPersistentArray assocN(int i,Object val) {
if(i >= _count)
throw new IndexOutOfRangeException();
return (PersistentArrayList) base.assocN(i, val);
}
override public int length(){
return _count;
}
override public int count(){
return _count;
}
override public IPersistentCollection cons(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.assocN(_count, val);
ret._count = _count + 1;
return ret;
}
public Object peek(){
if(_count > 0)
return nth(_count - 1);
return null;
}
public IPersistentList pop() {
if(_count == 0)
throw new InvalidOperationException();
PersistentArrayList ret = new PersistentArrayList(data.master, data.rev, data.baseline, data.history, _count - 1);
ret._meta = _meta;
return ret;
}
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){
PersistentArray ret = new PersistentArrayList(data.master, rev, baseline, history,_count);
ret._meta = _meta;
return ret;
}
override internal PersistentArray create(int size, Object defaultVal, float loadFactor) {
PersistentArray ret = new PersistentArrayList(size, defaultVal, loadFactor,_count);
ret._meta = _meta;
return ret;
}
}
}
|