@dra2020/baseclient 1.0.12 → 1.0.13

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.
Files changed (120) hide show
  1. package/package.json +16 -15
  2. package/LICENSE +0 -21
  3. package/README.md +0 -26
  4. package/dist/all/all.d.ts +0 -20
  5. package/dist/baseclient.js +0 -10113
  6. package/dist/baseclient.js.map +0 -1
  7. package/dist/context/all.d.ts +0 -1
  8. package/dist/context/context.d.ts +0 -13
  9. package/dist/filterexpr/all.d.ts +0 -1
  10. package/dist/filterexpr/filterexpr.d.ts +0 -67
  11. package/dist/fsm/all.d.ts +0 -1
  12. package/dist/fsm/fsm.d.ts +0 -119
  13. package/dist/geo/all.d.ts +0 -2
  14. package/dist/geo/geo.d.ts +0 -67
  15. package/dist/geo/vfeature.d.ts +0 -4
  16. package/dist/logabstract/all.d.ts +0 -1
  17. package/dist/logabstract/log.d.ts +0 -26
  18. package/dist/logclient/all.d.ts +0 -1
  19. package/dist/logclient/log.d.ts +0 -6
  20. package/dist/ot-editutil/all.d.ts +0 -2
  21. package/dist/ot-editutil/oteditutil.d.ts +0 -14
  22. package/dist/ot-editutil/otmaputil.d.ts +0 -21
  23. package/dist/ot-js/all.d.ts +0 -9
  24. package/dist/ot-js/otarray.d.ts +0 -111
  25. package/dist/ot-js/otclientengine.d.ts +0 -38
  26. package/dist/ot-js/otcomposite.d.ts +0 -37
  27. package/dist/ot-js/otcounter.d.ts +0 -17
  28. package/dist/ot-js/otengine.d.ts +0 -22
  29. package/dist/ot-js/otmap.d.ts +0 -19
  30. package/dist/ot-js/otserverengine.d.ts +0 -38
  31. package/dist/ot-js/otsession.d.ts +0 -114
  32. package/dist/ot-js/ottypes.d.ts +0 -29
  33. package/dist/poly/all.d.ts +0 -15
  34. package/dist/poly/blend.d.ts +0 -1
  35. package/dist/poly/boundbox.d.ts +0 -16
  36. package/dist/poly/cartesian.d.ts +0 -5
  37. package/dist/poly/graham-scan.d.ts +0 -8
  38. package/dist/poly/hash.d.ts +0 -1
  39. package/dist/poly/matrix.d.ts +0 -24
  40. package/dist/poly/minbound.d.ts +0 -1
  41. package/dist/poly/poly.d.ts +0 -52
  42. package/dist/poly/polybin.d.ts +0 -5
  43. package/dist/poly/polylabel.d.ts +0 -7
  44. package/dist/poly/polypack.d.ts +0 -30
  45. package/dist/poly/polyround.d.ts +0 -1
  46. package/dist/poly/polysimplify.d.ts +0 -1
  47. package/dist/poly/quad.d.ts +0 -48
  48. package/dist/poly/selfintersect.d.ts +0 -1
  49. package/dist/poly/shamos.d.ts +0 -1
  50. package/dist/poly/simplify.d.ts +0 -2
  51. package/dist/poly/topo.d.ts +0 -46
  52. package/dist/poly/union.d.ts +0 -49
  53. package/dist/util/all.d.ts +0 -5
  54. package/dist/util/bintrie.d.ts +0 -93
  55. package/dist/util/countedhash.d.ts +0 -19
  56. package/dist/util/gradient.d.ts +0 -15
  57. package/dist/util/indexedarray.d.ts +0 -15
  58. package/dist/util/util.d.ts +0 -68
  59. package/docs/context.md +0 -2
  60. package/docs/filterexpr.md +0 -22
  61. package/docs/fsm.md +0 -243
  62. package/docs/logabstract.md +0 -2
  63. package/docs/logclient.md +0 -2
  64. package/docs/ot-editutil.md +0 -2
  65. package/docs/ot-js.md +0 -95
  66. package/docs/poly.md +0 -103
  67. package/docs/util.md +0 -2
  68. package/lib/all/all.ts +0 -21
  69. package/lib/context/all.ts +0 -1
  70. package/lib/context/context.ts +0 -82
  71. package/lib/filterexpr/all.ts +0 -1
  72. package/lib/filterexpr/filterexpr.ts +0 -699
  73. package/lib/fsm/all.ts +0 -1
  74. package/lib/fsm/fsm.ts +0 -559
  75. package/lib/geo/all.ts +0 -2
  76. package/lib/geo/geo.ts +0 -452
  77. package/lib/geo/vfeature.ts +0 -34
  78. package/lib/logabstract/all.ts +0 -1
  79. package/lib/logabstract/log.ts +0 -55
  80. package/lib/logclient/all.ts +0 -1
  81. package/lib/logclient/log.ts +0 -105
  82. package/lib/ot-editutil/all.ts +0 -2
  83. package/lib/ot-editutil/oteditutil.ts +0 -180
  84. package/lib/ot-editutil/otmaputil.ts +0 -209
  85. package/lib/ot-js/all.ts +0 -9
  86. package/lib/ot-js/otarray.ts +0 -1168
  87. package/lib/ot-js/otclientengine.ts +0 -327
  88. package/lib/ot-js/otcomposite.ts +0 -247
  89. package/lib/ot-js/otcounter.ts +0 -145
  90. package/lib/ot-js/otengine.ts +0 -71
  91. package/lib/ot-js/otmap.ts +0 -144
  92. package/lib/ot-js/otserverengine.ts +0 -329
  93. package/lib/ot-js/otsession.ts +0 -202
  94. package/lib/ot-js/ottypes.ts +0 -98
  95. package/lib/poly/all.ts +0 -15
  96. package/lib/poly/blend.ts +0 -27
  97. package/lib/poly/boundbox.ts +0 -102
  98. package/lib/poly/cartesian.ts +0 -130
  99. package/lib/poly/graham-scan.ts +0 -401
  100. package/lib/poly/hash.ts +0 -15
  101. package/lib/poly/matrix.ts +0 -309
  102. package/lib/poly/minbound.ts +0 -211
  103. package/lib/poly/poly.ts +0 -767
  104. package/lib/poly/polybin.ts +0 -218
  105. package/lib/poly/polylabel.ts +0 -204
  106. package/lib/poly/polypack.ts +0 -468
  107. package/lib/poly/polyround.ts +0 -30
  108. package/lib/poly/polysimplify.ts +0 -24
  109. package/lib/poly/quad.ts +0 -272
  110. package/lib/poly/selfintersect.ts +0 -87
  111. package/lib/poly/shamos.ts +0 -297
  112. package/lib/poly/simplify.ts +0 -119
  113. package/lib/poly/topo.ts +0 -499
  114. package/lib/poly/union.ts +0 -388
  115. package/lib/util/all.ts +0 -5
  116. package/lib/util/bintrie.ts +0 -603
  117. package/lib/util/countedhash.ts +0 -83
  118. package/lib/util/gradient.ts +0 -108
  119. package/lib/util/indexedarray.ts +0 -80
  120. package/lib/util/util.ts +0 -695
@@ -1,603 +0,0 @@
1
- //
2
- // Packed format Trie for mapping string to string
3
- // Assumptions:
4
- // 1. Lots of duplicate prefix strings in keys (so branching in trie happens late).
5
- // 2. Lots of duplicate prefix strings in values.
6
- // 3. Lots of keys with duplicate prefix map to the same string value.
7
- // Especially good for something like our blockmapping.json file since both the keys (blockIDs)
8
- // and values (precinct IDs) have a ton of redundancy and ~250 avg keys (blockID) map to same
9
- // precinctID.
10
- // The packed structure is just read directly into memory and walked in packed format.
11
-
12
- // The structure is divided into two pieces, a node "tree" (flat n-ary trie with offsets
13
- // to next nodes) and a value table. A value is a pair of string fragment offsets.
14
- //
15
- // Main header is:
16
- // value table offset (32 bit value)
17
- // [ node table ]
18
- // [ value table ]
19
-
20
- // A tree node is:
21
- // node length / value - (length of byte and node offset table)
22
- // [ bytes ]* (padded to 4)
23
- // [ node or value offset ]* (32 bit signed values, negative values are value table refs)
24
- //
25
- // We just do a linear scan through the bytes since we assume many will only have a single child,
26
- // max ~15.
27
- // The byte array contains the next byte to match, the node offset is the respective next node.
28
- // A negative node offset is the actual value.
29
- //
30
- // A value is an entry in the value table. It is:
31
- // fragment offset 1 (from start of value table) (offset zero means null, not a legal offset)
32
- // fragment offset 2 (from start of value table)
33
- //
34
- // where a fragment is:
35
- // length (byte)
36
- // [ bytes ]*
37
- //
38
- // value table is:
39
- // number of pairs (32 bit value)
40
- // [ fragment offset pairs ]*
41
- // [ fragment values ]*
42
-
43
- export interface Coder
44
- {
45
- encoder: { encode: (s: string) => Uint8Array };
46
- decoder: { decode: (u8: Uint8Array) => string };
47
- }
48
-
49
- /*
50
- -- For Node
51
- import * as u from 'util';
52
- Util.setCoder({ encoder: new u.TextEncoder(), decoder: new u.TextDecoder('utf-8') });
53
-
54
- -- For Browser
55
- Util.setCoder({ encoder: new TextEncoder(), decoder: new TextDecoder('utf-8') });
56
- */
57
-
58
- export function s2u8(coder: Coder, s: string): Uint8Array
59
- {
60
- return coder.encoder.encode(s);
61
- }
62
-
63
- export function u82s(coder: Coder, u8: Uint8Array, offset: number, n: number): string
64
- {
65
- return coder.decoder.decode(u8.subarray(offset, offset+n));
66
- }
67
-
68
- // String table algorithm:
69
- // For each string, divide into fragments of n to 3 bytes
70
- // Allocate an occurence for each fragment.
71
- // Sort the fragments by number of occurrences.
72
- // For each string, pick fragmentation that maximizes occurrence count and mark
73
- // fragmentation as "in use"
74
-
75
- interface Fragment
76
- {
77
- count: number;
78
- used: number;
79
- offset: number;
80
- s: string;
81
- u8?: Uint8Array;
82
- }
83
-
84
- type FragmentTable = { [frag: string]: Fragment };
85
- type FragmentPair = { f1: Fragment, f2: Fragment, offset?: number };
86
- const NullFragment = { count: 0, used: 0, offset: 0, s: '' };
87
-
88
- function sortBestPair(p1: FragmentPair, p2: FragmentPair): number
89
- {
90
- let d = (p1.f1.count+p1.f2.count) - (p2.f1.count+p2.f2.count);
91
- if (d) return d;
92
- d = (p1.f1.used + p1.f2.used) - (p2.f1.used+p2.f2.used);
93
- return d;
94
- }
95
-
96
- function unique(a: string[]): string[]
97
- {
98
- a = a.slice().sort();
99
- return a.filter((s: string, i: number) => { return i == 0 || s !== a[i-1] });
100
- }
101
-
102
- class ValueTable
103
- {
104
- coder: Coder;
105
- ab: ArrayBuffer;
106
- u8: Uint8Array;
107
- u32: Uint32Array;
108
-
109
- constructor(coder: Coder) { this.coder = coder }
110
-
111
- static fromBuffer(coder: Coder, ab: ArrayBuffer, offset: number, length: number): ValueTable
112
- {
113
- let vt = new ValueTable(coder);
114
- vt.ab = ab;
115
- vt.u8 = new Uint8Array(ab, offset, length);
116
- let u32 = new Uint32Array(ab, offset, 1);
117
- let n = u32[0];
118
- vt.u32 = new Uint32Array(ab, offset, 1+2*n);
119
- return vt;
120
- }
121
-
122
- // Returns string given offset into value table
123
- fromOffset(offset: number): string
124
- {
125
- let o1 = this.u32[offset];
126
- let o2 = this.u32[offset+1];
127
- let n = 0;
128
- if (o1) n += this.u8[o1];
129
- if (o2) n += this.u8[o2];
130
- let ab = new ArrayBuffer(n);
131
- let u8 = new Uint8Array(ab);
132
- n = this.u8[o1];
133
- let j = 0;
134
- while (j < n) u8[j++] = this.u8[++o1];
135
- n = this.u8[o2];
136
- let k = 0;
137
- while (k < n) k++, u8[j++] = this.u8[++o2];
138
- return u82s(this.coder, u8, 0, j);
139
- }
140
- }
141
-
142
- class ValueTableBuilder
143
- {
144
- coder: Coder;
145
- values: string[];
146
- fragments: FragmentTable;
147
- pairs: { [value: string]: FragmentPair };
148
- ab: ArrayBuffer;
149
- u8: Uint8Array;
150
- u32: Uint32Array;
151
-
152
- constructor(coder: Coder) { this.coder = coder }
153
-
154
- // Building
155
- static fromStrings(coder: Coder, values: string[]): ValueTableBuilder
156
- {
157
- let nc = 0;
158
- values.forEach(s => nc += s.length);
159
- //console.log(`bintrie: ValueTable: ${values.length} initial values, ${nc} initial char count`);
160
- values = unique(values);
161
- //console.log(`bintrie: ValueTable: ${values.length} unique values`);
162
- let vtb = new ValueTableBuilder(coder);
163
- vtb.values = values;
164
- vtb.fragments = {};
165
- vtb.pairs = {};
166
- values.forEach(s => vtb.extractFragments(s));
167
- values.forEach(s => vtb.pickFragments(s));
168
- //console.log(`bintrie: ValueTable: ${Object.keys(vtb.fragments).length} initial fragments`);
169
- Object.keys(vtb.fragments).forEach(s => { if (! vtb.fragments[s].used) delete vtb.fragments[s] });
170
- //console.log(`bintrie: ValueTable: ${Object.keys(vtb.fragments).length} final fragments`);
171
- vtb.toBinary();
172
- vtb.validateStrings(values);
173
- //console.log(`bintrie: ValueTable: ${vtb.u8.length} final byte length`);
174
- return vtb;
175
- }
176
-
177
- // Validation
178
- validateStrings(values: string[]): void
179
- {
180
- let vt = ValueTable.fromBuffer(this.coder, this.ab, 0, this.ab.byteLength);
181
- let orig = values.slice().sort();
182
- let here: string[] = [];
183
- let n = this.u32[0];
184
- for (let i = 0; i < n; i++)
185
- here.push(vt.fromOffset(i*2+1));
186
- here.sort();
187
- for (let i = 0; i < here.length; i++)
188
- if (orig[i] !== here[i])
189
- {
190
- console.error('ValueTable: content mismatch');
191
- break;
192
- }
193
- }
194
-
195
- // Building
196
- addFragment(s: string): void
197
- {
198
- let f = this.fragments[s];
199
- if (f === undefined)
200
- f = { count: 0, used: 0, s: s, offset: 0, u8: s2u8(this.coder, s) }, this.fragments[s] = f;
201
- f.count++;
202
- }
203
-
204
- // Building
205
- extractFragments(s: string): void
206
- {
207
- let n = s.length;
208
- if (n < 6)
209
- this.addFragment(s);
210
- else
211
- for (let j = 3; j < n-2; j++)
212
- {
213
- this.addFragment(s.substring(0, j));
214
- this.addFragment(s.substring(j));
215
- }
216
- }
217
-
218
- // Building
219
- pickFragments(s: string): void
220
- {
221
- let a: { f1: Fragment, f2: Fragment }[] = [];
222
- let n = s.length;
223
- if (n < 6)
224
- a.push({ f1: this.fragments[s], f2: NullFragment });
225
- else
226
- for (let j = 3; j < n-2; j++)
227
- a.push({ f1: this.fragments[s.substring(0, j)], f2: this.fragments[s.substring(j)] });
228
- a.sort(sortBestPair);
229
- let p = a[0];
230
- p.f1.used = 1;
231
- p.f2.used = 1;
232
- this.pairs[s] = p;
233
- }
234
-
235
- // Building
236
- toOffset(s: string): number
237
- {
238
- return this.pairs[s].offset;
239
- }
240
-
241
- // Building
242
- toBinary(): void
243
- {
244
- let byteLength = 0;
245
- byteLength += (this.values.length * 2 * 4) + 4;
246
- let keys = Object.keys(this.fragments);
247
- keys.forEach(s => {
248
- let f = this.fragments[s];
249
- f.offset = byteLength;
250
- byteLength += f.u8.byteLength + 1;
251
- });
252
- this.ab = new ArrayBuffer(byteLength);
253
- this.u8 = new Uint8Array(this.ab);
254
- this.u32 = new Uint32Array(this.ab, 0, this.values.length*2+1);
255
- let pOffset = 0;
256
- this.u32[pOffset++] = this.values.length;
257
- this.values.forEach(s => {
258
- let p = this.pairs[s];
259
- p.offset = pOffset;
260
- this.u32[pOffset++] = p.f1.offset;
261
- this.u32[pOffset++] = p.f2.offset;
262
- });
263
- let fOffset = (this.values.length * 2 * 4) + 4;
264
- keys.forEach(s => {
265
- let f = this.fragments[s];
266
- this.u8[fOffset++] = f.u8.length;
267
- for (let i = 0; i < f.u8.length; i++)
268
- this.u8[fOffset++] = f.u8[i];
269
- });
270
- }
271
- }
272
-
273
- export type StringMap = { [key: string]: string };
274
-
275
- // Building
276
- interface UnpackedNode
277
- {
278
- // This for leaf node
279
- suffix: Uint8Array;
280
- value: number;
281
-
282
- // This for internal node
283
- bytes: number[] | null;
284
- nodes: UnpackedNode[] | null;
285
- }
286
-
287
- function pad(n: number, pad: number): number { let mod = n % pad; return mod ? pad - mod : 0; }
288
- function pad4(n: number): number { return pad(n, 4) }
289
-
290
- export class BinTrie
291
- {
292
- coder: Coder;
293
- ab: ArrayBuffer;
294
- vt: ValueTable;
295
- u8: Uint8Array;
296
- i32: Int32Array;
297
-
298
- constructor(coder: Coder)
299
- {
300
- this.coder = coder;
301
- }
302
-
303
- static fromBuffer(coder: Coder, ab: ArrayBuffer): BinTrie
304
- {
305
- let bt = new BinTrie(coder);
306
- bt.ab = ab;
307
- bt.u8 = new Uint8Array(bt.ab);
308
- let i32 = new Int32Array(bt.ab, 0, 1);
309
- let valueOffset = i32[0];
310
- bt.i32 = new Int32Array(bt.ab, 0, valueOffset >> 2);
311
- bt.vt = ValueTable.fromBuffer(coder, bt.ab, valueOffset, bt.u8.length - valueOffset);
312
- return bt;
313
- }
314
-
315
- get(key: string): string
316
- {
317
- let u8 = s2u8(this.coder, key);
318
- let byteOffset = 4;
319
- for (let i = 0; i <= u8.length; i++)
320
- {
321
- let iOffset = byteOffset >> 2;
322
- let n = this.i32[iOffset];
323
- if (i == u8.length)
324
- return undefined;
325
- let b = u8[i];
326
- byteOffset += 4;
327
- let j: number;
328
- for (j = 0; j < n; j++)
329
- if (this.u8[byteOffset+j] === b)
330
- {
331
- byteOffset += n + pad4(n); // move past byte table
332
- iOffset = byteOffset >> 2; // convert ioffset to that location
333
- iOffset += j; // index intoo node offset table
334
- byteOffset = this.i32[iOffset]; // and move to child node
335
- if (byteOffset < 0)
336
- return this.vt.fromOffset(-byteOffset);
337
- break;
338
- }
339
- if (j === n)
340
- return undefined;
341
- }
342
- return undefined;
343
- }
344
- }
345
-
346
- export class BinTrieBuilder
347
- {
348
- coder: Coder;
349
- root: UnpackedNode;
350
- vtb: ValueTableBuilder;
351
- vt: ValueTable;
352
- ab: ArrayBuffer;
353
- u8: Uint8Array;
354
- i32: Int32Array;
355
-
356
- constructor(coder: Coder)
357
- {
358
- this.coder = coder;
359
- }
360
-
361
- // Building
362
- nodeCount(node: UnpackedNode): number
363
- {
364
- let n = 1;
365
- if (node.nodes)
366
- node.nodes.forEach(child => n += this.nodeCount(child))
367
- return n;
368
- }
369
-
370
- // Validation
371
- nodeBranching(node: UnpackedNode, counts: number[]): number
372
- {
373
- let n = node.nodes ? node.nodes.length : 0;
374
- counts[n] = counts[n] === undefined ? 1 : counts[n]+1;
375
- if (node.nodes)
376
- node.nodes.forEach(child => n += this.nodeBranching(child, counts))
377
- return n;
378
- }
379
-
380
- // Validation
381
- nodeValueCount(node: UnpackedNode): number
382
- {
383
- let n = node.value ? 1 : 0;
384
- if (node.nodes)
385
- node.nodes.forEach(child => n += this.nodeValueCount(child))
386
- return n;
387
- }
388
-
389
- // Building
390
- nodeByteLength(node: UnpackedNode): number
391
- {
392
- let byteLength = 0; // length of child arrays
393
- if (node.nodes)
394
- {
395
- byteLength += 4; // length of child arrays
396
- byteLength += node.bytes.length + pad4(node.bytes.length);
397
- byteLength += node.nodes.length * 4;
398
- node.nodes.forEach(n => { byteLength += this.nodeByteLength(n) });
399
- }
400
- return byteLength;
401
- }
402
-
403
- // Building
404
- addString(s: string, value: number): void
405
- {
406
- let u8 = s2u8(this.coder, s);
407
- if (this.root == null)
408
- this.root = { suffix: u8, value: value, bytes: null, nodes: null };
409
- else
410
- {
411
- let node = this.root;
412
- let n = u8.length;
413
- let j = 0;
414
- while (j < n)
415
- {
416
- // If at leaf node, need to split it
417
- if (node.bytes == null)
418
- {
419
- node.bytes = [ node.suffix[0] ];
420
- node.nodes = [ { suffix: node.suffix.subarray(1), value: node.value, bytes: null, nodes: null } ];
421
- node.suffix = null;
422
- node.value = 0;
423
- }
424
-
425
- let k: number;
426
- for (k = 0; k < node.bytes.length; k++)
427
- if (node.bytes[k] == u8[j])
428
- break;
429
-
430
- if (k < node.bytes.length)
431
- {
432
- node = node.nodes[k];
433
- j++;
434
- }
435
- else
436
- {
437
- node.bytes.push(u8[j++]);
438
- let nNew: UnpackedNode = { suffix: u8.subarray(j), value: value, bytes: null, nodes: null };
439
- node.nodes.push(nNew);
440
- node = nNew;
441
- }
442
- }
443
- }
444
- }
445
-
446
- // Building
447
- dedup(node: UnpackedNode): void
448
- {
449
- // If all subnodes point to the same value, we can just turn this node into a value node
450
- if (node.nodes)
451
- {
452
- node.nodes.forEach(n => this.dedup(n));
453
- let value = node.nodes[0].value;
454
- if (value)
455
- {
456
- node.nodes.forEach(n => { if (n.value != value) value = 0 });
457
- if (value)
458
- {
459
- node.value = value;
460
- delete node.nodes;
461
- delete node.bytes;
462
- }
463
- }
464
- }
465
- }
466
-
467
- // Validation
468
- getUnpacked(key: string): string
469
- {
470
- function getFromNode(vt: ValueTable, node: UnpackedNode, u8: Uint8Array, offset: number): string
471
- {
472
- if (node.value)
473
- return vt.fromOffset(node.value);
474
- else
475
- {
476
- if (offset >= u8.length)
477
- {
478
- console.error('bintrie: failure during lookup in unpacked format');
479
- return 'undefined';
480
- }
481
- let j = node.bytes.findIndex(e => e === u8[offset]);
482
- if (j === undefined)
483
- {
484
- console.error('bintrie: failure during lookup in unpacked format');
485
- return 'undefined';
486
- }
487
- return getFromNode(vt, node.nodes[j], u8, offset+1);
488
- }
489
- }
490
-
491
- return getFromNode(this.vt, this.root, s2u8(this.coder, key), 0);
492
- }
493
-
494
- // Building
495
- packNode(node: UnpackedNode, byteOffset: number): number
496
- {
497
- if (node.nodes)
498
- {
499
- let i;
500
- let iOffset = byteOffset >> 2;
501
- this.i32[iOffset] = node.nodes.length;
502
- byteOffset += 4;
503
- for (i = 0; i < node.bytes.length; i++)
504
- this.u8[byteOffset++] = node.bytes[i];
505
- byteOffset += pad4(byteOffset);
506
- iOffset = byteOffset >> 2;
507
- byteOffset += node.nodes.length * 4;
508
- for (i = 0; i < node.nodes.length; i++)
509
- {
510
- let n = node.nodes[i];
511
- if (n.value)
512
- this.i32[iOffset++] = - n.value;
513
- else
514
- {
515
- this.i32[iOffset++] = byteOffset;
516
- byteOffset = this.packNode(n, byteOffset);
517
- }
518
- }
519
- }
520
- return byteOffset;
521
- }
522
-
523
- // Building
524
- toBinary(): void
525
- {
526
- let byteLength = 4 + this.nodeByteLength(this.root);
527
- let valueOffset = byteLength;
528
- byteLength += this.vtb.u8.length;
529
- this.ab = new ArrayBuffer(byteLength);
530
- this.u8 = new Uint8Array(this.ab);
531
- this.i32 = new Int32Array(this.ab, 0, valueOffset >> 2);
532
- this.i32[0] = valueOffset;
533
- let byteOffset = this.packNode(this.root, 4);
534
- if (byteOffset != valueOffset)
535
- throw 'unexpected result from packNode';
536
-
537
- // Now copy in ValueTable
538
- let u8 = this.vtb.u8;
539
- let n = u8.length;
540
- for (let j = 0, k = valueOffset; j < n; j++, k++)
541
- this.u8[k] = u8[j];
542
- }
543
-
544
- // Building
545
- static fromMap(coder: Coder, o: StringMap): BinTrie
546
- {
547
- let btb = new BinTrieBuilder(coder);
548
- btb.vtb = ValueTableBuilder.fromStrings(coder, Object.values(o));
549
- btb.vt = ValueTable.fromBuffer(coder, btb.vtb.ab, 0, btb.vtb.ab.byteLength);
550
- let keys = Object.keys(o);
551
- keys.forEach(s => btb.addString(s, btb.vtb.toOffset(o[s])));
552
-
553
- //console.log(`bintrie: initial node count: ${btb.nodeCount(btb.root)}`);
554
-
555
- // validate
556
- let good = true;
557
- keys.forEach(k => {
558
- if (good && btb.getUnpacked(k) !== o[k])
559
- {
560
- //console.error('bintrie: missing key in unpacked, un-deduped tree');
561
- good = false;
562
- }
563
- });
564
-
565
- // dedup (collapse branches pointing to same value)
566
- btb.dedup(btb.root);
567
-
568
- // validate
569
- keys.forEach(k => {
570
- if (good && btb.getUnpacked(k) !== o[k])
571
- {
572
- //console.error('bintrie: missing key in unpacked, deduped tree');
573
- good = false;
574
- }
575
- });
576
-
577
- //console.log(`bintrie: final node count after dedup: ${btb.nodeCount(btb.root)}`);
578
- //console.log(`bintrie: value nodes after dedup: ${btb.nodeValueCount(btb.root)}`);
579
- let counts: number[] = [];
580
- //console.log(`bintrie: singleton nodes after dedup: ${btb.nodeBranching(btb.root, counts)}`);
581
- counts.forEach((count: number, i: number) => {
582
- //if (count !== undefined)
583
- //console.log(`bintrie: branch factor: ${i}, count: ${count}`);
584
- });
585
-
586
- btb.toBinary();
587
-
588
- let bt = BinTrie.fromBuffer(coder, btb.ab);
589
-
590
- // validate
591
- keys.forEach((k: string, i: number) => {
592
- if (good && bt.get(k) !== o[k])
593
- {
594
- console.error(`bintrie: missing key (${i}th) in packed structure`);
595
- good = false;
596
- }
597
- });
598
-
599
- console.log(`bintrie: total size: ${btb.u8.length}, value table size: ${btb.vtb.u8.length}`);
600
-
601
- return bt;
602
- }
603
- }
@@ -1,83 +0,0 @@
1
- export class CountedHash
2
- {
3
- n: number;
4
- val: { [id: string]: true|null }; // true === isset, null === indeterminant
5
-
6
- constructor()
7
- {
8
- this.n = 0;
9
- this.val = {};
10
- }
11
-
12
- get length(): number { return this.n; }
13
-
14
- indeterminate(id: string): boolean
15
- {
16
- return id != '' && this.val[id] === null;
17
- }
18
-
19
- test(id: string): boolean
20
- {
21
- return id != '' && this.val[id] !== undefined;
22
- }
23
-
24
- set(id: string, val: true|null = true): void
25
- {
26
- if (id != '')
27
- {
28
- if (! this.test(id))
29
- this.n++;
30
- this.val[id] = val;
31
- }
32
- }
33
-
34
- clear(id: string): void
35
- {
36
- if (this.test(id))
37
- {
38
- this.n--;
39
- delete this.val[id];
40
- }
41
- }
42
-
43
- apply(vals: { [id: string]: boolean|null }): void
44
- {
45
- this.empty();
46
-
47
- if (vals)
48
- Object.keys(vals).forEach((id) => {
49
- if (vals[id] !== false)
50
- this.set(id, vals[id] === true ? true : null);
51
- });
52
- }
53
-
54
- empty(): void
55
- {
56
- this.n = 0;
57
- this.val = {};
58
- }
59
-
60
- asArray(): string[]
61
- {
62
- let a: string[] = [];
63
-
64
- this.forEach(id => { a.push(id) });
65
-
66
- return a;
67
- }
68
-
69
- // This really only useful when length === 0|1
70
- asString(): string
71
- {
72
- for (var id in this.val) if (this.val.hasOwnProperty(id))
73
- return id;
74
-
75
- return '';
76
- }
77
-
78
- forEach(f: (id: string) => void): void
79
- {
80
- for (var id in this.val) if (this.val.hasOwnProperty(id))
81
- f(id);
82
- }
83
- }