@calcit/procs 0.5.0-a6 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ts-src/js-map.ts CHANGED
@@ -3,7 +3,19 @@ import * as ternaryTree from "@calcit/ternary-tree";
3
3
  import { CalcitValue } from "./js-primes";
4
4
  import { CalcitSet } from "./js-set";
5
5
 
6
- import { TernaryTreeMap, initTernaryTreeMap, mapLen, assocMap, dissocMap, isMapEmpty, Hash, toPairsArray, mapGetDefault } from "@calcit/ternary-tree";
6
+ import {
7
+ TernaryTreeMap,
8
+ initTernaryTreeMap,
9
+ mapLen,
10
+ assocMap,
11
+ dissocMap,
12
+ isMapEmpty,
13
+ Hash,
14
+ toPairsArray,
15
+ mapGetDefault,
16
+ initEmptyTernaryTreeMap,
17
+ initTernaryTreeMapFromArray,
18
+ } from "@calcit/ternary-tree";
7
19
 
8
20
  import { isNestedCalcitData, tipNestedCalcitData, toString } from "./calcit-data";
9
21
 
@@ -21,62 +33,192 @@ let fakeUniqueSymbol = [] as any;
21
33
 
22
34
  export class CalcitMap {
23
35
  cachedHash: Hash;
24
- /** in arrayMode, only flatten values, not tree structure */
25
- arrayMode: boolean;
26
- arrayValue: CalcitValue[];
27
36
  value: TernaryTreeMap<CalcitValue, CalcitValue>;
28
- skipValue: CalcitValue;
29
- constructor(value: CalcitValue[] | TernaryTreeMap<CalcitValue, CalcitValue>) {
37
+ constructor(value: TernaryTreeMap<CalcitValue, CalcitValue>) {
30
38
  if (value == null) {
31
- this.arrayMode = true;
32
- this.arrayValue = [];
33
- } else if (Array.isArray(value)) {
34
- this.arrayMode = true;
35
- this.arrayValue = value;
39
+ this.value = initEmptyTernaryTreeMap();
36
40
  } else {
37
- this.arrayMode = false;
38
41
  this.value = value;
39
42
  }
40
43
  }
41
- turnMap() {
42
- if (this.arrayMode) {
43
- var dict: Array<[CalcitValue, CalcitValue]> = [];
44
- let halfLength = this.arrayValue.length >> 1;
45
- for (let idx = 0; idx < halfLength; idx++) {
46
- dict.push([this.arrayValue[idx << 1], this.arrayValue[(idx << 1) + 1]]);
44
+ len() {
45
+ return mapLen(this.value);
46
+ }
47
+ get(k: CalcitValue) {
48
+ return mapGetDefault(this.value, k, null);
49
+ }
50
+ assoc(...args: CalcitValue[]) {
51
+ if (args.length % 2 !== 0) throw new Error("expected even arguments");
52
+ let size = Math.floor(args.length / 2);
53
+
54
+ let result = this.value;
55
+ for (let idx = 0; idx < size; idx++) {
56
+ let k = args[idx << 1];
57
+ let v = args[(idx << 1) + 1];
58
+ result = assocMap(result, k, v);
59
+ }
60
+ return new CalcitMap(result);
61
+ }
62
+ dissoc(...args: CalcitValue[]) {
63
+ let ret = this.value;
64
+ for (let idx = 0; idx < args.length; idx++) {
65
+ ret = dissocMap(ret, args[idx]);
66
+ }
67
+ return new CalcitMap(ret);
68
+ }
69
+ toString(shorter = false) {
70
+ let itemsCode = "";
71
+ for (let [k, v] of this.pairs()) {
72
+ if (shorter) {
73
+ let keyPart = isNestedCalcitData(k) ? tipNestedCalcitData(k) : toString(k, true);
74
+ let valuePart = isNestedCalcitData(v) ? tipNestedCalcitData(v) : toString(v, true);
75
+ itemsCode = `${itemsCode} (${keyPart} ${valuePart})`;
76
+ } else {
77
+ itemsCode = `${itemsCode} (${toString(k, true)} ${toString(v, true)})`;
47
78
  }
48
- this.value = initTernaryTreeMap(dict);
49
- this.arrayMode = false;
50
- this.arrayValue = null;
51
79
  }
80
+ return `({}${itemsCode})`;
52
81
  }
53
- len() {
54
- if (this.arrayMode) {
55
- return this.arrayValue.length >> 1;
82
+ isEmpty() {
83
+ return isMapEmpty(this.value);
84
+ }
85
+ pairs(): Array<[CalcitValue, CalcitValue]> {
86
+ return toPairsArray(this.value);
87
+ }
88
+ keysArray(): Array<CalcitValue> {
89
+ return [...ternaryTree.toKeys(this.value)];
90
+ }
91
+ contains(k: CalcitValue) {
92
+ return ternaryTree.contains(this.value, k);
93
+ }
94
+ merge(ys: CalcitMap | CalcitSliceMap) {
95
+ return this.mergeSkip(ys, fakeUniqueSymbol);
96
+ }
97
+ mergeSkip(ys: CalcitMap | CalcitSliceMap, v: CalcitValue) {
98
+ if (ys == null) {
99
+ return this;
100
+ }
101
+
102
+ if (!(ys instanceof CalcitMap || ys instanceof CalcitSliceMap)) {
103
+ console.error("value:", v);
104
+ throw new Error("Expected map to merge");
105
+ }
106
+
107
+ if (ys instanceof CalcitSliceMap) {
108
+ let ret = this.value;
109
+ let size = ys.chunk.length >> 1;
110
+ for (let i = 0; i < size; i++) {
111
+ let pos = i << 1;
112
+ if (ys.chunk[pos + 1] === v) {
113
+ continue;
114
+ }
115
+ ret = assocMap(ret, ys.chunk[pos], ys.chunk[pos + 1]);
116
+ }
117
+ return new CalcitMap(ret);
56
118
  } else {
57
- return mapLen(this.value);
119
+ return new CalcitMap(ternaryTree.mergeSkip(this.value, ys.value, v));
58
120
  }
59
121
  }
122
+
123
+ /** TODO implement diff with low level code, opens opportunity for future optimizations */
124
+ diffNew(ys: CalcitMap | CalcitSliceMap): CalcitMap {
125
+ let zs = this.value;
126
+ if (ys instanceof CalcitSliceMap) {
127
+ let size = ys.chunk.length >> 1;
128
+ for (let i = 0; i < size; i++) {
129
+ let pos = i << 1;
130
+ let k = ys.chunk[pos];
131
+ if (ternaryTree.contains(zs, k)) {
132
+ zs = ternaryTree.dissocMap(zs, k);
133
+ }
134
+ }
135
+ return new CalcitMap(zs);
136
+ } else if (ys instanceof CalcitMap) {
137
+ let ysKeys = ys.keysArray();
138
+ for (let i = 0; i < ysKeys.length; i++) {
139
+ let k = ysKeys[i];
140
+ if (ternaryTree.contains(zs, k)) {
141
+ zs = ternaryTree.dissocMap(zs, k);
142
+ }
143
+ }
144
+ return new CalcitMap(zs);
145
+ } else {
146
+ throw new Error("unknown data to diff");
147
+ }
148
+ }
149
+
150
+ /** TODO implement diff with low level code, opens opportunity for future optimizations */
151
+ diffKeys(ys: CalcitMap | CalcitSliceMap): CalcitSet {
152
+ let ret: Array<CalcitValue> = [];
153
+ let ks = this.keysArray();
154
+ for (let i = 0; i < ks.length; i++) {
155
+ let k = ks[i];
156
+ if (!ys.contains(k)) {
157
+ ret.push(k);
158
+ }
159
+ }
160
+ return new CalcitSet(ret);
161
+ }
162
+
163
+ /** TODO implement diff with low level code, opens opportunity for future optimizations */
164
+ commonKeys(ys: CalcitMap | CalcitSliceMap): CalcitSet {
165
+ let ret: Array<CalcitValue> = [];
166
+ let ks = this.keysArray();
167
+ for (let i = 0; i < ks.length; i++) {
168
+ let k = ks[i];
169
+ if (ys.contains(k)) {
170
+ ret.push(k);
171
+ }
172
+ }
173
+ return new CalcitSet(ret);
174
+ }
175
+ }
176
+
177
+ // store small map in linear array to reduce cost of building tree
178
+ export class CalcitSliceMap {
179
+ cachedHash: Hash;
180
+ /** in arrayMode, only flatten values, instead of tree structure */
181
+ chunk: CalcitValue[];
182
+ constructor(value: CalcitValue[]) {
183
+ if (value == null) {
184
+ this.chunk = [];
185
+ } else if (Array.isArray(value)) {
186
+ this.chunk = value;
187
+ } else {
188
+ throw new Error("unknown data for map");
189
+ }
190
+ }
191
+ turnMap(): CalcitMap {
192
+ var dict: Array<[CalcitValue, CalcitValue]> = [];
193
+ let halfLength = this.chunk.length >> 1;
194
+ for (let idx = 0; idx < halfLength; idx++) {
195
+ dict.push([this.chunk[idx << 1], this.chunk[(idx << 1) + 1]]);
196
+ }
197
+ let value = initTernaryTreeMapFromArray(dict);
198
+ return new CalcitMap(value);
199
+ }
200
+ len() {
201
+ return this.chunk.length >> 1;
202
+ }
60
203
  get(k: CalcitValue) {
61
- if (this.arrayMode && this.arrayValue.length <= 16) {
62
- let size = this.arrayValue.length >> 1;
204
+ if (this.chunk.length <= 16) {
205
+ let size = this.chunk.length >> 1;
63
206
  for (let i = 0; i < size; i++) {
64
207
  let pos = i << 1;
65
- if (DATA_EQUAL(this.arrayValue[pos], k)) {
66
- return this.arrayValue[pos + 1];
208
+ if (DATA_EQUAL(this.chunk[pos], k)) {
209
+ return this.chunk[pos + 1];
67
210
  }
68
211
  }
69
212
  return null;
70
213
  } else {
71
- this.turnMap();
72
- return mapGetDefault(this.value, k, null);
214
+ return this.turnMap().get(k);
73
215
  }
74
216
  }
75
217
  assoc(...args: CalcitValue[]) {
76
218
  if (args.length % 2 !== 0) throw new Error("expected even arguments");
77
219
  let size = Math.floor(args.length / 2);
78
- if (this.arrayMode && this.arrayValue.length <= 16) {
79
- let ret = this.arrayValue.slice(0);
220
+ if (this.chunk.length <= 16) {
221
+ let ret = this.chunk.slice(0);
80
222
  outer: for (let j = 0; j < size; j++) {
81
223
  let k = args[j << 1];
82
224
  let v = args[(j << 1) + 1];
@@ -88,38 +230,26 @@ export class CalcitMap {
88
230
  }
89
231
  ret.push(k, v);
90
232
  }
91
- return new CalcitMap(ret);
233
+ return new CalcitSliceMap(ret);
92
234
  } else {
93
- this.turnMap();
94
- let result = this.value;
95
- for (let idx = 0; idx < size; idx++) {
96
- let k = args[idx << 1];
97
- let v = args[(idx << 1) + 1];
98
- result = assocMap(result, k, v);
99
- }
100
- return new CalcitMap(result);
235
+ return this.turnMap().assoc(...args);
101
236
  }
102
237
  }
103
238
  dissoc(...args: CalcitValue[]) {
104
- if (this.arrayMode && this.arrayValue.length <= 16) {
239
+ if (this.chunk.length <= 16) {
105
240
  let ret: CalcitValue[] = [];
106
- outer: for (let i = 0; i < this.arrayValue.length; i += 2) {
241
+ outer: for (let i = 0; i < this.chunk.length; i += 2) {
107
242
  for (let j = 0; j < args.length; j++) {
108
243
  let k = args[j];
109
- if (DATA_EQUAL(k, this.arrayValue[i])) {
244
+ if (DATA_EQUAL(k, this.chunk[i])) {
110
245
  continue outer;
111
246
  }
112
247
  }
113
- ret.push(this.arrayValue[i], this.arrayValue[i + 1]);
248
+ ret.push(this.chunk[i], this.chunk[i + 1]);
114
249
  }
115
- return new CalcitMap(ret);
250
+ return new CalcitSliceMap(ret);
116
251
  } else {
117
- this.turnMap();
118
- let ret = this.value;
119
- for (let idx = 0; idx < args.length; idx++) {
120
- ret = dissocMap(ret, args[idx]);
121
- }
122
- return new CalcitMap(ret);
252
+ return this.turnMap().dissoc(...args);
123
253
  }
124
254
  }
125
255
  toString(shorter = false) {
@@ -136,131 +266,82 @@ export class CalcitMap {
136
266
  return `({}${itemsCode})`;
137
267
  }
138
268
  isEmpty() {
139
- if (this.arrayMode) {
140
- return this.arrayValue.length === 0;
141
- } else {
142
- return isMapEmpty(this.value);
143
- }
269
+ return this.chunk.length === 0;
144
270
  }
145
271
  pairs(): Array<[CalcitValue, CalcitValue]> {
146
- if (this.arrayMode) {
147
- let ret: Array<[CalcitValue, CalcitValue]> = [];
148
- let size = this.arrayValue.length >> 1;
149
- for (let i = 0; i < size; i++) {
150
- let pos = i << 1;
151
- ret.push([this.arrayValue[pos], this.arrayValue[pos + 1]]);
152
- }
153
- return ret;
154
- } else {
155
- return toPairsArray(this.value);
272
+ let ret: Array<[CalcitValue, CalcitValue]> = [];
273
+ let size = this.chunk.length >> 1;
274
+ for (let i = 0; i < size; i++) {
275
+ let pos = i << 1;
276
+ ret.push([this.chunk[pos], this.chunk[pos + 1]]);
156
277
  }
278
+ return ret;
157
279
  }
158
280
  keysArray(): Array<CalcitValue> {
159
- if (this.arrayMode) {
160
- let ret: Array<CalcitValue> = [];
161
- let size = this.arrayValue.length >> 1;
162
- for (let i = 0; i < size; i++) {
163
- let pos = i << 1;
164
- ret.push(this.arrayValue[pos]);
165
- }
166
- return ret;
167
- } else {
168
- return [...ternaryTree.toKeys(this.value)];
281
+ let ret: Array<CalcitValue> = [];
282
+ let size = this.chunk.length >> 1;
283
+ for (let i = 0; i < size; i++) {
284
+ let pos = i << 1;
285
+ ret.push(this.chunk[pos]);
169
286
  }
287
+ return ret;
170
288
  }
171
289
  contains(k: CalcitValue) {
172
- if (this.arrayMode && this.arrayValue.length <= 16) {
290
+ if (this.chunk.length <= 16) {
173
291
  // guessed number
174
- let size = this.arrayValue.length >> 1;
292
+ let size = this.chunk.length >> 1;
175
293
  for (let i = 0; i < size; i++) {
176
294
  let pos = i << 1;
177
- if (DATA_EQUAL(this.arrayValue[pos], k)) {
295
+ if (DATA_EQUAL(this.chunk[pos], k)) {
178
296
  return true;
179
297
  }
180
298
  }
181
299
  return false;
182
300
  } else {
183
- this.turnMap();
184
- return ternaryTree.contains(this.value, k);
301
+ return this.turnMap().contains(k);
185
302
  }
186
303
  }
187
- merge(ys: CalcitMap) {
304
+ merge(ys: CalcitMap | CalcitSliceMap) {
188
305
  return this.mergeSkip(ys, fakeUniqueSymbol);
189
306
  }
190
- mergeSkip(ys: CalcitMap, v: CalcitValue) {
307
+ mergeSkip(ys: CalcitMap | CalcitSliceMap, v: CalcitValue) {
191
308
  if (ys == null) {
192
309
  return this;
193
310
  }
194
311
 
195
- if (!(ys instanceof CalcitMap)) {
312
+ if (!(ys instanceof CalcitMap || ys instanceof CalcitSliceMap)) {
196
313
  console.error("value:", v);
197
314
  throw new Error("Expected map to merge");
198
315
  }
199
316
 
200
- if (this.arrayMode && ys.arrayMode && this.arrayValue.length + ys.arrayValue.length <= 24) {
317
+ if (ys instanceof CalcitSliceMap && this.chunk.length + ys.len() <= 24) {
201
318
  // probably this length < 16, ys length < 8
202
- let ret = this.arrayValue.slice(0);
203
- outer: for (let i = 0; i < ys.arrayValue.length; i = i + 2) {
204
- if (ys.arrayValue[i + 1] === v) {
319
+ let ret = this.chunk.slice(0);
320
+ outer: for (let i = 0; i < ys.chunk.length; i = i + 2) {
321
+ if (ys.chunk[i + 1] === v) {
205
322
  continue;
206
323
  }
207
324
  for (let k = 0; k < ret.length; k = k + 2) {
208
- if (DATA_EQUAL(ys.arrayValue[i], ret[k])) {
209
- ret[k + 1] = ys.arrayValue[i + 1];
325
+ if (DATA_EQUAL(ys.chunk[i], ret[k])) {
326
+ ret[k + 1] = ys.chunk[i + 1];
210
327
  continue outer;
211
328
  }
212
329
  }
213
- ret.push(ys.arrayValue[i], ys.arrayValue[i + 1]);
330
+ ret.push(ys.chunk[i], ys.chunk[i + 1]);
214
331
  }
215
- return new CalcitMap(ret);
332
+ return new CalcitSliceMap(ret);
216
333
  }
217
334
 
218
- this.turnMap();
219
-
220
- if (ys.arrayMode) {
221
- let ret = this.value;
222
- let size = ys.arrayValue.length >> 1;
223
- for (let i = 0; i < size; i++) {
224
- let pos = i << 1;
225
- if (ys.arrayValue[pos + 1] === v) {
226
- continue;
227
- }
228
- ret = assocMap(ret, ys.arrayValue[pos], ys.arrayValue[pos + 1]);
229
- }
230
- return new CalcitMap(ret);
231
- } else {
232
- return new CalcitMap(ternaryTree.mergeSkip(this.value, ys.value, v));
233
- }
335
+ return this.turnMap().mergeSkip(ys, v);
234
336
  }
235
337
 
236
338
  /** TODO implement diff with low level code, opens opportunity for future optimizations */
237
- diffNew(ys: CalcitMap): CalcitMap {
238
- this.turnMap();
239
- let zs = this.value;
240
- if (ys.arrayMode) {
241
- let size = ys.arrayValue.length >> 1;
242
- for (let i = 0; i < size; i++) {
243
- let pos = i << 1;
244
- let k = ys.arrayValue[pos];
245
- if (ternaryTree.contains(zs, k)) {
246
- zs = ternaryTree.dissocMap(zs, k);
247
- }
248
- }
249
- return new CalcitMap(zs);
250
- } else {
251
- let ysKeys = ys.keysArray();
252
- for (let i = 0; i < ysKeys.length; i++) {
253
- let k = ysKeys[i];
254
- if (ternaryTree.contains(zs, k)) {
255
- zs = ternaryTree.dissocMap(zs, k);
256
- }
257
- }
258
- return new CalcitMap(zs);
259
- }
339
+ diffNew(ys: CalcitSliceMap | CalcitMap): CalcitMap {
340
+ return this.turnMap().diffNew(ys);
260
341
  }
261
342
 
262
343
  /** TODO implement diff with low level code, opens opportunity for future optimizations */
263
- diffKeys(ys: CalcitMap): CalcitSet {
344
+ diffKeys(ys: CalcitMap | CalcitSliceMap): CalcitSet {
264
345
  let ret: Array<CalcitValue> = [];
265
346
  let ks = this.keysArray();
266
347
  for (let i = 0; i < ks.length; i++) {
@@ -273,7 +354,7 @@ export class CalcitMap {
273
354
  }
274
355
 
275
356
  /** TODO implement diff with low level code, opens opportunity for future optimizations */
276
- commonKeys(ys: CalcitMap): CalcitSet {
357
+ commonKeys(ys: CalcitMap | CalcitSliceMap): CalcitSet {
277
358
  let ret: Array<CalcitValue> = [];
278
359
  let ks = this.keysArray();
279
360
  for (let i = 0; i < ks.length; i++) {
@@ -1,7 +1,7 @@
1
- import { CalcitKeyword, CalcitSymbol as CalcitSymbol, CalcitRef, CalcitFn, CalcitRecur } from "./calcit-data";
2
- import { CalcitList } from "./js-list";
1
+ import { CalcitKeyword, CalcitSymbol, CalcitRef, CalcitFn, CalcitRecur } from "./calcit-data";
2
+ import { CalcitList, CalcitSliceList } from "./js-list";
3
3
  import { CalcitRecord } from "./js-record";
4
- import { CalcitMap } from "./js-map";
4
+ import { CalcitMap, CalcitSliceMap } from "./js-map";
5
5
  import { CalcitSet as CalcitSet } from "./js-set";
6
6
  import { CalcitTuple } from "./js-tuple";
7
7
 
@@ -10,7 +10,9 @@ export type CalcitValue =
10
10
  | number
11
11
  | boolean
12
12
  | CalcitMap
13
+ | CalcitSliceMap
13
14
  | CalcitList
15
+ | CalcitSliceList
14
16
  | CalcitSet
15
17
  | CalcitKeyword
16
18
  | CalcitSymbol
@@ -2,7 +2,7 @@ import { initTernaryTreeMap, Hash, insert } from "@calcit/ternary-tree";
2
2
  import { CalcitValue } from "./js-primes";
3
3
  import { kwd, castKwd, toString, CalcitKeyword, getStringName, findInFields } from "./calcit-data";
4
4
 
5
- import { CalcitMap } from "./js-map";
5
+ import { CalcitMap, CalcitSliceMap } from "./js-map";
6
6
 
7
7
  export class CalcitRecord {
8
8
  name: CalcitKeyword;
@@ -11,7 +11,7 @@ export class CalcitRecord {
11
11
  cachedHash: Hash;
12
12
  constructor(name: CalcitKeyword, fields: Array<CalcitKeyword>, values?: Array<CalcitValue>) {
13
13
  this.name = name;
14
- let fieldNames = fields.map(getStringName).map(kwd);
14
+ let fieldNames = fields.map(castKwd);
15
15
  this.fields = fields;
16
16
  if (values != null) {
17
17
  if (values.length !== fields.length) {
@@ -152,7 +152,7 @@ export let _$n_record_$o_from_map = (proto: CalcitValue, data: CalcitValue): Cal
152
152
  }
153
153
  return new CalcitRecord(proto.name, proto.fields, values);
154
154
  }
155
- } else if (data instanceof CalcitMap) {
155
+ } else if (data instanceof CalcitMap || data instanceof CalcitSliceMap) {
156
156
  let pairs: Array<[CalcitKeyword, CalcitValue]> = [];
157
157
  for (let [k, v] of data.pairs()) {
158
158
  pairs.push([castKwd(k), v]);
@@ -179,11 +179,11 @@ export let _$n_record_$o_from_map = (proto: CalcitValue, data: CalcitValue): Cal
179
179
 
180
180
  export let _$n_record_$o_to_map = (x: CalcitValue): CalcitValue => {
181
181
  if (x instanceof CalcitRecord) {
182
- var dict: Array<[CalcitValue, CalcitValue]> = [];
182
+ var dict: Array<CalcitValue> = [];
183
183
  for (let idx = 0; idx < x.fields.length; idx++) {
184
- dict.push([x.fields[idx], x.values[idx]]);
184
+ dict.push(x.fields[idx], x.values[idx]);
185
185
  }
186
- return new CalcitMap(initTernaryTreeMap(dict));
186
+ return new CalcitSliceMap(dict);
187
187
  } else {
188
188
  throw new Error("Expected record");
189
189
  }
package/ts-src/js-set.ts CHANGED
@@ -1,6 +1,19 @@
1
1
  import { CalcitValue } from "./js-primes";
2
2
  import { toString } from "./calcit-data";
3
- import { TernaryTreeMap, initTernaryTreeMap, mapLen, assocMap, dissocMap, isMapEmpty, Hash, toPairsArray, mapGetDefault, contains } from "@calcit/ternary-tree";
3
+ import {
4
+ TernaryTreeMap,
5
+ initTernaryTreeMap,
6
+ mapLen,
7
+ assocMap,
8
+ dissocMap,
9
+ isMapEmpty,
10
+ Hash,
11
+ toPairsArray,
12
+ mapGetDefault,
13
+ contains,
14
+ initTernaryTreeMapFromArray,
15
+ initEmptyTernaryTreeMap,
16
+ } from "@calcit/ternary-tree";
4
17
  import * as ternaryTree from "@calcit/ternary-tree";
5
18
 
6
19
  /** need to compare by Calcit */
@@ -28,7 +41,7 @@ export class CalcitSet {
28
41
  }
29
42
  pairs.push([value[idx], true]);
30
43
  }
31
- this.value = initTernaryTreeMap(pairs);
44
+ this.value = initTernaryTreeMapFromArray(pairs);
32
45
  } else {
33
46
  this.value = value;
34
47
  }
@@ -65,7 +78,7 @@ export class CalcitSet {
65
78
  return new CalcitSet(result);
66
79
  }
67
80
  intersection(ys: CalcitSet): CalcitSet {
68
- let result: TernaryTreeMap<CalcitValue, boolean> = initTernaryTreeMap([]);
81
+ let result: TernaryTreeMap<CalcitValue, boolean> = initEmptyTernaryTreeMap();
69
82
  for (let k of ternaryTree.toKeys(this.value)) {
70
83
  if (ys.contains(k)) {
71
84
  result = assocMap(result, k, true);
@@ -77,14 +90,14 @@ export class CalcitSet {
77
90
  first(): CalcitValue {
78
91
  // rather suspicious solution since set has no logical order
79
92
 
80
- if (mapLen(this.value) == 0) {
93
+ if (mapLen(this.value) === 0) {
81
94
  return null;
82
95
  }
83
96
 
84
97
  return toPairsArray(this.value)[0][0];
85
98
  }
86
99
  rest(): CalcitSet {
87
- if (mapLen(this.value) == 0) {
100
+ if (mapLen(this.value) === 0) {
88
101
  return null;
89
102
  }
90
103
  let x0 = this.first();
@@ -12,18 +12,18 @@ export class CalcitTuple {
12
12
  this.cachedHash = null;
13
13
  }
14
14
  get(n: number) {
15
- if (n == 0) {
15
+ if (n === 0) {
16
16
  return this.fst;
17
- } else if (n == 1) {
17
+ } else if (n === 1) {
18
18
  return this.snd;
19
19
  } else {
20
20
  throw new Error("Tuple only have 2 elements");
21
21
  }
22
22
  }
23
23
  assoc(n: number, v: CalcitValue) {
24
- if (n == 0) {
24
+ if (n === 0) {
25
25
  return new CalcitTuple(v, this.snd);
26
- } else if (n == 1) {
26
+ } else if (n === 1) {
27
27
  return new CalcitTuple(this.fst, v);
28
28
  } else {
29
29
  throw new Error("Tuple only have 2 elements");