on master help sign in
Change _0 -> height, _1 -> table, _2 -> lengths
358f38eChristian Widera
libraries/Native/Array.js+146−144
@@ -8,33 +8,35 @@ Elm.Native.Array.make = function(elm) {
8
8
9 var List = Elm.Native.List.make(elm);
9 var List = Elm.Native.List.make(elm);
10
10
11− // An RRB-Tree has two distinct data types. A leaf which contains data as
11+ // A RRB-Tree has two distinct data types.
12− // an array in _1, and a height in _0, that is always 0. A node has in
12+ // Leaf -> "height" is always 0
13− // addition its size table in _2, while _1 contains an array of nodes or
13+ // "table" is an array of elements
14− // leaves.
14+ // Node -> "height" is always greater than 0
15−
15+ // "table" is an array of child nodes
16+ // "lengths" is an array of accumulated lengths of the child nodes
17+
16− // M is the maximal node size. 32 seems fast. E is the allowed increase
18+ // M is the maximal table size. 32 seems fast. E is the allowed increase
17 // of search steps when concatting to find an index. Lower values will
19 // of search steps when concatting to find an index. Lower values will
18 // decrease balancing, but will increase search steps.
20 // decrease balancing, but will increase search steps.
19 var M = 32;
21 var M = 32;
20 var E = 2;
22 var E = 2;
21
23
22 // An empty array.
24 // An empty array.
23− var empty = { ctor:"_Array", _0:0, _1:new Array() };
25+ var empty = { ctor:"_Array", height:0, table:new Array() };
24
26
25 // Gets the value at index i recursively.
27 // Gets the value at index i recursively.
26 function get(i, a) {
28 function get(i, a) {
27− if (a._0 == 0) {
29+ if (a.height == 0) {
28− if (i < a._1.length) {
30+ if (i < a.table.length) {
29− return a._1[i];
31+ return a.table[i];
30 } else {
32 } else {
31 throw new Error("Index "+ i +" on the array is out of range. Check the length first or you safeGet.");
33 throw new Error("Index "+ i +" on the array is out of range. Check the length first or you safeGet.");
32 }
34 }
33 }
35 }
34
36
35 var slot = getSlot(i, a);
37 var slot = getSlot(i, a);
36− var sub = slot > 0 ? a._2[slot-1] : 0;
38+ var sub = slot > 0 ? a.lengths[slot-1] : 0;
37− return get(i - sub, a._1[slot]);
39+ return get(i - sub, a.table[slot]);
38 }
40 }
39
41
40 // Sets the value at the index i. Only the nodes leading to i will get
42 // Sets the value at the index i. Only the nodes leading to i will get
@@ -44,14 +46,14 @@ Elm.Native.Array.make = function(elm) {
44 return a;
46 return a;
45 }
47 }
46 var newA = nodeCopy(a);
48 var newA = nodeCopy(a);
47− newA._1 = a._1.slice();
49+ newA.table = a.table.slice();
48
50
49− if (a._0 == 0) {
51+ if (a.height == 0) {
50− newA._1[i] = item;
52+ newA.table[i] = item;
51 } else {
53 } else {
52 var slot = getSlot(i, a);
54 var slot = getSlot(i, a);
53− var sub = slot > 0 ? a._2[slot-1] : 0;
55+ var sub = slot > 0 ? a.lengths[slot-1] : 0;
54− newA._1[slot] = set(i - sub, item, a._1[slot]);
56+ newA.table[slot] = set(i - sub, item, a.table[slot]);
55 }
57 }
56 return newA;
58 return newA;
57 }
59 }
@@ -63,7 +65,7 @@ Elm.Native.Array.make = function(elm) {
63 return pushed;
65 return pushed;
64 }
66 }
65
67
66− newTree = create(item, a._0);
68+ newTree = create(item, a.height);
67 return siblise(a, newTree);
69 return siblise(a, newTree);
68 }
70 }
69
71
@@ -72,10 +74,10 @@ Elm.Native.Array.make = function(elm) {
72 // null will be returned.
74 // null will be returned.
73 function push_(item, a) {
75 function push_(item, a) {
74 // Handle resursion stop at leaf level.
76 // Handle resursion stop at leaf level.
75− if (a._0 == 0) {
77+ if (a.height == 0) {
76− if (a._1.length < M) {
78+ if (a.table.length < M) {
77− var newA = { ctor:"_Array", _0:0, _1:a._1.slice() };
79+ var newA = { ctor:"_Array", height:0, table:a.table.slice() };
78− newA._1.push(item);
80+ newA.table.push(item);
79 return newA;
81 return newA;
80 } else {
82 } else {
81 return null;
83 return null;
@@ -89,19 +91,19 @@ Elm.Native.Array.make = function(elm) {
89 // be updated.
91 // be updated.
90 if (pushed != null) {
92 if (pushed != null) {
91 var newA = nodeCopy(a);
93 var newA = nodeCopy(a);
92− newA._1[newA._1.length - 1] = pushed;
94+ newA.table[newA.table.length - 1] = pushed;
93− newA._2[newA._2.length - 1]++;
95+ newA.lengths[newA.lengths.length - 1]++;
94 return newA
96 return newA
95 }
97 }
96
98
97 // When there was no space left, check if there is space left
99 // When there was no space left, check if there is space left
98 // for a new slot with a tree which contains only the item
100 // for a new slot with a tree which contains only the item
99 // at the bottom.
101 // at the bottom.
100− if (a._1.length < M) {
102+ if (a.table.length < M) {
101− var newSlot = create(item, a._0 - 1);
103+ var newSlot = create(item, a.height - 1);
102 var newA = nodeCopy(a);
104 var newA = nodeCopy(a);
103− newA._1.push(newSlot);
105+ newA.table.push(newSlot);
104− newA._2.push(newA._2[newA._2.length - 1] + length(newSlot));
106+ newA.lengths.push(newA.lengths[newA.lengths.length - 1] + length(newSlot));
105 return newA
107 return newA
106 } else {
108 } else {
107 return null;
109 return null;
@@ -114,41 +116,41 @@ Elm.Native.Array.make = function(elm) {
114 }
116 }
115
117
116 function elements_(list, a) {
118 function elements_(list, a) {
117− for (var i = a._1.length - 1; i >= 0; i--) {
119+ for (var i = a.table.length - 1; i >= 0; i--) {
118− list = a._0 == 0 ? List.Cons(a._1[i], list) : elements_(list, a._1[i]);
120+ list = a.height == 0 ? List.Cons(a.table[i], list) : elements_(list, a.table[i]);
119 }
121 }
120 return list;
122 return list;
121 }
123 }
122
124
123 // Maps a function over an array.
125 // Maps a function over an array.
124 function map(f, a) {
126 function map(f, a) {
125− var newA = { ctor:"_Array", _0:a._0, _1:new Array(a._1) };
127+ var newA = { ctor:"_Array", height:a.height, table:new Array(a.table) };
126− if (a._0 > 0) { newA._2 = a._2; }
128+ if (a.height > 0) { newA.lengths = a.lengths; }
127− for (var i = 0; i < a._1.length; i++) {
129+ for (var i = 0; i < a.table.length; i++) {
128− newA._1[i] = a._0 == 0 ? f(a._1[i]) : map(f, a._1[i]);
130+ newA.table[i] = a.height == 0 ? f(a.table[i]) : map(f, a.table[i]);
129 }
131 }
130 return newA;
132 return newA;
131 }
133 }
132
134
133 function assocMap(f, a) {
135 function assocMap(f, a) {
134− var newA = { ctor:"_Array", _0:a._0, _1:new Array(a._1) };
136+ var newA = { ctor:"_Array", height:a.height, table:new Array(a.table) };
135− if (a._0 > 0) { newA._2 = a._2; }
137+ if (a.height > 0) { newA.lengths = a.lengths; }
136− for (var i = 0; i < a._1.length; i++) {
138+ for (var i = 0; i < a.table.length; i++) {
137− newA._1[i] = a._0 == 0 ? A2(f, i, a._1[i]) : assocMap(f, a._1[i]);
139+ newA.table[i] = a.height == 0 ? A2(f, i, a.table[i]) : assocMap(f, a.table[i]);
138 }
140 }
139 return newA;
141 return newA;
140 }
142 }
141
143
142 function foldl(f, b, a) {
144 function foldl(f, b, a) {
143− for (var i = a._1.length - 1; i >= 0; i--) {
145+ for (var i = a.table.length - 1; i >= 0; i--) {
144− b = A2(f, a._0 == 0 ? a._1[i] : foldl(f, b, a._1[i]), b);
146+ b = A2(f, a.height == 0 ? a.table[i] : foldl(f, b, a.table[i]), b);
145 }
147 }
146 return b;
148 return b;
147 }
149 }
148
150
149 function foldr(f, b, a) {
151 function foldr(f, b, a) {
150− for (var i = 0; i < a._1.length; i++) {
152+ for (var i = 0; i < a.table.length; i++) {
151− b = A2(f, a._0 == 0 ? a._1[i] : foldr(f, b, a._1[i]), b);
153+ b = A2(f, a.height == 0 ? a.table[i] : foldr(f, b, a.table[i]), b);
152 }
154 }
153 return b;
155 return b;
154 }
156 }
@@ -170,15 +172,15 @@ Elm.Native.Array.make = function(elm) {
170 }
172 }
171
173
172 // Handle leaf level.
174 // Handle leaf level.
173− if (a._0 == 0) {
175+ if (a.height == 0) {
174− var newA = { ctor:"_Array", _0:0 };
176+ var newA = { ctor:"_Array", height:0 };
175− newA._1 = a._1.slice(0, to + 1);
177+ newA.table = a.table.slice(0, to + 1);
176 return newA;
178 return newA;
177 }
179 }
178
180
179 // Slice the right recursively.
181 // Slice the right recursively.
180 var right = getSlot(to, a);
182 var right = getSlot(to, a);
181− var sliced = sliceRight(to - (right > 0 ? a._2[right - 1] : 0), a._1[right]);
183+ var sliced = sliceRight(to - (right > 0 ? a.lengths[right - 1] : 0), a.table[right]);
182
184
183 // Maybe the a node is not even needed, as sliced contains the whole slice.
185 // Maybe the a node is not even needed, as sliced contains the whole slice.
184 if (right == 0) {
186 if (right == 0) {
@@ -186,11 +188,11 @@ Elm.Native.Array.make = function(elm) {
186 }
188 }
187
189
188 // Create new node.
190 // Create new node.
189− var newA = { ctor:"_Array", _0:a._0
191+ var newA = { ctor:"_Array", height:a.height
190− , _1:a._1.slice(0, right + 1)
192+ , table:a.table.slice(0, right + 1)
191− , _2:a._2.slice(0, right + 1) };
193+ , lengths:a.lengths.slice(0, right + 1) };
192− newA._1[right] = sliced;
194+ newA.table[right] = sliced;
193− newA._2[right] = length(sliced) + (right > 0 ? newA._2[right - 1] : 0);
195+ newA.lengths[right] = length(sliced) + (right > 0 ? newA.lengths[right - 1] : 0);
194 return newA;
196 return newA;
195 }
197 }
196
198
@@ -200,30 +202,30 @@ Elm.Native.Array.make = function(elm) {
200 }
202 }
201
203
202 // Handle leaf level.
204 // Handle leaf level.
203− if (a._0 == 0) {
205+ if (a.height == 0) {
204− var newA = { ctor:"_Array", _0:0 };
206+ var newA = { ctor:"_Array", height:0 };
205− newA._1 = a._1.slice(from, a._1.length + 1);
207+ newA.table = a.table.slice(from, a.table.length + 1);
206 return newA;
208 return newA;
207 }
209 }
208
210
209 // Slice the left recursively.
211 // Slice the left recursively.
210 var left = getSlot(from, a);
212 var left = getSlot(from, a);
211− var sliced = sliceLeft(from - (left > 0 ? a._2[left - 1] : 0), a._1[left]);
213+ var sliced = sliceLeft(from - (left > 0 ? a.lengths[left - 1] : 0), a.table[left]);
212
214
213 // Maybe the a node is not even needed, as sliced contains the whole slice.
215 // Maybe the a node is not even needed, as sliced contains the whole slice.
214− if (left == a._1.length - 1) {
216+ if (left == a.table.length - 1) {
215 return sliced;
217 return sliced;
216 }
218 }
217
219
218 // Create new node.
220 // Create new node.
219− var newA = { ctor:"_Array", _0:a._0
221+ var newA = { ctor:"_Array", height:a.height
220− , _1:a._1.slice(left, a._1.length + 1)
222+ , table:a.table.slice(left, a.table.length + 1)
221− , _2:new Array(a._1.length - left) };
223+ , lengths:new Array(a.table.length - left) };
222− newA._1[left] = sliced;
224+ newA.table[left] = sliced;
223 var len = 0;
225 var len = 0;
224− for (var i = 0; i < newA._1.length; i++) {
226+ for (var i = 0; i < newA.table.length; i++) {
225− len += length(newA._1[i]);
227+ len += length(newA.table[i]);
226− newA._2[i] = len;
228+ newA.lengths[i] = len;
227 }
229 }
228
230
229 return newA;
231 return newA;
@@ -233,12 +235,12 @@ Elm.Native.Array.make = function(elm) {
233 // TODO: Add support for concatting trees of different sizes. Current
235 // TODO: Add support for concatting trees of different sizes. Current
234 // behavior will just rise the lower tree and then concat them.
236 // behavior will just rise the lower tree and then concat them.
235 function concat(a, b) {
237 function concat(a, b) {
236− if (b._0 > a._0) { return concat(parentise(a, b._0), b); }
238+ if (b.height > a.height) { return concat(parentise(a, b.height), b); }
237− if (a._0 > b._0) { return concat(a, parentise(b, a._0)); }
239+ if (a.height > b.height) { return concat(a, parentise(b, a.height)); }
238− if (a._0 == 0) { return concat(parentise(a, 1), parentise(b, 1)); }
240+ if (a.height == 0) { return concat(parentise(a, 1), parentise(b, 1)); }
239
241
240 var c = concat_(a, b);
242 var c = concat_(a, b);
241− if (c[1]._1.length > 0) {
243+ if (c[1].table.length > 0) {
242 return siblise(c[0], c[1]);
244 return siblise(c[0], c[1]);
243 } else {
245 } else {
244 return c[0];
246 return c[0];
@@ -249,7 +251,7 @@ Elm.Native.Array.make = function(elm) {
249 // needs to be handled by the function, that called concat_. May be only
251 // needs to be handled by the function, that called concat_. May be only
250 // called for trees with an minimal height of 1.
252 // called for trees with an minimal height of 1.
251 function concat_(a, b) {
253 function concat_(a, b) {
252− if (a._0 == 1) {
254+ if (a.height == 1) {
253 // Check if balancing is needed and return based on that.
255 // Check if balancing is needed and return based on that.
254 var toRemove = calcToRemove(a, b);
256 var toRemove = calcToRemove(a, b);
255 if (toRemove <= E) {
257 if (toRemove <= E) {
@@ -263,29 +265,29 @@ Elm.Native.Array.make = function(elm) {
263 a = nodeCopy(a), b = nodeCopy(b);
265 a = nodeCopy(a), b = nodeCopy(b);
264
266
265 // Adjust the bottom right side of the new tree.
267 // Adjust the bottom right side of the new tree.
266− a._1[a._1.length - 1] = concated[0];
268+ a.table[a.table.length - 1] = concated[0];
267− a._2[a._2.length - 1] = length(concated[0])
269+ a.lengths[a.lengths.length - 1] = length(concated[0])
268− a._2[a._2.length - 1] += a._2.length > 1 ? a._2[a._2.length - 2] : 0;
270+ a.lengths[a.lengths.length - 1] += a.lengths.length > 1 ? a.lengths[a.lengths.length - 2] : 0;
269
271
270 // Adjust the bottom left side of the new tree.
272 // Adjust the bottom left side of the new tree.
271− if (concated[1]._1.length > 0) {
273+ if (concated[1].table.length > 0) {
272− b._1[0] = concated[1];
274+ b.table[0] = concated[1];
273− b._2[0] = length(concated[1]);
275+ b.lengths[0] = length(concated[1]);
274− for (var i = 1, len = length(b._1[0]); i < b._2.length; i++) {
276+ for (var i = 1, len = length(b.table[0]); i < b.lengths.length; i++) {
275− len += length(b._1[i]);
277+ len += length(b.table[i]);
276− b._2[i] = len;
278+ b.lengths[i] = len;
277 }
279 }
278 } else {
280 } else {
279− b._1.shift();
281+ b.table.shift();
280− for (var i = 1; i < b._2.length; i++) {
282+ for (var i = 1; i < b.lengths.length; i++) {
281− b._2[i] = b._2[i] - b._2[0];
283+ b.lengths[i] = b.lengths[i] - b.lengths[0];
282 }
284 }
283− b._2.shift();
285+ b.lengths.shift();
284 }
286 }
285
287
286 // Check if balancing is needed and return based on that.
288 // Check if balancing is needed and return based on that.
287 var toRemove = calcToRemove(a, b);
289 var toRemove = calcToRemove(a, b);
288− if (toRemove <= E || b._1.length == 0) {
290+ if (toRemove <= E || b.table.length == 0) {
289 return [a,b];
291 return [a,b];
290 }
292 }
291
293
@@ -295,14 +297,14 @@ Elm.Native.Array.make = function(elm) {
295 // Returns the extra search steps for E. Refer to the paper.
297 // Returns the extra search steps for E. Refer to the paper.
296 function calcToRemove(a, b) {
298 function calcToRemove(a, b) {
297 var subLengths = 0;
299 var subLengths = 0;
298− for (var i = 0; i < a._1.length; i++) {
300+ for (var i = 0; i < a.table.length; i++) {
299− subLengths += a._1[i]._1.length;
301+ subLengths += a.table[i].table.length;
300 }
302 }
301− for (var i = 0; i < b._1.length; i++) {
303+ for (var i = 0; i < b.table.length; i++) {
302− subLengths += b._1[i]._1.length;
304+ subLengths += b.table[i].table.length;
303 }
305 }
304
306
305− var toRemove = a._1.length + b._1.length
307+ var toRemove = a.table.length + b.table.length
306 return toRemove - (Math.floor((subLengths - 1) / M) + 1);
308 return toRemove - (Math.floor((subLengths - 1) / M) + 1);
307 }
309 }
308
310
@@ -321,57 +323,57 @@ Elm.Native.Array.make = function(elm) {
321
323
322 // Creates a node or leaf with a given length at their arrays for perfomance.
324 // Creates a node or leaf with a given length at their arrays for perfomance.
323 // Is only used by shuffle.
325 // Is only used by shuffle.
324− function createNode(height, length) {
326+ function createNode(h, length) {
325 if (length < 0) { length = 0; }
327 if (length < 0) { length = 0; }
326− var a = { ctor:"_Array", _0:height, _1:new Array(length) };
328+ var a = { ctor:"_Array", height:h, table:new Array(length) };
327− if (height > 0) {
329+ if (h > 0) {
328− a._2 = new Array(length);
330+ a.lengths = new Array(length);
329 }
331 }
330 return a;
332 return a;
331 }
333 }
332
334
333 function saveSlot(a, b, index, slot) {
335 function saveSlot(a, b, index, slot) {
334− set2(a._1, b._1, index, slot);
336+ set2(a.table, b.table, index, slot);
335
337
336− var l = (index == 0 || index == a._2.length) ?
338+ var l = (index == 0 || index == a.lengths.length) ?
337− 0 : get2(a._2, a._2, index - 1);
339+ 0 : get2(a.lengths, a.lengths, index - 1);
338− set2(a._2, b._2, index, l + length(slot));
340+ set2(a.lengths, b.lengths, index, l + length(slot));
339 }
341 }
340
342
341 // Returns an array of two balanced nodes.
343 // Returns an array of two balanced nodes.
342 function shuffle(a, b, toRemove) {
344 function shuffle(a, b, toRemove) {
343− var newA = createNode(a._0, Math.min(M, a._1.length + b._1.length - toRemove));
345+ var newA = createNode(a.height, Math.min(M, a.table.length + b.table.length - toRemove));
344− var newB = createNode(a._0, newA._1.length - (a._1.length + b._1.length - toRemove));
346+ var newB = createNode(a.height, newA.table.length - (a.table.length + b.table.length - toRemove));
345
347
346 // Skip the slots with size M. More precise: copy the slot references
348 // Skip the slots with size M. More precise: copy the slot references
347 // to the new node
349 // to the new node
348 var read = 0;
350 var read = 0;
349− while (get2(a._1, b._1, read)._1.length % M == 0) {
351+ while (get2(a.table, b.table, read).table.length % M == 0) {
350− set2(newA._1, newB._1, read, get2(a._1, b._1, read));
352+ set2(newA.table, newB.table, read, get2(a.table, b.table, read));
351− set2(newA._2, newB._2, read, get2(a._2, b._2, read));
353+ set2(newA.lengths, newB.lengths, read, get2(a.lengths, b.lengths, read));
352 read++;
354 read++;
353 }
355 }
354
356
355 // Pulling items from left to right, caching in a slot before writing
357 // Pulling items from left to right, caching in a slot before writing
356 // it into the new nodes.
358 // it into the new nodes.
357 var write = read;
359 var write = read;
358− var slot = new createNode(a._0 - 1, 0);
360+ var slot = new createNode(a.height - 1, 0);
359 var from = 0;
361 var from = 0;
360
362
361 // If the current slot is still containing data, then there will be at
363 // If the current slot is still containing data, then there will be at
362 // least one more write, so we do not break this loop yet.
364 // least one more write, so we do not break this loop yet.
363− while (read - write - (slot._1.length > 0 ? 1 : 0) < toRemove) {
365+ while (read - write - (slot.table.length > 0 ? 1 : 0) < toRemove) {
364 // Find out the max possible items for copying.
366 // Find out the max possible items for copying.
365− var source = get2(a._1, b._1, read);
367+ var source = get2(a.table, b.table, read);
366− var to = Math.min(M - slot._1.length, source._1.length)
368+ var to = Math.min(M - slot.table.length, source.table.length)
367
369
368 // Copy and adjust size table.
370 // Copy and adjust size table.
369− slot._1 = slot._1.concat(source._1.slice(from, to));
371+ slot.table = slot.table.concat(source.table.slice(from, to));
370− if (slot._0 > 0) {
372+ if (slot.height > 0) {
371− var len = slot._2.length;
373+ var len = slot.lengths.length;
372 for (var i = len; i < len + to - from; i++) {
374 for (var i = len; i < len + to - from; i++) {
373− slot._2[i] = length(slot._1[i]);
375+ slot.lengths[i] = length(slot.table[i]);
374− slot._2[i] += (i > 0 ? slot._2[i - 1] : 0);
376+ slot.lengths[i] += (i > 0 ? slot.lengths[i - 1] : 0);
375 }
377 }
376 }
378 }
377
379
@@ -379,60 +381,60 @@ Elm.Native.Array.make = function(elm) {
379
381
380 // Only proceed to next slots[i] if the current one was
382 // Only proceed to next slots[i] if the current one was
381 // fully copied.
383 // fully copied.
382− if (source._1.length <= to) {
384+ if (source.table.length <= to) {
383 read++; from = 0;
385 read++; from = 0;
384 }
386 }
385
387
386 // Only create a new slot if the current one is filled up.
388 // Only create a new slot if the current one is filled up.
387− if (slot._1.length == M) {
389+ if (slot.table.length == M) {
388 saveSlot(newA, newB, write, slot);
390 saveSlot(newA, newB, write, slot);
389− slot = createNode(a._0 - 1,0);
391+ slot = createNode(a.height - 1,0);
390 write++;
392 write++;
391 }
393 }
392 }
394 }
393
395
394 // Cleanup after the loop. Copy the last slot into the new nodes.
396 // Cleanup after the loop. Copy the last slot into the new nodes.
395− if (slot._1.length > 0) {
397+ if (slot.table.length > 0) {
396 saveSlot(newA, newB, write, slot);
398 saveSlot(newA, newB, write, slot);
397 write++;
399 write++;
398 }
400 }
399
401
400 // Shift the untouched slots to the left
402 // Shift the untouched slots to the left
401− while (read < a._1.length + b._1.length ) {
403+ while (read < a.table.length + b.table.length ) {
402− saveSlot(newA, newB, write, get2(a._1, b._1, read));
404+ saveSlot(newA, newB, write, get2(a.table, b.table, read));
403 read++; write++;
405 read++; write++;
404 }
406 }
405
407
406 return [newA, newB];
408 return [newA, newB];
407 }
409 }
408
410
409− // Helper functions
411+ // Navigation functions
410− function botRight(a) { return a._1[a._1.length - 1]; }
412+ function botRight(a) { return a.table[a.table.length - 1]; }
411− function botLeft(a) { return a._1[0]; }
413+ function botLeft(a) { return a.table[0]; }
412
414
413− // Copies a node for updating. Note that you should not use
415+ // Copies a node for updating. Note that you should not use this if
414− // this if only updating one of _1 and _2 for performance reasons.
416+ // only updating only one of "table" or "lengths" for performance reasons.
415 function nodeCopy(a) {
417 function nodeCopy(a) {
416− var newA = { ctor:"_Array", _0:a._0
418+ var newA = { ctor:"_Array", height:a.height
417− , _1:a._1.slice() };
419+ , table:a.table.slice() };
418− if (a._0 > 0) { newA._2 = a._2.slice(); }
420+ if (a.height > 0) { newA.lengths = a.lengths.slice(); }
419 return newA;
421 return newA;
420 }
422 }
421
423
422 // Returns how many items are in the tree.
424 // Returns how many items are in the tree.
423 function length(a) {
425 function length(a) {
424− if (a._0 == 0) {
426+ if (a.height == 0) {
425− return a._1.length;
427+ return a.table.length;
426 } else {
428 } else {
427− return a._2[a._2.length - 1];
429+ return a.lengths[a.lengths.length - 1];
428 }
430 }
429 }
431 }
430
432
431 // Calculates in which slot the item probably is, then
433 // Calculates in which slot the item probably is, then
432− // find the exact slot in the size table ._2. Returns the index.
434+ // find the exact slot in "lengths". Returns the index.
433 function getSlot(i, a) {
435 function getSlot(i, a) {
434− var slot = Math.floor(i / (Math.pow(M, a._0)));
436+ var slot = Math.floor(i / (Math.pow(M, a.height)));
435− while (a._2[slot] <= i) {
437+ while (a.lengths[slot] <= i) {
436 slot++
438 slot++
437 }
439 }
438 return slot;
440 return slot;
@@ -440,33 +442,33 @@ Elm.Native.Array.make = function(elm) {
440
442
441 // Recursively creates a tree with a given height containing
443 // Recursively creates a tree with a given height containing
442 // only the given item.
444 // only the given item.
443− function create(item, height) {
445+ function create(item, h) {
444− if (height == 0) {
446+ if (h == 0) {
445− return { ctor:"_Array", _0:0
447+ return { ctor:"_Array", height:0
446− , _1:[item] };
448+ , table:[item] };
447 } else {
449 } else {
448− return { ctor:"_Array", _0:height
450+ return { ctor:"_Array", height:h
449− , _1:[create(item, height - 1)]
451+ , table:[create(item, h - 1)]
450− , _2:[1] };
452+ , lengths:[1] };
451 }
453 }
452 }
454 }
453
455
454 // Recursively creates a tree that contains the given tree.
456 // Recursively creates a tree that contains the given tree.
455− function parentise(tree, height) {
457+ function parentise(tree, h) {
456− if (height == tree._0) {
458+ if (h == tree.height) {
457 return tree;
459 return tree;
458 } else {
460 } else {
459− return { ctor:"_Array", _0:height
461+ return { ctor:"_Array", height:h
460− , _1:[parentise(tree, height - 1)]
462+ , table:[parentise(tree, h - 1)]
461− , _2:[length(tree)] };
463+ , lengths:[length(tree)] };
462 }
464 }
463 }
465 }
464
466
465 // Emphasizes blood brotherhood beneath two trees.
467 // Emphasizes blood brotherhood beneath two trees.
466 function siblise(a, b) {
468 function siblise(a, b) {
467− return { ctor:"_Array", _0:a._0 + 1
469+ return { ctor:"_Array", height:a.height + 1
468− , _1:[a, b]
470+ , table:[a, b]
469− , _2:[length(a), length(a) + length(b)] };
471+ , lengths:[length(a), length(a) + length(b)] };
470 }
472 }
471
473
472 Elm.Native.Array.values = {
474 Elm.Native.Array.values = {