Repository navigation
perf: read a configurable set of parts for text index key and value lookups #3635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f09f916
ebcd775
d4fcb1f
28e98ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| --- | ||
| '@hyperdx/common-utils': patch | ||
| '@hyperdx/api': patch | ||
| '@hyperdx/app': patch | ||
| --- | ||
|
|
||
| perf: read only 20 median-sized parts for text index key and value lookups | ||
|
|
||
| Map key discovery and "all values" lookups on text indexes read the index | ||
| dictionary of every part in the time range, which is slow on tables with many | ||
| parts. They now read the 20 parts closest to the median size. Log and trace | ||
| sources can change the count with the new "Map key index parts" setting | ||
| (`mapKeyIndexMaxParts`), and which parts are read with "Map key index part size" | ||
| (`mapKeyIndexPartSelection`: median, smallest, or largest). "Load more" on a | ||
| single filter key still reads every part in the time range. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -448,6 +448,26 @@ const mcpSaveSourceSchema = z.object({ | |
| 'Log and trace sources. Rollup tables used for fast field discovery and ' + | ||
| 'value autocomplete in filters and search suggestions.', | ||
| ), | ||
| mapKeyIndexMaxParts: z | ||
| .number() | ||
| .int() | ||
| .min(1) | ||
| .optional() | ||
| .describe( | ||
| 'Log and trace sources. How many data parts are read from text indexes ' + | ||
| 'to discover attribute keys and filter values, chosen by ' + | ||
| 'mapKeyIndexPartSelection. Raise it if keys or values are missing from ' + | ||
| 'filters; lower it if they load slowly. Omit for the default of 20.', | ||
| ), | ||
| mapKeyIndexPartSelection: z | ||
| .enum(['median', 'smallest', 'largest']) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔵 minor — MCP schema hand-copies the The conventions require one source of truth (DRY, REQUIRED). This file already imports from Advisory. Fix if it is a small defect in code this PR changes; otherwise reply in the thread. Do not widen the PR or touch files it did not already change. How to respond |
||
| .optional() | ||
| .describe( | ||
| 'Log and trace sources. Which data parts, by row count, are read from ' + | ||
| 'text indexes for attribute keys and filter values: "median" (used when unset) ' + | ||
| 'balances coverage and cost, "smallest" reads the newest unmerged ' + | ||
| 'parts, "largest" reads the most merged data.', | ||
| ), | ||
| }); | ||
|
|
||
| export type McpSaveSourceInput = z.infer<typeof mcpSaveSourceSchema>; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| import { Control, Controller } from 'react-hook-form'; | ||
| import { DEFAULT_MAP_KEY_INDEX_MAX_PARTS } from '@hyperdx/common-utils/dist/core/metadata'; | ||
| import { TSource } from '@hyperdx/common-utils/dist/types'; | ||
| import { NumberInput } from '@mantine/core'; | ||
|
|
||
| import SelectControlled from '@/components/SelectControlled'; | ||
|
|
||
| import { MAP_KEY_INDEX_PART_SELECTION_OPTIONS } from './constants'; | ||
| import { FormRow } from './FormRow'; | ||
|
|
||
| export function MapKeyIndexMaxPartsFormRow({ | ||
| control, | ||
| }: { | ||
| control: Control<TSource>; | ||
| }) { | ||
| return ( | ||
| <FormRow | ||
| label="Map key index parts" | ||
| helpText={`How many data parts are read from text indexes to discover attribute keys and filter values; "Map key index part size" picks which ones. Raise it if keys or values are missing from filters; lower it if they load slowly. Defaults to ${DEFAULT_MAP_KEY_INDEX_MAX_PARTS}.`} | ||
| > | ||
| <Controller | ||
| control={control} | ||
| name="mapKeyIndexMaxParts" | ||
| render={({ field, fieldState }) => ( | ||
| <NumberInput | ||
| {...field} | ||
| value={field.value ?? ''} | ||
| onChange={v => field.onChange(v === '' ? undefined : v)} | ||
| min={1} | ||
| allowDecimal={false} | ||
| allowNegative={false} | ||
| placeholder={String(DEFAULT_MAP_KEY_INDEX_MAX_PARTS)} | ||
| error={fieldState.error?.message} | ||
| /> | ||
| )} | ||
| /> | ||
| </FormRow> | ||
| ); | ||
| } | ||
|
|
||
| export function MapKeyIndexPartSelectionFormRow({ | ||
| control, | ||
| }: { | ||
| control: Control<TSource>; | ||
| }) { | ||
| return ( | ||
| <FormRow | ||
| label="Map key index part size" | ||
| helpText='Which data parts, by row count, are read from text indexes for attribute keys and filter values. "Median" balances coverage and cost; "Smallest" reads the newest unmerged parts, which is cheap and shows new keys first; "Largest" reads the most merged data, which covers the most keys but reads the biggest indexes.' | ||
| > | ||
| <SelectControlled | ||
| control={control} | ||
| name="mapKeyIndexPartSelection" | ||
| data={MAP_KEY_INDEX_PART_SELECTION_OPTIONS} | ||
| placeholder={MAP_KEY_INDEX_PART_SELECTION_OPTIONS[0].label} | ||
| allowDeselect={false} | ||
| /> | ||
| </FormRow> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔵 minor — MCP save_source restates the enum and int constraint instead of reusing the common-utils schemas
z.enum(['median','smallest','largest'])and.int().min(1)duplicateMapKeyIndexPartSelectionSchemaandMapKeyIndexMaxPartsSchemainpackages/common-utils/src/types.ts. Usez.nativeEnum(MapKeyIndexPartSelection)(orMapKeyIndexPartSelectionSchema), and export and reuse the max-parts constraint, so adding a selection mode can't leave MCP behind.Advisory. Fix if it is a small defect in code this PR changes; otherwise reply in the thread. Do not widen the PR or touch files it did not already change. How to respond