cspell-trie-lib 8.4.0 → 8.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.
@@ -2,16 +2,6 @@ import type { PartialTrieOptions, TrieOptions } from '../trie.js';
2
2
  import type { TrieData } from '../TrieData.js';
3
3
  import type { BuilderCursor } from './BuilderCursor.js';
4
4
  export interface TrieBuilder<T extends TrieData> {
5
- /**
6
- * Use this method to convert a word into an array of characters.
7
- * Since `[...word]` is not equal to `word.split('')` or `word[i]` in some cases,
8
- * this method is used to ensure that the characters are split correctly.
9
- * @see [String.codePointAt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt)
10
- * @see [String.charCodeAt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt)
11
- * @param word - The word to convert into an array of characters.
12
- * @returns An array of characters, one for each character in the word.
13
- */
14
- wordToCharacters(word: string): string[];
15
5
  getCursor(): BuilderCursor;
16
6
  build(): T;
17
7
  setOptions(options: Readonly<PartialTrieOptions>): Readonly<TrieOptions>;
@@ -1,4 +1,3 @@
1
1
  import type { BuilderCursor } from './BuilderCursor.js';
2
2
  export declare function insertWordsAtCursor(cursor: BuilderCursor, words: Iterable<string>): void;
3
- export declare function commonStringPrefixLen(a: string, b: string): number;
4
3
  //# sourceMappingURL=cursor-util.d.ts.map
@@ -1,11 +1,10 @@
1
1
  export function insertWordsAtCursor(cursor, words) {
2
2
  let prevWord = '';
3
3
  for (const word of words) {
4
- const pLen = commonStrPrefix(prevWord, word);
4
+ const pLen = commonPrefixLen(prevWord, word);
5
5
  const stepBack = prevWord.length - pLen;
6
6
  cursor.backStep(stepBack);
7
- const wLen = word.length;
8
- for (let i = pLen; i < wLen; ++i) {
7
+ for (let i = pLen; i < word.length; ++i) {
9
8
  cursor.insertChar(word[i]);
10
9
  }
11
10
  cursor.markEOW();
@@ -13,21 +12,7 @@ export function insertWordsAtCursor(cursor, words) {
13
12
  }
14
13
  cursor.backStep(prevWord.length);
15
14
  }
16
- export function commonStringPrefixLen(a, b) {
17
- let i = 0;
18
- for (i = 0; i < a.length && a[i] === b[i]; ++i) {
19
- /* empty */
20
- }
21
- if (i) {
22
- // detect second half of a surrogate pair and backup.
23
- const c = a.charCodeAt(i) & 0xffff;
24
- if (c >= 0xdc00 && c <= 0xdfff) {
25
- --i;
26
- }
27
- }
28
- return i;
29
- }
30
- function commonStrPrefix(a, b) {
15
+ function commonPrefixLen(a, b) {
31
16
  let i = 0;
32
17
  for (i = 0; i < a.length && a[i] === b[i]; ++i) {
33
18
  /* empty */
@@ -186,10 +186,10 @@ export function isEndOfWordNode(n) {
186
186
  return !!n?.eow;
187
187
  }
188
188
  function walk(root, word) {
189
- const w = [...word];
189
+ const w = word;
190
190
  let n = root;
191
191
  let i = 0;
192
- while (n && i < w.length) {
192
+ while (n && i < word.length) {
193
193
  const h = w[i++];
194
194
  n = n.get(h);
195
195
  }
@@ -6,29 +6,21 @@ import { FastTrieBlobInternals } from './FastTrieBlobInternals.js';
6
6
  import { TrieBlob } from './TrieBlob.js';
7
7
  export declare class FastTrieBlob implements TrieData {
8
8
  private nodes;
9
- private _charIndex;
9
+ private charIndex;
10
10
  readonly bitMasksInfo: FastTrieBlobBitMaskInfo;
11
- private _charToIndexMap;
11
+ private charToIndexMap;
12
12
  private _readonly;
13
13
  private _forbidIdx;
14
14
  private _iTrieRoot;
15
- wordToCharacters: (word: string) => readonly string[];
16
15
  readonly info: Readonly<TrieInfo>;
17
16
  private constructor();
18
- private _lookUpCharIndex;
19
- private wordToNodeCharIndexSequence;
20
- private letterToNodeCharIndexSequence;
17
+ private lookUpCharIndex;
21
18
  has(word: string): boolean;
22
19
  private _has;
23
20
  words(): Iterable<string>;
24
21
  toTrieBlob(): TrieBlob;
25
22
  isReadonly(): boolean;
26
23
  freeze(): this;
27
- toJSON(): {
28
- info: Readonly<TrieInfo>;
29
- nodes: NodeElement[];
30
- charIndex: readonly string[];
31
- };
32
24
  static create(data: FastTrieBlobInternals, options?: PartialTrieInfo): FastTrieBlob;
33
25
  static toITrieNodeRoot(trie: FastTrieBlob): ITrieNodeRoot;
34
26
  static NodeMaskEOW: number;
@@ -42,20 +34,6 @@ export declare class FastTrieBlob implements TrieData {
42
34
  hasForbiddenWords(): boolean;
43
35
  /** number of nodes */
44
36
  get size(): number;
45
- private _lookupCharIndexNode;
46
- /** Search from nodeIdx for the node index representing the character. */
47
- private _searchNodeForChar;
48
- get charIndex(): readonly string[];
49
- static fromTrieBlob(trie: TrieBlob): FastTrieBlob;
37
+ private _lookupChar;
50
38
  }
51
- interface NodeElement {
52
- id: number;
53
- eow: boolean;
54
- n: number;
55
- c: {
56
- c: number | string;
57
- i: number;
58
- }[];
59
- }
60
- export {};
61
39
  //# sourceMappingURL=FastTrieBlob.d.ts.map
@@ -3,35 +3,26 @@ import { mergeOptionalWithDefaults } from '../utils/mergeOptionalWithDefaults.js
3
3
  import { extractInfo } from './FastTrieBlobBitMaskInfo.js';
4
4
  import { FastTrieBlobInternals } from './FastTrieBlobInternals.js';
5
5
  import { FastTrieBlobIRoot } from './FastTrieBlobIRoot.js';
6
- import { NumberSequenceByteDecoderAccumulator } from './NumberSequenceByteDecoderAccumulator.js';
7
6
  import { TrieBlob } from './TrieBlob.js';
8
7
  export class FastTrieBlob {
9
8
  nodes;
10
- _charIndex;
9
+ charIndex;
11
10
  bitMasksInfo;
12
- _charToIndexMap;
11
+ charToIndexMap;
13
12
  _readonly = false;
14
13
  _forbidIdx;
15
14
  _iTrieRoot;
16
- wordToCharacters;
17
15
  info;
18
- constructor(nodes, _charIndex, bitMasksInfo, options) {
16
+ constructor(nodes, charIndex, bitMasksInfo, options) {
19
17
  this.nodes = nodes;
20
- this._charIndex = _charIndex;
18
+ this.charIndex = charIndex;
21
19
  this.bitMasksInfo = bitMasksInfo;
22
20
  this.info = mergeOptionalWithDefaults(options);
23
- this.wordToCharacters = (word) => [...word];
24
- this._charToIndexMap = createCharToIndexMap(_charIndex);
25
- this._forbidIdx = this._searchNodeForChar(0, this.info.forbiddenWordPrefix);
21
+ this.charToIndexMap = createCharToIndexMap(charIndex);
22
+ this._forbidIdx = this._lookupChar(0, this.info.forbiddenWordPrefix);
26
23
  }
27
- _lookUpCharIndex(char) {
28
- return this._charToIndexMap[char] ?? -1;
29
- }
30
- wordToNodeCharIndexSequence(word) {
31
- return TrieBlob.charactersToCharIndexSequence(this.wordToCharacters(word), (c) => this._lookUpCharIndex(c));
32
- }
33
- letterToNodeCharIndexSequence(letter) {
34
- return TrieBlob.toCharIndexSequence(this._lookUpCharIndex(letter));
24
+ lookUpCharIndex(char) {
25
+ return this.charToIndexMap[char] ?? -1;
35
26
  }
36
27
  has(word) {
37
28
  return this._has(0, word);
@@ -41,11 +32,10 @@ export class FastTrieBlob {
41
32
  const NodeChildRefShift = this.bitMasksInfo.NodeChildRefShift;
42
33
  const NodeMaskEOW = this.bitMasksInfo.NodeMaskEOW;
43
34
  const nodes = this.nodes;
44
- const charIndexes = this.wordToNodeCharIndexSequence(word);
45
- const len = charIndexes.length;
35
+ const len = word.length;
46
36
  let node = nodes[nodeIdx];
47
37
  for (let p = 0; p < len; ++p, node = nodes[nodeIdx]) {
48
- const letterIdx = charIndexes[p];
38
+ const letterIdx = this.lookUpCharIndex(word[p]);
49
39
  const count = node.length;
50
40
  let i = count - 1;
51
41
  for (; i > 0; --i) {
@@ -66,11 +56,10 @@ export class FastTrieBlob {
66
56
  const NodeChildRefShift = this.bitMasksInfo.NodeChildRefShift;
67
57
  const NodeMaskEOW = this.bitMasksInfo.NodeMaskEOW;
68
58
  const nodes = this.nodes;
69
- const accumulator = NumberSequenceByteDecoderAccumulator.create();
70
- const stack = [{ nodeIdx: 0, pos: 0, word: '', accumulator }];
59
+ const stack = [{ nodeIdx: 0, pos: 0, word: '' }];
71
60
  let depth = 0;
72
61
  while (depth >= 0) {
73
- const { nodeIdx, pos, word, accumulator } = stack[depth];
62
+ const { nodeIdx, pos, word } = stack[depth];
74
63
  const node = nodes[nodeIdx];
75
64
  if (!pos && node[0] & NodeMaskEOW) {
76
65
  yield word;
@@ -82,15 +71,12 @@ export class FastTrieBlob {
82
71
  const nextPos = ++stack[depth].pos;
83
72
  const entry = node[nextPos];
84
73
  const charIdx = entry & NodeMaskChildCharIndex;
85
- const acc = accumulator.clone();
86
- const letterIdx = acc.decode(charIdx);
87
- const letter = (letterIdx && this._charIndex[letterIdx]) || '';
74
+ const letter = this.charIndex[charIdx];
88
75
  ++depth;
89
76
  stack[depth] = {
90
77
  nodeIdx: entry >>> NodeChildRefShift,
91
78
  pos: 0,
92
79
  word: word + letter,
93
- accumulator: acc,
94
80
  };
95
81
  }
96
82
  }
@@ -125,7 +111,7 @@ export class FastTrieBlob {
125
111
  binNodes[offset++] = (nodeToIndex[nodeRef] << refShift) | charIndex;
126
112
  }
127
113
  }
128
- return new TrieBlob(binNodes, this._charIndex, this.info);
114
+ return new TrieBlob(binNodes, this.charIndex, this.info);
129
115
  }
130
116
  isReadonly() {
131
117
  return this._readonly;
@@ -134,18 +120,11 @@ export class FastTrieBlob {
134
120
  this._readonly = true;
135
121
  return this;
136
122
  }
137
- toJSON() {
138
- return {
139
- info: this.info,
140
- nodes: nodesToJson(this.nodes),
141
- charIndex: this._charIndex,
142
- };
143
- }
144
123
  static create(data, options) {
145
124
  return new FastTrieBlob(data.nodes, data.charIndex, extractInfo(data), options);
146
125
  }
147
126
  static toITrieNodeRoot(trie) {
148
- return new FastTrieBlobIRoot(new FastTrieBlobInternals(trie.nodes, trie._charIndex, trie._charToIndexMap, trie.bitMasksInfo), 0, trie.info);
127
+ return new FastTrieBlobIRoot(new FastTrieBlobInternals(trie.nodes, trie.charIndex, trie.charToIndexMap, trie.bitMasksInfo), 0, trie.info);
149
128
  }
150
129
  static NodeMaskEOW = TrieBlob.NodeMaskEOW;
151
130
  static NodeChildRefShift = TrieBlob.NodeChildRefShift;
@@ -174,12 +153,12 @@ export class FastTrieBlob {
174
153
  get size() {
175
154
  return this.nodes.length;
176
155
  }
177
- _lookupCharIndexNode(nodeIdx, charIndex) {
156
+ _lookupChar(nodeIdx, char) {
178
157
  const NodeMaskChildCharIndex = this.bitMasksInfo.NodeMaskChildCharIndex;
179
158
  const NodeChildRefShift = this.bitMasksInfo.NodeChildRefShift;
180
159
  const nodes = this.nodes;
181
160
  const node = nodes[nodeIdx];
182
- const letterIdx = charIndex;
161
+ const letterIdx = this.lookUpCharIndex(char);
183
162
  const count = node.length;
184
163
  let i = count - 1;
185
164
  for (; i > 0; --i) {
@@ -189,54 +168,6 @@ export class FastTrieBlob {
189
168
  }
190
169
  return 0;
191
170
  }
192
- /** Search from nodeIdx for the node index representing the character. */
193
- _searchNodeForChar(nodeIdx, char) {
194
- const charIndexes = this.letterToNodeCharIndexSequence(char);
195
- let idx = nodeIdx;
196
- for (let i = 0; i < charIndexes.length; ++i) {
197
- idx = this._lookupCharIndexNode(idx, charIndexes[i]);
198
- if (!idx)
199
- return 0;
200
- }
201
- return idx;
202
- }
203
- get charIndex() {
204
- return [...this._charIndex];
205
- }
206
- static fromTrieBlob(trie) {
207
- const bitMasksInfo = {
208
- NodeMaskEOW: TrieBlob.NodeMaskEOW,
209
- NodeMaskChildCharIndex: TrieBlob.NodeMaskChildCharIndex,
210
- NodeChildRefShift: TrieBlob.NodeChildRefShift,
211
- };
212
- const trieNodesBin = TrieBlob.nodesView(trie);
213
- const nodeOffsets = [];
214
- for (let offset = 0; offset < trieNodesBin.length; offset += (trieNodesBin[offset] & TrieBlob.NodeMaskNumChildren) + 1) {
215
- nodeOffsets.push(offset);
216
- }
217
- const offsetToNodeIndex = new Map(nodeOffsets.map((offset, i) => [offset, i]));
218
- const nodes = new Array(nodeOffsets.length);
219
- for (let i = 0; i < nodes.length; ++i) {
220
- const offset = nodeOffsets[i];
221
- const n = trieNodesBin[offset];
222
- const eow = n & TrieBlob.NodeMaskEOW;
223
- const count = n & TrieBlob.NodeMaskNumChildren;
224
- const node = new Array(count + 1);
225
- node[0] = eow;
226
- nodes[i] = node;
227
- for (let j = 1; j <= count; ++j) {
228
- const n = trieNodesBin[offset + j];
229
- const charIndex = n & TrieBlob.NodeMaskChildCharIndex;
230
- const nodeIndex = n >>> TrieBlob.NodeChildRefShift;
231
- const idx = offsetToNodeIndex.get(nodeIndex);
232
- if (idx === undefined) {
233
- throw new Error(`Invalid node index ${nodeIndex}`);
234
- }
235
- node[j] = (idx << TrieBlob.NodeChildRefShift) | charIndex;
236
- }
237
- }
238
- return new FastTrieBlob(nodes, trie.charIndex, bitMasksInfo, trie.info);
239
- }
240
171
  }
241
172
  function createCharToIndexMap(charIndex) {
242
173
  const map = Object.create(null);
@@ -247,16 +178,4 @@ function createCharToIndexMap(charIndex) {
247
178
  }
248
179
  return map;
249
180
  }
250
- function nodesToJson(nodes) {
251
- function nodeElement(node, index) {
252
- const eow = !!(node[0] & TrieBlob.NodeMaskEOW);
253
- const children = node.slice(1).map((n) => ({
254
- c: ('00' + (n & TrieBlob.NodeMaskChildCharIndex).toString(16)).slice(-2),
255
- i: n >>> TrieBlob.NodeChildRefShift,
256
- }));
257
- return { id: index, eow, n: node.length, c: children };
258
- }
259
- const elements = nodes.map((n, i) => nodeElement(n, i));
260
- return elements;
261
- }
262
181
  //# sourceMappingURL=FastTrieBlob.js.map
@@ -11,14 +11,11 @@ export declare class FastTrieBlobBuilder implements TrieBuilder<FastTrieBlob> {
11
11
  private IdxEOW;
12
12
  private _cursor;
13
13
  private _options;
14
- wordToCharacters: (word: string) => string[];
15
14
  readonly bitMasksInfo: FastTrieBlobBitMaskInfo;
16
15
  constructor(options?: PartialTrieInfo, bitMasksInfo?: FastTrieBlobBitMaskInfo);
17
16
  setOptions(options: PartialTrieInfo): Readonly<TrieInfo>;
18
17
  get options(): Readonly<TrieInfo>;
19
18
  private getCharIndex;
20
- private wordToNodeCharIndexSequence;
21
- private letterToNodeCharIndexSequence;
22
19
  insert(word: string | Iterable<string> | string[]): this;
23
20
  getCursor(): BuilderCursor;
24
21
  private createCursor;
@@ -27,7 +24,7 @@ export declare class FastTrieBlobBuilder implements TrieBuilder<FastTrieBlob> {
27
24
  isReadonly(): boolean;
28
25
  freeze(): this;
29
26
  build(): FastTrieBlob;
30
- static fromWordList(words: readonly string[] | Iterable<string>, options?: PartialTrieInfo): FastTrieBlob;
27
+ static fromWordList(words: string[] | Iterable<string>, options?: PartialTrieInfo): FastTrieBlob;
31
28
  static fromTrieRoot(root: TrieRoot): FastTrieBlob;
32
29
  static NodeMaskEOW: number;
33
30
  static NodeChildRefShift: number;
@@ -1,6 +1,5 @@
1
1
  import { assert } from '../utils/assert.js';
2
2
  import { mergeOptionalWithDefaults } from '../utils/mergeOptionalWithDefaults.js';
3
- import { assertValidUtf16Character } from '../utils/text.js';
4
3
  import { FastTrieBlob } from './FastTrieBlob.js';
5
4
  import { FastTrieBlobInternals } from './FastTrieBlobInternals.js';
6
5
  import { resolveMap } from './resolveMap.js';
@@ -13,7 +12,6 @@ export class FastTrieBlobBuilder {
13
12
  IdxEOW;
14
13
  _cursor;
15
14
  _options;
16
- wordToCharacters = (word) => [...word];
17
15
  bitMasksInfo;
18
16
  constructor(options, bitMasksInfo = FastTrieBlobBuilder.DefaultBitMaskInfo) {
19
17
  this._options = mergeOptionalWithDefaults(options);
@@ -39,12 +37,6 @@ export class FastTrieBlobBuilder {
39
37
  this.charToIndexMap[charNFD] = idx;
40
38
  return idx;
41
39
  }
42
- wordToNodeCharIndexSequence(word) {
43
- return TrieBlob.charactersToCharIndexSequence(this.wordToCharacters(word), (c) => this.getCharIndex(c));
44
- }
45
- letterToNodeCharIndexSequence(letter) {
46
- return TrieBlob.toCharIndexSequence(this.getCharIndex(letter));
47
- }
48
40
  insert(word) {
49
41
  if (this.isReadonly()) {
50
42
  throw new Error('FastTrieBlob is readonly');
@@ -84,43 +76,10 @@ export class FastTrieBlobBuilder {
84
76
  const eow = 1;
85
77
  const eowShifted = eow << NodeChildRefShift;
86
78
  const nodes = this.nodes;
87
- const stack = [{ nodeIdx: 0, pos: 0, dCount: 1, ps: '' }];
79
+ const stack = [{ nodeIdx: 0, pos: 0 }];
88
80
  let nodeIdx = 0;
89
81
  let depth = 0;
90
82
  const insertChar = (char) => {
91
- const cc = char.charCodeAt(0) & 0xdc00;
92
- // Work with partial surrogate pairs.
93
- if (cc === 0xd800 && char.length == 1) {
94
- // We have a high surrogate
95
- const s = stack[depth];
96
- const ns = stack[++depth];
97
- if (ns) {
98
- ns.nodeIdx = s.nodeIdx;
99
- ns.pos = s.pos;
100
- ns.dCount = 1;
101
- ns.ps = char;
102
- }
103
- else {
104
- stack[depth] = { nodeIdx: s.nodeIdx, pos: s.pos, dCount: 1, ps: char };
105
- }
106
- return;
107
- }
108
- if (stack[depth].ps) {
109
- char = stack[depth].ps + char;
110
- assertValidUtf16Character(char);
111
- }
112
- const indexSeq = this.letterToNodeCharIndexSequence(char);
113
- for (let i = 0; i < indexSeq.length; ++i) {
114
- insertCharIndexes(indexSeq[i], i + 1);
115
- }
116
- };
117
- /**
118
- * A single character can result in multiple nodes being created
119
- * because it takes multiple bytes to represent a character.
120
- * @param charIndex - partial character index.
121
- * @param char - the source character
122
- */
123
- const insertCharIndexes = (charIndex, dCount) => {
124
83
  // console.warn('i %o at %o', char, nodeIdx);
125
84
  if (nodes[nodeIdx] && Object.isFrozen(nodes[nodeIdx])) {
126
85
  nodeIdx = nodes.push([...nodes[nodeIdx]]) - 1;
@@ -132,7 +91,7 @@ export class FastTrieBlobBuilder {
132
91
  }
133
92
  const node = nodes[nodeIdx] ?? [0];
134
93
  nodes[nodeIdx] = node;
135
- const letterIdx = charIndex;
94
+ const letterIdx = this.getCharIndex(char);
136
95
  const hasIdx = childPos(node, letterIdx);
137
96
  const childIdx = hasIdx ? node[hasIdx] >>> NodeChildRefShift : nodes.length;
138
97
  const pos = hasIdx || node.push((childIdx << NodeChildRefShift) | letterIdx) - 1;
@@ -141,11 +100,9 @@ export class FastTrieBlobBuilder {
141
100
  if (s) {
142
101
  s.nodeIdx = nodeIdx;
143
102
  s.pos = pos;
144
- s.dCount = dCount;
145
- s.ps = '';
146
103
  }
147
104
  else {
148
- stack[depth] = { nodeIdx, pos, dCount, ps: '' };
105
+ stack[depth] = { nodeIdx, pos };
149
106
  }
150
107
  nodeIdx = childIdx;
151
108
  };
@@ -184,9 +141,7 @@ export class FastTrieBlobBuilder {
184
141
  return;
185
142
  // console.warn('<< %o', num);
186
143
  assert(num <= depth && num > 0);
187
- for (; num > 0; --num) {
188
- depth -= stack[depth].dCount;
189
- }
144
+ depth -= num;
190
145
  nodeIdx = stack[depth + 1].nodeIdx;
191
146
  };
192
147
  const c = {
@@ -206,11 +161,10 @@ export class FastTrieBlobBuilder {
206
161
  const NodeMaskEOW = this.bitMasksInfo.NodeMaskEOW;
207
162
  const IdxEOW = this.IdxEOW;
208
163
  const nodes = this.nodes;
209
- const charIndexes = this.wordToNodeCharIndexSequence(word);
210
- const len = charIndexes.length;
164
+ const len = word.length;
211
165
  let nodeIdx = 0;
212
166
  for (let p = 0; p < len; ++p) {
213
- const letterIdx = charIndexes[p];
167
+ const letterIdx = this.getCharIndex(word[p]);
214
168
  const node = nodes[nodeIdx];
215
169
  const count = node.length;
216
170
  let i = count - 1;
@@ -243,12 +197,11 @@ export class FastTrieBlobBuilder {
243
197
  const NodeChildRefShift = this.bitMasksInfo.NodeChildRefShift;
244
198
  const NodeMaskEOW = this.bitMasksInfo.NodeMaskEOW;
245
199
  const nodes = this.nodes;
246
- const charIndexes = this.wordToNodeCharIndexSequence(word);
247
- const len = charIndexes.length;
200
+ const len = word.length;
248
201
  let nodeIdx = 0;
249
202
  let node = nodes[nodeIdx];
250
203
  for (let p = 0; p < len; ++p, node = nodes[nodeIdx]) {
251
- const letterIdx = charIndexes[p];
204
+ const letterIdx = this.charToIndexMap[word[p]];
252
205
  const count = node.length;
253
206
  let i = count - 1;
254
207
  for (; i > 0; --i) {
@@ -281,7 +234,6 @@ export class FastTrieBlobBuilder {
281
234
  static fromTrieRoot(root) {
282
235
  const bitMasksInfo = FastTrieBlobBuilder.DefaultBitMaskInfo;
283
236
  const NodeChildRefShift = bitMasksInfo.NodeChildRefShift;
284
- const NodeCharIndexMask = bitMasksInfo.NodeMaskChildCharIndex;
285
237
  const NodeMaskEOW = bitMasksInfo.NodeMaskEOW;
286
238
  const tf = new FastTrieBlobBuilder(undefined, bitMasksInfo);
287
239
  const IdxEOW = tf.IdxEOW;
@@ -301,37 +253,15 @@ export class FastTrieBlobBuilder {
301
253
  if (!n.c)
302
254
  return nodeIdx;
303
255
  const children = Object.entries(n.c);
256
+ node.length = children.length + 1;
304
257
  for (let p = 0; p < children.length; ++p) {
305
258
  const [char, childNode] = children[p];
306
- addCharToNode(node, char, childNode);
259
+ const letterIdx = tf.getCharIndex(char);
260
+ const childIdx = walk(childNode);
261
+ node[p + 1] = (childIdx << NodeChildRefShift) | letterIdx;
307
262
  }
308
263
  return nodeIdx;
309
264
  }
310
- function resolveChild(node, charIndex) {
311
- let i = 1;
312
- for (i = 1; i < node.length && (node[i] & NodeCharIndexMask) !== charIndex; ++i) {
313
- // empty
314
- }
315
- return i;
316
- }
317
- function addCharToNode(node, char, n) {
318
- const indexSeq = tf.letterToNodeCharIndexSequence(char);
319
- for (const idx of indexSeq.slice(0, -1)) {
320
- const pos = resolveChild(node, idx);
321
- if (pos < node.length) {
322
- node = tf.nodes[node[pos] >>> NodeChildRefShift];
323
- }
324
- else {
325
- const next = [0];
326
- const nodeIdx = tf.nodes.push(next) - 1;
327
- node[pos] = (nodeIdx << NodeChildRefShift) | idx;
328
- node = next;
329
- }
330
- }
331
- const letterIdx = indexSeq[indexSeq.length - 1];
332
- const i = node.push(letterIdx) - 1;
333
- node[i] = (walk(n) << NodeChildRefShift) | letterIdx;
334
- }
335
265
  walk(root);
336
266
  return tf.build();
337
267
  }
@@ -1,25 +1,19 @@
1
1
  import type { ITrieNode, ITrieNodeId, ITrieNodeRoot } from '../ITrieNode/ITrieNode.js';
2
2
  import type { TrieInfo } from '../ITrieNode/TrieInfo.js';
3
3
  import type { FastTrieBlobInternals } from './FastTrieBlobInternals.js';
4
- type Node = readonly number[];
5
- type NodeIndex = number;
6
4
  declare class FastTrieBlobINode implements ITrieNode {
7
5
  readonly trie: FastTrieBlobInternals;
8
- readonly nodeIdx: NodeIndex;
6
+ readonly nodeIdx: number;
9
7
  readonly id: number;
10
- readonly node: Node;
8
+ readonly size: number;
9
+ readonly node: number[];
11
10
  readonly eow: boolean;
11
+ charToIdx: Record<string, number> | undefined;
12
12
  private _keys;
13
- private _count;
14
- private _size;
15
- private _chained;
16
- private _nodesEntries;
17
- private _entries;
18
- private _values;
19
- protected charToIdx: Readonly<Record<string, NodeIndex>> | undefined;
20
- constructor(trie: FastTrieBlobInternals, nodeIdx: NodeIndex);
21
- /** get keys to children */
13
+ constructor(trie: FastTrieBlobInternals, nodeIdx: number);
22
14
  keys(): readonly string[];
15
+ /** get keys to children */
16
+ private calcKeys;
23
17
  values(): readonly ITrieNode[];
24
18
  entries(): readonly (readonly [string, ITrieNode])[];
25
19
  /** get child ITrieNode */
@@ -28,10 +22,6 @@ declare class FastTrieBlobINode implements ITrieNode {
28
22
  hasChildren(): boolean;
29
23
  child(keyIdx: number): ITrieNode;
30
24
  getCharToIdxMap(): Record<string, number>;
31
- private containsChainedIndexes;
32
- private getNodesEntries;
33
- private walkChainedIndexes;
34
- get size(): number;
35
25
  }
36
26
  export declare class FastTrieBlobIRoot extends FastTrieBlobINode implements ITrieNodeRoot {
37
27
  readonly info: Readonly<TrieInfo>;