Skip to content

Commit b6b9fe1

Browse files
committedJul 28, 2024·
progress on collect line numbers
1 parent e21621d commit b6b9fe1

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed
 

‎src/trie.ts

+60-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import {
33
readGzippedJSON,
44
TRIE_FILE,
55
TSV_DB_FILE,
6+
uniteSets,
67
writeGzippedJSON,
78
} from "./util.js";
8-
import { readFileSync, writeFileSync } from "fs";
9+
import { readFileSync } from "fs";
910

1011
interface EncodedTrieNode {
1112
c?: Record<string, EncodedTrieNode>;
@@ -70,6 +71,64 @@ export class Trie {
7071
return currentNode;
7172
}
7273

74+
findLastNodeMatch(query: string) {
75+
// Initialize the currentNode pointer with the root node
76+
let currentNode = this.root;
77+
78+
let i = 0;
79+
// Iterate across the length of the string
80+
for (i = 0; i < query.length; i++) {
81+
const c = query[i] as string;
82+
// Check if the node exist for the current character in the Trie.
83+
if (!currentNode.children[c]) {
84+
// Given word as a prefix does not exist in Trie
85+
return { currentNode, i };
86+
}
87+
88+
// Move the currentNode pointer to the already existing node for current character.
89+
currentNode = currentNode.children[c];
90+
}
91+
92+
// Prefix exist in the Trie
93+
return { currentNode, i };
94+
}
95+
96+
autocomplete(query: string, maxResultCount = 10) {
97+
const resultSet = new Set<number>();
98+
99+
const { i, currentNode } = this.findLastNodeMatch(query);
100+
this.collectLineNumbersWithBFS(
101+
currentNode,
102+
query.length,
103+
i,
104+
resultSet,
105+
maxResultCount,
106+
);
107+
return resultSet;
108+
}
109+
110+
collectLineNumbersWithBFS(
111+
currentNode: TrieNode,
112+
querySize: number,
113+
queryIndex: number,
114+
resultSet: Set<number>,
115+
maxResultCount = 10,
116+
) {
117+
if (resultSet.size > maxResultCount) return;
118+
uniteSets(resultSet, currentNode.lineNumbers);
119+
if (queryIndex >= querySize) return;
120+
121+
for (const [_, childNode] of Object.entries(currentNode.children)) {
122+
this.collectLineNumbersWithBFS(
123+
childNode,
124+
querySize,
125+
queryIndex++,
126+
resultSet,
127+
maxResultCount,
128+
);
129+
}
130+
}
131+
73132
searchPrefix(query: string): number[] | null {
74133
const searchTerm = query.trim().toLowerCase();
75134
if (searchTerm.length < 1) return null;

‎src/util.ts

+14
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,17 @@ export async function readLinesFromTSV(
189189

190190
return linesRead;
191191
}
192+
193+
/**
194+
* add all elements of `setB` to `setA`
195+
*
196+
* @export
197+
* @template T
198+
* @param {Set<T>} setA
199+
* @param {Set<T>} setB
200+
*/
201+
export function uniteSets<T>(setA: Set<T>, setB: Set<T>) {
202+
for (const elem of setB) {
203+
setA.add(elem);
204+
}
205+
}

‎test/util.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ describe("util functions", () => {
3232
]);
3333
});
3434

35-
it("should 1000 lines in maximum 50 ms", async () => {
35+
it("should 100 lines in maximum 50 ms", async () => {
3636
function createArray(n: number) {
3737
return Array.from({ length: n }, (v, k) => k + 1);
3838
}
3939
const t1 = new Date().getTime();
40-
await readLinesFromTSV(TSV_DB_FILE, createArray(1000));
40+
await readLinesFromTSV(TSV_DB_FILE, createArray(100));
4141
const deltaTime = new Date().getTime() - t1;
4242
expect(deltaTime).toBeLessThan(50);
4343
});

0 commit comments

Comments
 (0)
Please sign in to comment.