@calcit/procs 0.5.0-a9 → 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/lib/js-map.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as ternaryTree from "@calcit/ternary-tree";
2
2
  import "./js-primes";
3
3
  import { CalcitSet } from "./js-set";
4
- import { initTernaryTreeMap, mapLen, assocMap, dissocMap, isMapEmpty, toPairsArray, mapGetDefault } from "@calcit/ternary-tree";
4
+ import { mapLen, assocMap, dissocMap, isMapEmpty, toPairsArray, mapGetDefault, initEmptyTernaryTreeMap, initTernaryTreeMapFromArray, } from "@calcit/ternary-tree";
5
5
  import { isNestedCalcitData, tipNestedCalcitData, toString } from "./calcit-data";
6
6
  /** need to compare by Calcit */
7
7
  let DATA_EQUAL = (x, y) => {
@@ -15,60 +15,189 @@ let fakeUniqueSymbol = [];
15
15
  export class CalcitMap {
16
16
  constructor(value) {
17
17
  if (value == null) {
18
- this.arrayMode = true;
19
- this.arrayValue = [];
20
- }
21
- else if (Array.isArray(value)) {
22
- this.arrayMode = true;
23
- this.arrayValue = value;
18
+ this.value = initEmptyTernaryTreeMap();
24
19
  }
25
20
  else {
26
- this.arrayMode = false;
27
21
  this.value = value;
28
22
  }
29
23
  }
30
- turnMap() {
31
- if (this.arrayMode) {
32
- var dict = [];
33
- let halfLength = this.arrayValue.length >> 1;
34
- for (let idx = 0; idx < halfLength; idx++) {
35
- dict.push([this.arrayValue[idx << 1], this.arrayValue[(idx << 1) + 1]]);
24
+ len() {
25
+ return mapLen(this.value);
26
+ }
27
+ get(k) {
28
+ return mapGetDefault(this.value, k, null);
29
+ }
30
+ assoc(...args) {
31
+ if (args.length % 2 !== 0)
32
+ throw new Error("expected even arguments");
33
+ let size = Math.floor(args.length / 2);
34
+ let result = this.value;
35
+ for (let idx = 0; idx < size; idx++) {
36
+ let k = args[idx << 1];
37
+ let v = args[(idx << 1) + 1];
38
+ result = assocMap(result, k, v);
39
+ }
40
+ return new CalcitMap(result);
41
+ }
42
+ dissoc(...args) {
43
+ let ret = this.value;
44
+ for (let idx = 0; idx < args.length; idx++) {
45
+ ret = dissocMap(ret, args[idx]);
46
+ }
47
+ return new CalcitMap(ret);
48
+ }
49
+ toString(shorter = false) {
50
+ let itemsCode = "";
51
+ for (let [k, v] of this.pairs()) {
52
+ if (shorter) {
53
+ let keyPart = isNestedCalcitData(k) ? tipNestedCalcitData(k) : toString(k, true);
54
+ let valuePart = isNestedCalcitData(v) ? tipNestedCalcitData(v) : toString(v, true);
55
+ itemsCode = `${itemsCode} (${keyPart} ${valuePart})`;
56
+ }
57
+ else {
58
+ itemsCode = `${itemsCode} (${toString(k, true)} ${toString(v, true)})`;
36
59
  }
37
- this.value = initTernaryTreeMap(dict);
38
- this.arrayMode = false;
39
- this.arrayValue = null;
40
60
  }
61
+ return `({}${itemsCode})`;
41
62
  }
42
- len() {
43
- if (this.arrayMode) {
44
- return this.arrayValue.length >> 1;
63
+ isEmpty() {
64
+ return isMapEmpty(this.value);
65
+ }
66
+ pairs() {
67
+ return toPairsArray(this.value);
68
+ }
69
+ keysArray() {
70
+ return [...ternaryTree.toKeys(this.value)];
71
+ }
72
+ contains(k) {
73
+ return ternaryTree.contains(this.value, k);
74
+ }
75
+ merge(ys) {
76
+ return this.mergeSkip(ys, fakeUniqueSymbol);
77
+ }
78
+ mergeSkip(ys, v) {
79
+ if (ys == null) {
80
+ return this;
81
+ }
82
+ if (!(ys instanceof CalcitMap || ys instanceof CalcitSliceMap)) {
83
+ console.error("value:", v);
84
+ throw new Error("Expected map to merge");
85
+ }
86
+ if (ys instanceof CalcitSliceMap) {
87
+ let ret = this.value;
88
+ let size = ys.chunk.length >> 1;
89
+ for (let i = 0; i < size; i++) {
90
+ let pos = i << 1;
91
+ if (ys.chunk[pos + 1] === v) {
92
+ continue;
93
+ }
94
+ ret = assocMap(ret, ys.chunk[pos], ys.chunk[pos + 1]);
95
+ }
96
+ return new CalcitMap(ret);
97
+ }
98
+ else {
99
+ return new CalcitMap(ternaryTree.mergeSkip(this.value, ys.value, v));
100
+ }
101
+ }
102
+ /** TODO implement diff with low level code, opens opportunity for future optimizations */
103
+ diffNew(ys) {
104
+ let zs = this.value;
105
+ if (ys instanceof CalcitSliceMap) {
106
+ let size = ys.chunk.length >> 1;
107
+ for (let i = 0; i < size; i++) {
108
+ let pos = i << 1;
109
+ let k = ys.chunk[pos];
110
+ if (ternaryTree.contains(zs, k)) {
111
+ zs = ternaryTree.dissocMap(zs, k);
112
+ }
113
+ }
114
+ return new CalcitMap(zs);
115
+ }
116
+ else if (ys instanceof CalcitMap) {
117
+ let ysKeys = ys.keysArray();
118
+ for (let i = 0; i < ysKeys.length; i++) {
119
+ let k = ysKeys[i];
120
+ if (ternaryTree.contains(zs, k)) {
121
+ zs = ternaryTree.dissocMap(zs, k);
122
+ }
123
+ }
124
+ return new CalcitMap(zs);
45
125
  }
46
126
  else {
47
- return mapLen(this.value);
127
+ throw new Error("unknown data to diff");
48
128
  }
49
129
  }
130
+ /** TODO implement diff with low level code, opens opportunity for future optimizations */
131
+ diffKeys(ys) {
132
+ let ret = [];
133
+ let ks = this.keysArray();
134
+ for (let i = 0; i < ks.length; i++) {
135
+ let k = ks[i];
136
+ if (!ys.contains(k)) {
137
+ ret.push(k);
138
+ }
139
+ }
140
+ return new CalcitSet(ret);
141
+ }
142
+ /** TODO implement diff with low level code, opens opportunity for future optimizations */
143
+ commonKeys(ys) {
144
+ let ret = [];
145
+ let ks = this.keysArray();
146
+ for (let i = 0; i < ks.length; i++) {
147
+ let k = ks[i];
148
+ if (ys.contains(k)) {
149
+ ret.push(k);
150
+ }
151
+ }
152
+ return new CalcitSet(ret);
153
+ }
154
+ }
155
+ // store small map in linear array to reduce cost of building tree
156
+ export class CalcitSliceMap {
157
+ constructor(value) {
158
+ if (value == null) {
159
+ this.chunk = [];
160
+ }
161
+ else if (Array.isArray(value)) {
162
+ this.chunk = value;
163
+ }
164
+ else {
165
+ throw new Error("unknown data for map");
166
+ }
167
+ }
168
+ turnMap() {
169
+ var dict = [];
170
+ let halfLength = this.chunk.length >> 1;
171
+ for (let idx = 0; idx < halfLength; idx++) {
172
+ dict.push([this.chunk[idx << 1], this.chunk[(idx << 1) + 1]]);
173
+ }
174
+ let value = initTernaryTreeMapFromArray(dict);
175
+ return new CalcitMap(value);
176
+ }
177
+ len() {
178
+ return this.chunk.length >> 1;
179
+ }
50
180
  get(k) {
51
- if (this.arrayMode && this.arrayValue.length <= 16) {
52
- let size = this.arrayValue.length >> 1;
181
+ if (this.chunk.length <= 16) {
182
+ let size = this.chunk.length >> 1;
53
183
  for (let i = 0; i < size; i++) {
54
184
  let pos = i << 1;
55
- if (DATA_EQUAL(this.arrayValue[pos], k)) {
56
- return this.arrayValue[pos + 1];
185
+ if (DATA_EQUAL(this.chunk[pos], k)) {
186
+ return this.chunk[pos + 1];
57
187
  }
58
188
  }
59
189
  return null;
60
190
  }
61
191
  else {
62
- this.turnMap();
63
- return mapGetDefault(this.value, k, null);
192
+ return this.turnMap().get(k);
64
193
  }
65
194
  }
66
195
  assoc(...args) {
67
196
  if (args.length % 2 !== 0)
68
197
  throw new Error("expected even arguments");
69
198
  let size = Math.floor(args.length / 2);
70
- if (this.arrayMode && this.arrayValue.length <= 16) {
71
- let ret = this.arrayValue.slice(0);
199
+ if (this.chunk.length <= 16) {
200
+ let ret = this.chunk.slice(0);
72
201
  outer: for (let j = 0; j < size; j++) {
73
202
  let k = args[j << 1];
74
203
  let v = args[(j << 1) + 1];
@@ -80,40 +209,28 @@ export class CalcitMap {
80
209
  }
81
210
  ret.push(k, v);
82
211
  }
83
- return new CalcitMap(ret);
212
+ return new CalcitSliceMap(ret);
84
213
  }
85
214
  else {
86
- this.turnMap();
87
- let result = this.value;
88
- for (let idx = 0; idx < size; idx++) {
89
- let k = args[idx << 1];
90
- let v = args[(idx << 1) + 1];
91
- result = assocMap(result, k, v);
92
- }
93
- return new CalcitMap(result);
215
+ return this.turnMap().assoc(...args);
94
216
  }
95
217
  }
96
218
  dissoc(...args) {
97
- if (this.arrayMode && this.arrayValue.length <= 16) {
219
+ if (this.chunk.length <= 16) {
98
220
  let ret = [];
99
- outer: for (let i = 0; i < this.arrayValue.length; i += 2) {
221
+ outer: for (let i = 0; i < this.chunk.length; i += 2) {
100
222
  for (let j = 0; j < args.length; j++) {
101
223
  let k = args[j];
102
- if (DATA_EQUAL(k, this.arrayValue[i])) {
224
+ if (DATA_EQUAL(k, this.chunk[i])) {
103
225
  continue outer;
104
226
  }
105
227
  }
106
- ret.push(this.arrayValue[i], this.arrayValue[i + 1]);
228
+ ret.push(this.chunk[i], this.chunk[i + 1]);
107
229
  }
108
- return new CalcitMap(ret);
230
+ return new CalcitSliceMap(ret);
109
231
  }
110
232
  else {
111
- this.turnMap();
112
- let ret = this.value;
113
- for (let idx = 0; idx < args.length; idx++) {
114
- ret = dissocMap(ret, args[idx]);
115
- }
116
- return new CalcitMap(ret);
233
+ return this.turnMap().dissoc(...args);
117
234
  }
118
235
  }
119
236
  toString(shorter = false) {
@@ -131,56 +248,40 @@ export class CalcitMap {
131
248
  return `({}${itemsCode})`;
132
249
  }
133
250
  isEmpty() {
134
- if (this.arrayMode) {
135
- return this.arrayValue.length === 0;
136
- }
137
- else {
138
- return isMapEmpty(this.value);
139
- }
251
+ return this.chunk.length === 0;
140
252
  }
141
253
  pairs() {
142
- if (this.arrayMode) {
143
- let ret = [];
144
- let size = this.arrayValue.length >> 1;
145
- for (let i = 0; i < size; i++) {
146
- let pos = i << 1;
147
- ret.push([this.arrayValue[pos], this.arrayValue[pos + 1]]);
148
- }
149
- return ret;
150
- }
151
- else {
152
- return toPairsArray(this.value);
254
+ let ret = [];
255
+ let size = this.chunk.length >> 1;
256
+ for (let i = 0; i < size; i++) {
257
+ let pos = i << 1;
258
+ ret.push([this.chunk[pos], this.chunk[pos + 1]]);
153
259
  }
260
+ return ret;
154
261
  }
155
262
  keysArray() {
156
- if (this.arrayMode) {
157
- let ret = [];
158
- let size = this.arrayValue.length >> 1;
159
- for (let i = 0; i < size; i++) {
160
- let pos = i << 1;
161
- ret.push(this.arrayValue[pos]);
162
- }
163
- return ret;
164
- }
165
- else {
166
- return [...ternaryTree.toKeys(this.value)];
263
+ let ret = [];
264
+ let size = this.chunk.length >> 1;
265
+ for (let i = 0; i < size; i++) {
266
+ let pos = i << 1;
267
+ ret.push(this.chunk[pos]);
167
268
  }
269
+ return ret;
168
270
  }
169
271
  contains(k) {
170
- if (this.arrayMode && this.arrayValue.length <= 16) {
272
+ if (this.chunk.length <= 16) {
171
273
  // guessed number
172
- let size = this.arrayValue.length >> 1;
274
+ let size = this.chunk.length >> 1;
173
275
  for (let i = 0; i < size; i++) {
174
276
  let pos = i << 1;
175
- if (DATA_EQUAL(this.arrayValue[pos], k)) {
277
+ if (DATA_EQUAL(this.chunk[pos], k)) {
176
278
  return true;
177
279
  }
178
280
  }
179
281
  return false;
180
282
  }
181
283
  else {
182
- this.turnMap();
183
- return ternaryTree.contains(this.value, k);
284
+ return this.turnMap().contains(k);
184
285
  }
185
286
  }
186
287
  merge(ys) {
@@ -190,69 +291,32 @@ export class CalcitMap {
190
291
  if (ys == null) {
191
292
  return this;
192
293
  }
193
- if (!(ys instanceof CalcitMap)) {
294
+ if (!(ys instanceof CalcitMap || ys instanceof CalcitSliceMap)) {
194
295
  console.error("value:", v);
195
296
  throw new Error("Expected map to merge");
196
297
  }
197
- if (this.arrayMode && ys.arrayMode && this.arrayValue.length + ys.arrayValue.length <= 24) {
298
+ if (ys instanceof CalcitSliceMap && this.chunk.length + ys.len() <= 24) {
198
299
  // probably this length < 16, ys length < 8
199
- let ret = this.arrayValue.slice(0);
200
- outer: for (let i = 0; i < ys.arrayValue.length; i = i + 2) {
201
- if (ys.arrayValue[i + 1] === v) {
300
+ let ret = this.chunk.slice(0);
301
+ outer: for (let i = 0; i < ys.chunk.length; i = i + 2) {
302
+ if (ys.chunk[i + 1] === v) {
202
303
  continue;
203
304
  }
204
305
  for (let k = 0; k < ret.length; k = k + 2) {
205
- if (DATA_EQUAL(ys.arrayValue[i], ret[k])) {
206
- ret[k + 1] = ys.arrayValue[i + 1];
306
+ if (DATA_EQUAL(ys.chunk[i], ret[k])) {
307
+ ret[k + 1] = ys.chunk[i + 1];
207
308
  continue outer;
208
309
  }
209
310
  }
210
- ret.push(ys.arrayValue[i], ys.arrayValue[i + 1]);
311
+ ret.push(ys.chunk[i], ys.chunk[i + 1]);
211
312
  }
212
- return new CalcitMap(ret);
213
- }
214
- this.turnMap();
215
- if (ys.arrayMode) {
216
- let ret = this.value;
217
- let size = ys.arrayValue.length >> 1;
218
- for (let i = 0; i < size; i++) {
219
- let pos = i << 1;
220
- if (ys.arrayValue[pos + 1] === v) {
221
- continue;
222
- }
223
- ret = assocMap(ret, ys.arrayValue[pos], ys.arrayValue[pos + 1]);
224
- }
225
- return new CalcitMap(ret);
226
- }
227
- else {
228
- return new CalcitMap(ternaryTree.mergeSkip(this.value, ys.value, v));
313
+ return new CalcitSliceMap(ret);
229
314
  }
315
+ return this.turnMap().mergeSkip(ys, v);
230
316
  }
231
317
  /** TODO implement diff with low level code, opens opportunity for future optimizations */
232
318
  diffNew(ys) {
233
- this.turnMap();
234
- let zs = this.value;
235
- if (ys.arrayMode) {
236
- let size = ys.arrayValue.length >> 1;
237
- for (let i = 0; i < size; i++) {
238
- let pos = i << 1;
239
- let k = ys.arrayValue[pos];
240
- if (ternaryTree.contains(zs, k)) {
241
- zs = ternaryTree.dissocMap(zs, k);
242
- }
243
- }
244
- return new CalcitMap(zs);
245
- }
246
- else {
247
- let ysKeys = ys.keysArray();
248
- for (let i = 0; i < ysKeys.length; i++) {
249
- let k = ysKeys[i];
250
- if (ternaryTree.contains(zs, k)) {
251
- zs = ternaryTree.dissocMap(zs, k);
252
- }
253
- }
254
- return new CalcitMap(zs);
255
- }
319
+ return this.turnMap().diffNew(ys);
256
320
  }
257
321
  /** TODO implement diff with low level code, opens opportunity for future optimizations */
258
322
  diffKeys(ys) {
package/lib/js-record.js CHANGED
@@ -1,11 +1,11 @@
1
- import { initTernaryTreeMap } from "@calcit/ternary-tree";
1
+ import "@calcit/ternary-tree";
2
2
  import "./js-primes";
3
- import { kwd, castKwd, toString, getStringName, findInFields } from "./calcit-data";
4
- import { CalcitMap } from "./js-map";
3
+ import { castKwd, toString, findInFields } from "./calcit-data";
4
+ import { CalcitMap, CalcitSliceMap } from "./js-map";
5
5
  export class CalcitRecord {
6
6
  constructor(name, fields, values) {
7
7
  this.name = name;
8
- let fieldNames = fields.map(getStringName).map(kwd);
8
+ let fieldNames = fields.map(castKwd);
9
9
  this.fields = fields;
10
10
  if (values != null) {
11
11
  if (values.length !== fields.length) {
@@ -146,7 +146,7 @@ export let _$n_record_$o_from_map = (proto, data) => {
146
146
  return new CalcitRecord(proto.name, proto.fields, values);
147
147
  }
148
148
  }
149
- else if (data instanceof CalcitMap) {
149
+ else if (data instanceof CalcitMap || data instanceof CalcitSliceMap) {
150
150
  let pairs = [];
151
151
  for (let [k, v] of data.pairs()) {
152
152
  pairs.push([castKwd(k), v]);
@@ -174,9 +174,9 @@ export let _$n_record_$o_to_map = (x) => {
174
174
  if (x instanceof CalcitRecord) {
175
175
  var dict = [];
176
176
  for (let idx = 0; idx < x.fields.length; idx++) {
177
- dict.push([x.fields[idx], x.values[idx]]);
177
+ dict.push(x.fields[idx], x.values[idx]);
178
178
  }
179
- return new CalcitMap(initTernaryTreeMap(dict));
179
+ return new CalcitSliceMap(dict);
180
180
  }
181
181
  else {
182
182
  throw new Error("Expected record");
package/lib/js-set.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "./js-primes";
2
2
  import { toString } from "./calcit-data";
3
- import { initTernaryTreeMap, mapLen, assocMap, dissocMap, toPairsArray, contains } from "@calcit/ternary-tree";
3
+ import { mapLen, assocMap, dissocMap, toPairsArray, contains, initTernaryTreeMapFromArray, initEmptyTernaryTreeMap, } from "@calcit/ternary-tree";
4
4
  import * as ternaryTree from "@calcit/ternary-tree";
5
5
  /** need to compare by Calcit */
6
6
  let DATA_EQUAL = (x, y) => {
@@ -23,7 +23,7 @@ export class CalcitSet {
23
23
  }
24
24
  pairs.push([value[idx], true]);
25
25
  }
26
- this.value = initTernaryTreeMap(pairs);
26
+ this.value = initTernaryTreeMapFromArray(pairs);
27
27
  }
28
28
  else {
29
29
  this.value = value;
@@ -60,7 +60,7 @@ export class CalcitSet {
60
60
  return new CalcitSet(result);
61
61
  }
62
62
  intersection(ys) {
63
- let result = initTernaryTreeMap([]);
63
+ let result = initEmptyTernaryTreeMap();
64
64
  for (let k of ternaryTree.toKeys(this.value)) {
65
65
  if (ys.contains(k)) {
66
66
  result = assocMap(result, k, true);
@@ -70,13 +70,13 @@ export class CalcitSet {
70
70
  }
71
71
  first() {
72
72
  // rather suspicious solution since set has no logical order
73
- if (mapLen(this.value) == 0) {
73
+ if (mapLen(this.value) === 0) {
74
74
  return null;
75
75
  }
76
76
  return toPairsArray(this.value)[0][0];
77
77
  }
78
78
  rest() {
79
- if (mapLen(this.value) == 0) {
79
+ if (mapLen(this.value) === 0) {
80
80
  return null;
81
81
  }
82
82
  let x0 = this.first();
package/lib/js-tuple.js CHANGED
@@ -7,10 +7,10 @@ export class CalcitTuple {
7
7
  this.cachedHash = null;
8
8
  }
9
9
  get(n) {
10
- if (n == 0) {
10
+ if (n === 0) {
11
11
  return this.fst;
12
12
  }
13
- else if (n == 1) {
13
+ else if (n === 1) {
14
14
  return this.snd;
15
15
  }
16
16
  else {
@@ -18,10 +18,10 @@ export class CalcitTuple {
18
18
  }
19
19
  }
20
20
  assoc(n, v) {
21
- if (n == 0) {
21
+ if (n === 0) {
22
22
  return new CalcitTuple(v, this.snd);
23
23
  }
24
- else if (n == 1) {
24
+ else if (n === 1) {
25
25
  return new CalcitTuple(this.fst, v);
26
26
  }
27
27
  else {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.5.0-a9",
3
+ "version": "0.5.0",
4
4
  "main": "./lib/calcit.procs.js",
5
5
  "devDependencies": {
6
- "@types/node": "^16.10.5",
7
- "esbuild": "^0.13.5",
6
+ "@types/node": "^16.11.6",
7
+ "esbuild": "^0.13.12",
8
8
  "typescript": "^4.4.4"
9
9
  },
10
10
  "scripts": {
@@ -20,8 +20,8 @@
20
20
  "url": "https://github.com/calcit-lang/calcit_runner.rs"
21
21
  },
22
22
  "dependencies": {
23
- "@calcit/ternary-tree": "0.0.16",
24
- "@cirru/parser.ts": "^0.0.4",
23
+ "@calcit/ternary-tree": "0.0.18",
24
+ "@cirru/parser.ts": "^0.0.5",
25
25
  "@cirru/writer.ts": "^0.1.3"
26
26
  }
27
27
  }