Skip to content

Commit cb34879

Browse files
committed
perf: look up Map text index block sizes in parallel
1 parent 757f2ea commit cb34879

2 files changed

Lines changed: 61 additions & 8 deletions

File tree

‎packages/common-utils/src/__tests__/metadata.test.ts‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,6 +2217,52 @@ describe('Metadata', () => {
22172217
value: ['r1'],
22182218
};
22192219

2220+
it("looks up every Map column's dictionary block size at once", async () => {
2221+
setupDefaultLogsSchema();
2222+
const kvIndex = (mapColumn: string, indexName: string) => ({
2223+
kv: {
2224+
columnName: mapColumn,
2225+
mapColumn,
2226+
indexName,
2227+
separator: '=',
2228+
useHasAny: false,
2229+
},
2230+
});
2231+
jest.spyOn(metadata, 'getMapColumnTextIndexes').mockResolvedValue(
2232+
new Map([
2233+
['LogAttributes', kvIndex('LogAttributes', 'idx_log_attr_items')],
2234+
[
2235+
'ResourceAttributes',
2236+
kvIndex('ResourceAttributes', 'idx_res_attr_items'),
2237+
],
2238+
]),
2239+
);
2240+
let releaseSettings: () => void = () => {};
2241+
const settings = jest
2242+
.spyOn(metadata, 'getMergeTreeSettings')
2243+
.mockReturnValue(
2244+
new Promise(resolve => {
2245+
releaseSettings = () => resolve(undefined);
2246+
}),
2247+
);
2248+
2249+
const result = metadata.getAllKeyValues({
2250+
...baseArgs,
2251+
keyExpressions: [
2252+
"LogAttributes['requestId']",
2253+
"ResourceAttributes['service.name']",
2254+
],
2255+
});
2256+
// Both lookups start before either finishes.
2257+
for (let i = 0; i < 50 && settings.mock.calls.length < 2; i++) {
2258+
await new Promise(resolve => setImmediate(resolve));
2259+
}
2260+
expect(settings).toHaveBeenCalledTimes(2);
2261+
2262+
releaseSettings();
2263+
await result;
2264+
});
2265+
22202266
it('yields each query as it finishes, without waiting for the slowest', async () => {
22212267
setupDefaultLogsSchema();
22222268
let releaseMapTextIndex: () => void = () => {};

‎packages/common-utils/src/core/metadata.ts‎

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3141,14 +3141,21 @@ export class Metadata {
31413141
// high-cardinality key holds up only its own batch's values. Within a
31423142
// batch, large dictionary blocks get one read per key; see
31433143
// getMapTextIndexKeyValues.
3144-
for (const [column, options] of mapTextIndexQueryOptions) {
3145-
const perKey =
3146-
(await this.getTextIndexDictionaryBlockSize({
3147-
databaseName,
3148-
tableName,
3149-
connectionId,
3150-
indexName: options.indexName,
3151-
})) >= PER_KEY_TEXT_INDEX_MIN_DICTIONARY_BLOCK_SIZE;
3144+
// Every Map column's block size is looked up at once, not one at a time.
3145+
const mapColumns = await Promise.all(
3146+
[...mapTextIndexQueryOptions].map(async ([column, options]) => ({
3147+
column,
3148+
options,
3149+
perKey:
3150+
(await this.getTextIndexDictionaryBlockSize({
3151+
databaseName,
3152+
tableName,
3153+
connectionId,
3154+
indexName: options.indexName,
3155+
})) >= PER_KEY_TEXT_INDEX_MIN_DICTIONARY_BLOCK_SIZE,
3156+
})),
3157+
);
3158+
for (const { column, options, perKey } of mapColumns) {
31523159
for (const keys of chunk(options.keys, TEXT_INDEX_KEYS_PER_QUERY)) {
31533160
promises.push(
31543161
this.getMapTextIndexKeyValues({

0 commit comments

Comments
 (0)