@@ -5,6 +5,8 @@ import type { StringTable } from '../StringTable/StringTable.ts';
55import type { TrieData } from '../TrieData.ts' ;
66import { endianness } from '../utils/endian.ts' ;
77import { mergeOptionalWithDefaults } from '../utils/mergeOptionalWithDefaults.ts' ;
8+ import type { TextOffsetCode } from './prefix.ts' ;
9+ import { matchEntirePrefix } from './prefix.ts' ;
810import { decodeTrieBlobToBTrie , encodeTrieBlobToBTrie } from './TrieBlobEncoder.ts' ;
911import {
1012 NodeChildIndexRefShift ,
@@ -13,11 +15,9 @@ import {
1315 NodeHeaderNumChildrenShift ,
1416} from './TrieBlobFormat.ts' ;
1517import { TrieBlobInternals , TrieBlobIRoot } from './TrieBlobIRoot.ts' ;
18+ import type { U8Array , U32Array } from './TypedArray.ts' ;
1619import { encodeTextToUtf8_32Rev , Utf8Accumulator } from './Utf8.ts' ;
1720
18- type U8Array = Uint8Array < ArrayBuffer > ;
19- type U32Array = Uint32Array < ArrayBuffer > ;
20-
2121export class TrieBlob implements TrieData {
2222 readonly info : Readonly < TrieInfo > ;
2323 #forbidIdx: number | undefined ;
@@ -162,7 +162,7 @@ export class TrieBlob implements TrieData {
162162 p . code = p . code || encodeTextToUtf8_32Rev ( p ) ;
163163 const prefixIdx = node >>> 9 ;
164164 const pfx = prefixIdx ? this . #stringTable. getStringBytes ( prefixIdx ) : undefined ;
165- if ( pfx && ! matchPrefix ( p , pfx ) ) return undefined ;
165+ if ( pfx && ! matchEntirePrefix ( p , pfx ) ) return undefined ;
166166
167167 const code = p . code ;
168168
@@ -227,11 +227,16 @@ export class TrieBlob implements TrieData {
227227 const NodeMaskChildCharIndex = TrieBlob . NodeMaskChildCharIndex ;
228228 const NodeChildRefShift = TrieBlob . NodeChildRefShift ;
229229 const nodes = this . nodes ;
230+ const st = this . #stringTable;
230231 const stack : StackItem [ ] = [ { nodeIdx : rootIdx , pos : 0 , word : '' , acc : Utf8Accumulator . create ( ) } ] ;
231232 let depth = 0 ;
232233
233234 while ( depth >= 0 ) {
234- const { nodeIdx, pos, word, acc } = stack [ depth ] ;
235+ const s = stack [ depth ] ;
236+ if ( ! s . pos ) {
237+ applyPrefixString ( s ) ;
238+ }
239+ const { nodeIdx, pos, word, acc } = s ;
235240 const node = nodes [ nodeIdx ] ;
236241 // pos is 0 when first entering a node
237242 if ( ! pos && node & NodeMaskEOW ) {
@@ -255,6 +260,13 @@ export class TrieBlob implements TrieData {
255260 acc : nAcc ,
256261 } ;
257262 }
263+
264+ function applyPrefixString ( s : StackItem ) : void {
265+ const prefixIdx = nodes [ s . nodeIdx ] >>> 9 ;
266+ const pfx = prefixIdx ? st . getStringBytes ( prefixIdx ) : undefined ;
267+ if ( ! pfx ) return ;
268+ s . word += s . acc . decodeBytesToString ( pfx ) ;
269+ }
258270 }
259271
260272 get size ( ) : number {
@@ -443,23 +455,3 @@ function trieBlobSort(data: U32Array) {
443455 sorted . forEach ( ( v , i ) => ( data [ start + i ] = v ) ) ;
444456 }
445457}
446-
447- interface TextOffsetCode {
448- text : string ;
449- offset : number ;
450- code : number ;
451- }
452-
453- function matchPrefix ( p : TextOffsetCode , prefix : U8Array | undefined ) : boolean {
454- if ( ! prefix ?. length ) return true ;
455-
456- const len = prefix . length ;
457- for ( let i = 0 ; i < len ; ++ i ) {
458- const charVal = p . code & 0xff ;
459- if ( prefix [ i ] !== charVal ) return false ;
460- p . code >>>= 8 ;
461- p . code = p . code || encodeTextToUtf8_32Rev ( p ) ;
462- }
463-
464- return true ;
465- }
0 commit comments