Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(607)

Side by Side Diff: lib/growable_array.dart

Issue 10012042: Wire GrowableArray to use the internal VM object. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class GrowableObjectArray<T> implements List<T> { 5 class GrowableObjectArray<T> implements List<T> {
6 ObjectArray<T> backingArray;
7
8 factory GrowableObjectArray._uninstantiable() { 6 factory GrowableObjectArray._uninstantiable() {
9 throw const UnsupportedOperationException( 7 throw const UnsupportedOperationException(
10 "GrowableObjectArray can only be allocated by the VM"); 8 "GrowableObjectArray can only be allocated by the VM");
11 } 9 }
12 10
13 void copyFrom(List<Object> src, int srcStart, int dstStart, int count) { 11 void copyFrom(List<Object> src, int srcStart, int dstStart, int count) {
14 Arrays.copy(src, srcStart, this, dstStart, count); 12 Arrays.copy(src, srcStart, this, dstStart, count);
15 } 13 }
16 14
17 void setRange(int start, int length, List<T> from, [int startFrom = 0]) { 15 void setRange(int start, int length, List<T> from, [int startFrom = 0]) {
18 if (length < 0) { 16 if (length < 0) {
19 throw new IllegalArgumentException("negative length $length"); 17 throw new IllegalArgumentException("negative length $length");
20 } 18 }
21 Arrays.copy(from, startFrom, this, start, length); 19 Arrays.copy(from, startFrom, this, start, length);
22 } 20 }
23 21
24 void removeRange(int start, int length) { 22 void removeRange(int start, int length) {
25 if (length == 0) { 23 if (length == 0) {
26 return; 24 return;
27 } 25 }
28 if (length < 0) { 26 if (length < 0) {
29 throw new IllegalArgumentException("negative length $length"); 27 throw new IllegalArgumentException("negative length $length");
30 } 28 }
31 if (start < 0 || start >= this.length) { 29 if (start < 0 || start >= this.length) {
32 throw new IndexOutOfRangeException(start); 30 throw new IndexOutOfRangeException(start);
33 } 31 }
34 if (start + length > this.length) { 32 if (start + length > this.length) {
35 throw new IndexOutOfRangeException(start + length); 33 throw new IndexOutOfRangeException(start + length);
36 } 34 }
37 Arrays.copy(backingArray, 35 Arrays.copy(this,
38 start + length, 36 start + length,
39 backingArray, 37 this,
40 start, 38 start,
41 this.length - length - start); 39 this.length - length - start);
42 this.length = this.length - length; 40 this.length = this.length - length;
43 } 41 }
44 42
45 void insertRange(int start, int length, [T initialValue = null]) { 43 void insertRange(int start, int length, [T initialValue = null]) {
46 if (length == 0) { 44 if (length == 0) {
47 return; 45 return;
48 } 46 }
49 if (length < 0) { 47 if ((length < 0) || (length is! int)) {
50 throw new IllegalArgumentException("negative length $length"); 48 throw new IllegalArgumentException("invalid length specified");
srdjan 2012/04/06 21:19:51 Add $length to message?
siva 2012/04/09 20:57:24 Done.
51 } 49 }
52 if (start < 0 || start > this.length) { 50 if (start < 0 || start > this.length) {
53 throw new IndexOutOfRangeException(start); 51 throw new IndexOutOfRangeException(start);
54 } 52 }
55 if (this.length + length > backingArray.length) { 53 var old_length = this.length;
56 grow(backingArray.length + length); 54 this.length = old_length + length; // Will expand if needed.
57 } 55 Arrays.copy(this,
58 Arrays.copy(backingArray,
59 start, 56 start,
60 backingArray, 57 this,
61 start + length, 58 start + length,
62 this.length - start); 59 old_length - start);
63 if (initialValue !== null) { 60 if (initialValue !== null) {
64 for (int i = start; i < start + length; i++) { 61 for (int i = start; i < start + length; i++) {
65 backingArray[i] = initialValue; 62 this[i] = initialValue;
66 } 63 }
67 } 64 }
68 this.length = this.length + length;
69 } 65 }
70 66
71 List<T> getRange(int start, int length) { 67 List<T> getRange(int start, int length) {
72 if (length == 0) return []; 68 if (length == 0) return [];
73 Arrays.rangeCheck(this, start, length); 69 Arrays.rangeCheck(this, start, length);
74 List list = new List<T>(); 70 List list = new List<T>();
75 list.length = length; 71 list.length = length;
76 Arrays.copy(this, start, list, 0, length); 72 Arrays.copy(this, start, list, 0, length);
77 return list; 73 return list;
78 } 74 }
79 75
80 // The length of this growable array. It is always less than or equal to the 76 factory GrowableObjectArray() {
81 // length of the backing array, which itself is always greater than 0, so that 77 var data = new ObjectArray<T>(4);
82 // grow() does not have to check for a zero length backing array before 78 return new GrowableObjectArray<T>.fromObjectArray(data);
83 // doubling its size. 79 }
84 int _length;
85 80
86 GrowableObjectArray() 81 factory GrowableObjectArray.withCapacity(int capacity) {
87 : _length = 0, backingArray = new ObjectArray<T>(4) {} 82 var data = new ObjectArray<T>(capacity);
88 83 return new GrowableObjectArray<T>.fromObjectArray(data);
89 GrowableObjectArray.withCapacity(int capacity) {
90 _length = 0;
91 if (capacity <= 0) {
92 capacity = 4;
93 }
94 backingArray = new ObjectArray<T>(capacity);
95 } 84 }
96 85
97 factory GrowableObjectArray.from(Collection<T> other) { 86 factory GrowableObjectArray.from(Collection<T> other) {
98 List<T> result = new GrowableObjectArray<T>(); 87 List<T> result = new GrowableObjectArray<T>();
99 result.addAll(other); 88 result.addAll(other);
100 return result; 89 return result;
101 } 90 }
102 91
103 int get length() { 92 factory GrowableObjectArray.fromObjectArray(ObjectArray<T> data)
104 return _length; 93 native "GrowableObjectArray_allocate";
94
95 int get length() native "GrowableObjectArray_getLength";
96
97 int get capacity() native "GrowableObjectArray_getCapacity";
98
99 void set length(int new_length) {
100 if (new_length > capacity) {
101 _grow(new_length);
102 } else {
103 for (int i = new_length; i < length; i++) {
104 this[i] = null;
105 }
106 }
107 _setLength(new_length);
105 } 108 }
106 109
107 void set length(int new_length) { 110 void _setLength(int new_length) native "GrowableObjectArray_setLength";
108 if (new_length > backingArray.length) { 111
109 grow(new_length); 112 void set data(ObjectArray<T> array) native "GrowableObjectArray_setData";
110 } else { 113
111 for (int i = new_length; i < _length; i++) { 114 T operator [](int index) native "GrowableObjectArray_getIndexed";
112 backingArray[i] = null; 115
113 } 116 void operator []=(int index, T value) native "GrowableObjectArray_setIndexed";
117
118 // The length of this growable array. It is always less than or equal to the
119 // length of the object array, which itself is always greater than 0, so that
120 // grow() does not have to check for a zero length object array before
121 // doubling its size.
122 void add(T value) {
123 var len = length;
124 if (len == capacity) {
125 _grow(len * 2);
114 } 126 }
115 _length = new_length; 127 _setLength(len + 1);
116 } 128 this[len] = value;
117
118 T operator [](int index) {
119 if (index is !int) {
120 throw new IllegalArgumentException("[] with $index");
121 }
122 if (index >= _length) {
123 throw new IndexOutOfRangeException(index);
124 }
125 return backingArray[index];
126 }
127
128 void operator []=(int index, T value) {
129 if (index is !int) {
130 throw new IllegalArgumentException("[]= with $index");
131 }
132 if (index >= _length) {
133 throw new IndexOutOfRangeException(index);
134 }
135 backingArray[index] = value;
136 }
137
138 void grow(int capacity) {
139 ObjectArray<T> newArray = new ObjectArray<T>(capacity);
140 int length = backingArray.length;
141 for (int i = 0; i < length; i++) {
142 newArray[i] = backingArray[i];
143 }
144 backingArray = newArray;
145 }
146
147 void add(T value) {
148 if (_length == backingArray.length) {
149 grow(_length * 2);
150 }
151 backingArray[_length] = value;
152 ++_length;
153 } 129 }
154 130
155 void addLast(T element) { 131 void addLast(T element) {
156 add(element); 132 add(element);
157 } 133 }
158 134
159 void addAll(Collection<T> collection) { 135 void addAll(Collection<T> collection) {
160 for (T elem in collection) { 136 for (T elem in collection) {
161 add(elem); 137 add(elem);
162 } 138 }
163 } 139 }
164 140
165 T removeLast() { 141 T removeLast() {
166 if (_length == 0) { 142 var len = length - 1;
143 if (len < 0) {
167 throw new IndexOutOfRangeException(-1); 144 throw new IndexOutOfRangeException(-1);
168 } 145 }
169 _length--; 146 var elem = this[len];
170 return backingArray[_length]; 147 this[len] = null;
148 _setLength(len);
149 return elem;
171 } 150 }
172 151
173 T last() { 152 T last() {
174 if (_length === 0) { 153 if (length === 0) {
175 throw new IndexOutOfRangeException(-1); 154 throw new IndexOutOfRangeException(-1);
176 } 155 }
177 return backingArray[_length - 1]; 156 return this[length - 1];
178 } 157 }
179 158
180 int indexOf(T element, [int start = 0]) { 159 int indexOf(T element, [int start = 0]) {
181 return Arrays.indexOf(backingArray, element, start, _length); 160 return Arrays.indexOf(this, element, start, length);
182 } 161 }
183 162
184 int lastIndexOf(T element, [int start = null]) { 163 int lastIndexOf(T element, [int start = null]) {
185 if (start === null) start = length - 1; 164 if (start === null) start = length - 1;
186 return Arrays.lastIndexOf(backingArray, element, start); 165 return Arrays.lastIndexOf(this, element, start);
166 }
167
168 void _grow(int new_length) {
169 var new_data = new ObjectArray<T>(new_length);
170 for (int i = 0; i < length; i++) {
171 new_data[i] = this[i];
172 }
173 data = new_data;
187 } 174 }
188 175
189 /** 176 /**
190 * Collection interface. 177 * Collection interface.
191 */ 178 */
192 179
193 void forEach(f(T element)) { 180 void forEach(f(T element)) {
194 // TODO(srdjan): Use Collections.forEach(this, f); 181 // TODO(srdjan): Use Collections.forEach(this, f);
195 // Using backingArray directly improves DeltaBlue performance by 25%. 182 // Accessing the list directly improves DeltaBlue performance by 25%.
196 for (int i = 0; i < _length; i++) { 183 for (int i = 0; i < length; i++) {
197 f(backingArray[i]); 184 f(this[i]);
198 } 185 }
199 } 186 }
200 187
201 Collection map(f(T element)) { 188 Collection map(f(T element)) {
202 return Collections.map(this, new GrowableObjectArray.withCapacity(length), f ); 189 return Collections.map(this,
190 new GrowableObjectArray.withCapacity(length), f);
203 } 191 }
204 192
205 Collection<T> filter(bool f(T element)) { 193 Collection<T> filter(bool f(T element)) {
206 return Collections.filter(this, new GrowableObjectArray<T>(), f); 194 return Collections.filter(this, new GrowableObjectArray<T>(), f);
207 } 195 }
208 196
209 bool every(bool f(T element)) { 197 bool every(bool f(T element)) {
210 return Collections.every(this, f); 198 return Collections.every(this, f);
211 } 199 }
212 200
(...skipping 23 matching lines...) Expand all
236 } 224 }
237 225
238 226
239 // Iterator for arrays with variable size. 227 // Iterator for arrays with variable size.
240 class VariableSizeArrayIterator<T> implements Iterator<T> { 228 class VariableSizeArrayIterator<T> implements Iterator<T> {
241 VariableSizeArrayIterator(GrowableObjectArray<T> array) 229 VariableSizeArrayIterator(GrowableObjectArray<T> array)
242 : _array = array, _pos = 0 { 230 : _array = array, _pos = 0 {
243 } 231 }
244 232
245 bool hasNext() { 233 bool hasNext() {
246 return _array._length > _pos; 234 return _array.length > _pos;
247 } 235 }
248 236
249 T next() { 237 T next() {
250 if (!hasNext()) { 238 if (!hasNext()) {
251 throw const NoMoreElementsException(); 239 throw const NoMoreElementsException();
252 } 240 }
253 return _array[_pos++]; 241 return _array[_pos++];
254 } 242 }
255 243
256 final GrowableObjectArray<T> _array; 244 final GrowableObjectArray<T> _array;
257 int _pos; 245 int _pos;
258 } 246 }
259
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698