73 Commits
Author SHA1 Message Date
sparknackandGitHub 28a7661a2e fix: warm no-index vector fields as indexes (#50836)
issue: #50834

Fix no-index sealed vector raw data warmup selection. When a sealed
segment has no usable built or interim vector index, segcore now treats
raw vector field data as the vector search representation and resolves
its warmup from vector-index policy. Once a built or interim index
exists, raw vector data keeps normal vector-field warmup semantics.

Go load paths continue to pass field warmup unchanged; segcore resolves
the effective policy from current segment state.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-07-18 15:22:41 +08:00
sparknackandGitHub 6bd2418df7 enhance: Load JsonStats shredding through manifest translator (#51116)
issue: #51114

JsonStats shredding now loads through
`ManifestGroupTranslator`/`ChunkReader`, but JsonStats files do not have
the normal sealed-segment manifest metadata. The load path reconstructs
the needed column-group view from the existing parquet footer/schema:
column names, Arrow field ids, row counts, and file ordering. This keeps
the current `meta.json` contract unchanged; parquet key-value metadata
is only a fallback for old files that do not have the separate meta
file.

The main follow-up after switching to the manifest translator was
projection behavior. Lazy loading now builds one projected reader per
shredding column, so a predicate on one JSON path does not pull the
whole group; when warmup is enabled it still uses the full column group
so warmup can preload everything together. The added tests cover parquet
files without packed field-list metadata, multi-file ordering, lazy
single-column projection, and warmup full-group projection.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-07-15 16:42:36 +08:00
sparknackandGitHub 5abc17c3af fix: reserve index entry futures before submit (#51035)
issue: #50891

## What changed
- Reserve `IndexEntryReader` future vectors before submitting
read/download tasks so submitted tasks cannot be lost to vector
reallocation failures.
- Drain already stored futures if submission/setup fails before
releasing result buffers, download state, file descriptors, or
positioned writers.
- Cover memory reads, fd downloads, and stream-to-files download paths.

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-07-07 10:28:30 +08:00
sparknackandGitHub 5eb509aa5d fix: isolate local index cache cleanup paths (#50608)
issue: #48792

Local index cache directories were derived from index metadata. When
QueryNode releases a segment and then loads the same segment/index
again, the old and new `DiskFileManagerImpl` instances can point to the
same local directory.

That makes two races possible:
- a late writer from the old load can write into the directory used by
the new load;
- cleanup can remove a local directory while async writers for that
directory are still active.

Both races can leave the local disk index state inconsistent during
load/release concurrency.

This PR fixes the problem in two layers:
- Add a process-local generation to each `DiskFileManagerImpl` and
append it to all local index/text/json/ngram/raw-data cache prefixes.
Old and new file managers no longer share the same local directory,
while remote paths stay unchanged.
- Add per-directory RAII write leases. Cleanup closes the directory,
rejects new writers, and defers `RemoveDir` until active writers release
their leases.

The disk index raw-data scratch paths and cleanup are routed through
`DiskFileManagerImpl` so they use the same generation and lease rules.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-06-30 16:54:34 +08:00
sparknackandGitHub 8dad593ba5 enhance: stream field data loading (#50478)
- Replace `common.entryStream.streamBudgetRatio` with refreshable
`common.loadTransientBudgetBytes`, a process-wide transient load budget
shared by scalar index V3 entry streaming and storage v2/v3 field-data
loading. `0` keeps the limit disabled.
- Gate field-data batch reads on the shared budget, split batches by
loading overhead, scale read parallelism from the effective batch
budget, and finalize `GroupChunk` cells before pushing them so Arrow
tables are released promptly.
- Align MCL loading-overhead reservations for storage v1 scalar indexes
and storage v2/v3 field data under one load-transient overhead group,
with array-field overhead and mmap file usage accounted separately.
- Propagate load cancellation into budget waits, field-data batch tasks,
and V3 scalar `IndexEntryReader` stream/file reads so canceled loads do
not stay blocked behind transient memory pressure.
- Update segcore init/config watchers and add C++/Go coverage for budget
sizing, cancellation, field-data batching/finalization, V3 entry
streaming, and the new config.

issue: #49499

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-06-26 10:34:26 +08:00
sparknackandGitHub b7784881b7 fix: create marisa string index temp directory (#50500)
issue: #50488

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-06-17 11:34:22 +08:00
sparknackandGitHub 778f53fa70 fix: align expression cursor with scalar index raw data (#50233)
issue: #50197

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-06-16 16:34:23 +08:00
0cbe634b52 enhance: add streaming load support for scalar index v3 (#50267)
issue: https://github.com/milvus-io/milvus/issues/48957

## What changed

- Add streaming V3 `LoadEntries` paths for scalar indexes to avoid
reading full index entries into memory before materialization.
- Persist and load auxiliary metadata for sort/string indexes, including
offset maps, valid bitsets, and CSR arrays, so mmap paths can map
metadata directly and memory paths can preallocate buffers.
- Update scalar index resource estimates and related loading tests for
the streaming/mmap load behavior.

## Why

- Reduce peak memory during sealed scalar index load, especially for
large scalar sort, string, and bitmap indexes.
- Avoid recomputing persisted metadata at load time when V3 entries
already contain it.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-11 13:40:21 +08:00
sparknackandGitHub 87b3b8b78e enhance: add storage and Arrow IO pool metrics (#49610)
issue: #33132

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-06-08 20:40:19 +08:00
sparknackandGitHub 1cc43cdef8 enhance: upgrade knowhere vector index version to 10 explicitly (#50238)
issue: #42937

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-06-03 16:26:21 +08:00
sparknackandGitHub d5917c265e enhance: Add V3 entry streaming reader (#50073)
issue: #48957

- Add `IndexEntryReader::ReadEntryStream`, `GetEntrySize`, and
`HasEntry` for V3 entries.
- Stream plain and encrypted entries through ordered slices with
incremental CRC32c verification.
- Bound transient stream memory with a process-wide entry stream budget.
- Add dynamically refreshable `common.entryStream.streamBudgetRatio` to
tune the shared entry stream budget for current scalar index loading and
later field data loading.
- Use 16MB stream slices by default, aligned with the encrypted slice
size and existing V3 range size.
- Derive the entry stream budget from CPU core count: `CPU cores *
streamBudgetRatio * 16MB`.
- Harden stream error handling:
  - keep active futures bounded by the thread pool size
  - reject zero or too-small explicit slice sizes
  - use overflow-safe slice count calculation
  - verify CRC for empty entries
  - release budget when callbacks throw or task submission fails
  - wait for active workers before returning on abnormal exits
- validate decrypted slice length and include actual/expected CRC in
stream errors
- Document V3 streaming read behavior and shared budget configuration.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-05-30 16:20:13 +08:00
sparknackandGitHub def1e79754 enhance: Expose Arrow reader config (#49620)
issue: #49616

- Expose Arrow reader range coalescing options through
`common.arrow.reader.holeSizeLimitBytes` and
`common.arrow.reader.rangeSizeLimitBytes`.
- Pass the configured Arrow reader properties into StorageV2
`FileRowGroupReader` paths.
- Propagate the same config into StorageV3 milvus-storage reader
properties (`reader.parquet.prebuffer.*`).
- Update milvus-storage to the official main revision that supports the
reader hole and range size options.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-05-20 16:02:30 +08:00
sparknackandGitHub ac87f5a2fa fix: preserve filter bitset when MVCC is disabled (#49736)
issue: #49735

- Preserve upstream scalar filter bitsets when
`common.visibilityFilterEnabled=false`.
- Only mark all rows visible in the disabled visibility-filter path when
`MvccNode` has no upstream filter input.
- Add C++ and Go regression coverage for preserving predicates/filter
bitsets in this path.

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-05-13 10:52:11 +08:00
sparknackandGitHub 96c56fc915 enhance: add expression filter cache for two-stage search (#48883)
issue: https://github.com/milvus-io/milvus/issues/47218

Two-stage search evaluates the same sealed-segment filter in Stage 1 for
selectivity and again in Stage 2 before vector search. Cache the Stage 1
full-filter bitmap in ExprResCacheManager so Stage 2 can reuse it
instead of re-evaluating the predicate.

Build full-filter cache keys from the FilterBitsNode currently being
executed instead of carrying an outer vector-plan cache key. Include
entity TTL physical time when TTL filtering is active so cached bitsets
are reused only for equivalent effective predicates.

Text/Phrase match already store sub-expression bitmaps in the same
manager. When full-filter caching is enabled, disable sub-expression
writes so one request path does not cache both the child text bitmap and
the full-filter bitmap. Existing child entries may still be read.

Keep request merging from mixing EnableExprCache modes, otherwise a
Stage 2 two-stage request can merge with a normal search and run with
the wrong cache behavior. Restore FilterOnly and EnableExprCache after
the filter stage so fallback continues with the caller original request
mode.

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-04-30 00:47:51 +08:00
df51830b58 enhance: add preferFieldDataWhenIndexHasRawData toggle for sealed retrieve (#49127)
## Summary

- New QueryNode toggle `queryNode.preferFieldDataWhenIndexHasRawData`
(default `false`) makes sealed retrieve serve scalar and vector fields
from resident column data instead of index-backed raw data, and the
loader keeps the column resident alongside the index on load/reload.
- Hot-path short-circuit: when the toggle is off, retrieve does not call
`HasFieldData` or take the segment's `shared_lock`, so the default
retrieve path is unchanged in cost.
- Observability: log at `InitQueryNode` when the toggle is on, calling
out the memory trade-off (field data + index both resident).

## Test plan

- [x] C++ unit:
`RetrieveScalarFieldFromColumnWhenIndexHasRawDataAndPreferFieldDataEnabled`
— seeds the scalar index with values deliberately desynchronized from
the column, then asserts the retrieved value equals the column value
under toggle=true. Positively proves the index branch is skipped rather
than just checking the API returns something.
- [x] Go unit (positive):
`TestLoadWithIndexPreferFieldDataWhenIndexHasRawData` — toggle=on,
asserts `HasFieldData=true`.
- [x] Go unit (negative): `TestLoadWithIndexSkipsFieldDataByDefault` —
toggle=off default, asserts `HasFieldData=false`. Guards the
memory-saving behavior existing deployments rely on.
- [ ] Integration smoke on local standalone.

## Trade-off

Enabling the toggle keeps both the raw field data and the index resident
in memory, roughly doubling the memory footprint for fields whose index
normally supplies raw data. The toggle is off by default, so no existing
deployment is affected.

issue: #49126

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 00:05:46 +08:00
23fc265179 enhance: async reduce with cancellation and per-segment OpContext scoping (#49117)
## Summary
- Parallelize per-segment `FillTargetEntry` on the MIDDLE thread pool
(matching `FillPrimaryKeys`) and plumb `OpContext*` through the reduce
path for cancellation support.
- Add `AsyncReduceSearchResultsAndFillData` returning `CFuture`,
propagating the folly cancellation token into a per-call `OpContext`.
Switch the Go wrapper to `cgo.Async` so a cancelled query context aborts
the in-flight reduce instead of blocking until completion.
- Use a per-call `OpContext` for `storage_usage` in `FillPrimaryKeys` /
`FillTargetEntry` — sharing `op_ctx` across segments made each segment's
`search_storage_cost_` accumulate every prior segment's bytes, inflating
`GetTotalStorageCost()`.
- Move preflight logic (AssertInfo, input copying) inside the async
lambda so exceptions become failed `CFuture` results rather than
escaping across the C ABI.

issue: #49116

## Test plan
- [x] Add `TestReduceAsyncSuccess` — end-to-end async reduce with valid
results
- [x] Add `TestReduceAsyncCancelled` — pre-cancelled context surfaces
`context.Canceled`
- [ ] Existing reduce tests pass (`go test -tags dynamic,test
./internal/util/segcore/...`)
- [ ] C++ unit tests pass (synchronous C entry point preserved)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-26 00:03:45 +08:00
794710a7d5 enhance: configurable byte-size threshold for storage v2 cell packing (#49205)
## Summary

This PR ships two related commits:

1. **`enhance: fold calculate_size and write_to_target passes for
variable-length chunk writers`** — refactor String/JSON/Geometry chunk
writers from two Arrow passes (count + cache) to one Arrow pass that
fills a shared `offsets_` member. Eliminates per-row heap allocation (no
more `simdjson::padded_string` copies). `AssertInfo` guards `cursor <=
UINT32_MAX` before each narrowing cast so oversize chunks fail loudly
instead of silently wrapping.

2. **`enhance: configurable byte-size threshold for storage v2 cell
packing`** — replace the hardcoded `4 row groups per cell` constant with
a runtime-configurable byte-size target driven by
`queryNode.segcore.storageV2.cellTargetSizeBytes` (default `4 MiB`,
refreshable).
- At cell-build time, `rgs_per_cell = max(1, target /
avg_row_group_size)`, with cells never crossing file boundaries.
- Paramtable `Formatter` rejects non-positive values and falls back to 4
MiB with a warn log.
- Value pushed into segcore via a new CGO setter
(`SetStorageV2CellTargetSizeBytes`) on QueryNode startup and on
paramtable change, backed by an inline atomic in `GroupCTMeta.h`.

## Why

The fixed `4` constant does not scale across workloads: large row groups
make each cell too fat (coarse eviction, unpredictable memory), small
row groups waste cache slots and increase bookkeeping overhead. A
byte-target keeps cache cell footprint predictable regardless of parquet
row group layout, and gives operators a runtime tuning knob. Default 4
MiB preserves the prior `4 rgs × ~1 MiB/rg` footprint.

## Test plan

- [x] Dedicated `ComputeRowGroupsPerCell` unit tests with hardcoded
expected outputs pin helper behavior independently of the translator
integration tests.
- [x] `GroupChunkTranslatorTest` / `ManifestGroupTranslatorTest` read
`GetCellTargetSizeBytes()` so assertions track production.
- [ ] CI: `ci-v2/build-ut-cov`, `ci-v2/e2e-amd`
- [ ] Manual: toggle `queryNode.segcore.storageV2.cellTargetSizeBytes`
at runtime and confirm newly loaded segments observe the new pack size.

issue: #49204

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 14:41:45 +08:00
693eb2a265 enhance: pin scalar index only after committing to ScalarIndex exec path (#49238)
issue: #49237

## Summary

`SegmentExpr::InitSegmentExpr()` was unconditionally pinning the scalar
index via `PinIndex()` in its ctor. On a tiered-storage
`ChunkedSegmentSealedImpl`, that triggers `CacheSlot::PinCells()` and a
cold fetch even for expressions whose exec path is `TextIndex` /
`PkIndex` / `JsonStats` / `RawData` — none of which ever touch
`pinned_index_`.

Observed impact: `TEXT_MATCH(field, "…")` on an `enable_match=true`
VARCHAR field slows down after an `INVERTED` AUTOINDEX is added on the
same field, because every expr construction cold-loads the scalar index
cell that `TEXT_MATCH` never reads.

This PR restructures `SegmentExpr::DetermineExecPath()` so that
`EnsurePinnedIndex()` runs only once we've fully committed to
`ExprExecPath::ScalarIndex`. Pin happens **iff** `exec_path_ ==
ScalarIndex`.

## Changes

- `InitSegmentExpr()` sets `num_index_chunk_` speculatively from
`segment_->HasIndex()` (cheap bitset, no pin), so
`HasCompatibleScalarIndex()` can decide existence without triggering a
cold fetch.
- New `SegmentInterface::GetJsonFlatIndexNestedPath()` exposes the
`JsonFlatIndex` nested path already stored in segment JSON-index
metadata; `SegmentSealed` overrides it with a mirror of `PinJsonIndex`'s
prefix-matching loop, but without pinning.
- `IsJsonPathCompatible()` is extracted from
`HasCompatibleScalarIndex()` and rewritten to use the new segment API,
removing its dependency on `pinned_index_`.
- Base `DetermineExecPath()` short-circuits to `RawData` when either
check fails and only then calls `EnsurePinnedIndex()`. A post-pin
reconciliation guard also falls back to `RawData` if `HasIndex()` was
speculatively true but `scalar_indexings_` had no entry (rare edge case:
vector/binlog-index-only field or a load transient).

All subclass `DetermineExecPath` short-circuits (`TextMatch` /
`PhraseMatch` / `PkIndex` / `JsonStats`) already return before reaching
the base, so they still never pin. Downstream `pinned_index_[i]`
accessors are gated on `exec_path_ == ScalarIndex` (either explicitly or
via `UseIndexCursor()` / `ProcessIndexChunks` helpers), so the invariant
is preserved without changing dispatch sites.

Observable behavior of `HasCompatibleScalarIndex()` and
`CanUseNestedIndex()` is unchanged: the JSON-path narrowing moves into
`IsJsonPathCompatible()` but the combined decision in
`DetermineExecPath` is identical, and `CanUseNestedIndex()`'s
`pinned_index_.empty()` guard keeps the external return value the same
for every valid state.

## Test plan

- [ ] `make core` + segcore C++ UT (`tests/cpp_test/`), especially
expression-related suites
- [ ] `make test-querynode` / `make test-proxy`
- [ ] Manual: with tiered storage / lazy loading on QueryNode, compare
`TEXT_MATCH(field, "...")` P99 latency on a collection that has
`enable_match=true` VARCHAR + AUTOINDEX `INVERTED` on the same field —
expect no cold-fetch of the scalar INVERTED cell per query
- [ ] Regression: scalar `==` / `IN` / range / `LIKE` / JSON-path / PK
queries still use the correct index path (`exec_path_ == ScalarIndex` →
`pinned_index_` populated)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:41:45 +08:00
919bdf15ba enhance: expose arrow IO thread pool capacity via paramtable (#49208)
## Summary

Expose Arrow's internal IO thread pool capacity as a refreshable
paramtable knob so operators can raise it beyond Arrow's fixed default
of 8, independently of segcore `HIGH/MIDDLE` pools and
`minio.maxConnections`.

- New keys (both refreshable, `common` scope):
- `common.arrow.ioThreadPoolCoefficient` (default `0` → keep Arrow's
built-in default)
  - `common.arrow.ioThreadPoolMaxCapacity` (default `0` → no cap)
- Effective size = `coefficient × CPU cores`, clamped by `maxCapacity`
when `> 0`.
- Wired through `init_c.{h,cpp}` + `initcore` + QueryNode paramtable
watcher; hot reloads apply without restart.

## Why

`GetIOThreadPool` runs the async range reads behind `ReadRangeCache`,
which is what actually issues S3 `GetObject` for storage v2 reads.
Milvus never calls `SetIOThreadPoolCapacity`, so this pool sticks at
Arrow's fixed default (`kDefaultNumIoThreads = 8` in arrow 17). Off-CPU
profiling on a QueryNode under heavy storage v2 load shows ~62% of
`HIGH`-pool wait time sitting on `curl_easy_perform -> poll` —
`HIGH`-pool threads blocked inside `ReadRangeCache::Wait` because
Arrow's IO pool cannot dispatch their range reads fast enough.

## Test plan

- [ ] CI: `ci-v2/build-ut-cov`, `ci-v2/e2e-amd`
- [ ] Manual: set `common.arrow.ioThreadPoolCoefficient=4` on a
QueryNode, confirm the `arrow io thread pool capacity set to N` log at
startup and that the pool is resized on subsequent config edits.
- [ ] Manual: re-run the storage-v2-heavy workload that produced the
off-CPU profile and confirm `curl_easy_perform -> poll` share drops from
~62%.

issue: #49207

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 18:11:45 +08:00
sparknackandGitHub f332aebcd0 enhance: decouple parquet metadata loading from GroupChunkTranslator (#49026)
issue: #49025

## Summary

- Extract parquet metadata loading out of `GroupChunkTranslator`'s
constructor into a free `LoadGroupChunkMetadata` function declared in
`segcore/ChunkedSegmentSealedImpl.h`. Returns `{ row_group_meta_list,
parquet_stats_by_field }`.
- When `ENABLE_PARQUET_STATS_SKIP_INDEX` is off (default), the loader
only reads the lightweight `RowGroupMetadataVector` (24 B per row group)
and skips `GetParquetMetadata()` entirely — no `parquet::FileMetaData`
is loaded or retained.
- When on, stats are extracted during the same parallel file pass and
the `FileMetaData` is released before the translator is constructed.
- `GroupChunkTranslator` now accepts
`std::vector<milvus_storage::RowGroupMetadataVector>&&` directly; the
`parquet_file_metas()` / `field_id_mapping()` getters are removed.
- Updated both call sites
(`ChunkedSegmentSealedImpl::load_column_group_data_internal`,
`JsonKeyStats`) and the translator unit test.

## Test plan

- [x] Local build passes (`milvus_segcore`, `milvus_index`)
- [x] Existing `GroupChunkTranslatorTest` updated and compiles
- [ ] Full CI — C++ unit tests + integration tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-04-17 18:13:42 +08:00
sparknackandGitHub e537d292a1 fix: await background load futures during cancellation and fix loadingTimeoutMs default (#48855)
## Summary
- Await background load futures in `GroupChunkTranslator` and
`ManifestGroupTranslator` cancellation cleanup paths to prevent
use-after-free / dangling futures
- Add `CheckCancellation` calls in `LoadCellBatchAsync` loop for prompt
cancellation
- Fix `tieredStorage.loadingTimeoutMs` default from `0` (immediate
failure) to `-1` (no timeout)

issue: #48854

## Test plan
- [x] Added unit test `CancellationStopsMidBatchPush` verifying
mid-batch cancellation stops loading and raises `FollyCancel`
- [ ] CI passes

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-04-13 16:39:40 +08:00
b4d61e5ecc enhance: add thread pool metrics for QueryNode C++ executor and storage pools (#48687)
## Summary
- Add per-pool Prometheus metrics (`pool=search`/`pool=load`) for the
folly `CPUThreadPoolExecutor` pools split in #48675, covering pool_size,
inflight tasks, executing tasks, queue duration, execute duration, and
cancellation counters.
- Add Prometheus metrics for the custom storage `ThreadPool`
(high/middle/low priority): capacity, active threads, idle threads,
queue depth, submitted/completed task counters.
- Fix stale active gauge on Worker thread shutdown/shrink paths and data
race in `SetMetrics()` initial value seeding.

issue: #33132

## Test plan
- [ ] Verify metrics are exposed via `/metrics` endpoint on a running
QueryNode
- [ ] Confirm `internal_cgo_pool_size{pool="search"}` and
`internal_cgo_pool_size{pool="load"}` report correct thread counts
- [ ] Confirm `internal_storage_pool_*` metrics report for
high/middle/low priority pools
- [ ] Verify gauge values stay consistent after pool shrink (idle
timeout)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 20:37:40 +08:00
d3ec9ee750 enhance: PK compressed storage and lazy system index for segment loading optimization (#48771)
## Summary

- Add bitpacking-based CompressedInt64PkArray for int64 PK compression
(50-75% memory reduction)
- Defer timestamp/PK index construction to first access via lazy
SystemIndexTranslator (zero S3 I/O on load path)
- Parallelize StorageV2 row group metadata fetching across files
- Skip OffsetOrderedArray for sorted-by-pk segments (save ~12 bytes/row)

issue: #48770

## Changes

### PK Compressed Storage (4 commits)
- `CompressedInt64PkArray`: block-based encoding with per-block min +
variable-width bitpacked deltas, O(1) random access via block index
- `build_offset2pk()` on `InsertRecord`: builds compressed offset→pk for
both sorted and unsorted segments, enabling fast `FillPrimaryKeys` path
- Unit tests covering edge cases: empty, single element, large ranges,
INT64_MAX boundaries

### Segment Loading Optimization (2 commits)
- Prefetch pk and timestamp column chunks before sequential access
- Parallelize row group metadata fetching using HIGH thread pool (fix:
capture loop variable by value to avoid dangling reference)

### Lazy System Index - SystemIndexTranslator (2 commits)
- `TimestampIndexTranslator`: builds timestamp index lazily on first
`mask_with_timestamps` / `bulk_subscript` call
- `PkIndexTranslator`: builds pk2offset / offset2pk lazily on first
`Contain` / `search` call
- V1 compatibility: fallback to `insert_record_` when translator slot is
empty
- Sorted-by-pk: skip OffsetOrderedArray (pk2offset) construction, only
build offset2pk

### Bug Fixes (4 commits)
- Fix `Contain()` returning false for sorted-by-pk segments (missing
binary search path)
- Remove `TimestampData` from `TimestampIndexCell` to prevent DList
deadlock (read timestamp from column directly)
- Remove stale `system_ready_count_++` references; init empty timestamps
for zero-row segments so `is_system_field_ready()` returns true
- Fix dangling reference in parallel metadata fetch lambda
(GroupChunkTranslator + JsonKeyStats)
- Fix same-timestamp delete check in StorageV2 lazy-init path: when
`insert_record_.timestamps_` is empty, use a callback to read insert
timestamps from the timestamp column instead of skipping the check
(which incorrectly allowed deletes with matching timestamps to take
effect)

## Test plan

- [ ] CompressedInt64PkArray unit tests pass
- [ ] StorageV2 lazy system index tests pass
(TestLazySystemIndexesOnUnsortedSegment,
TestLazySystemIndexesOnSortedSegment)
- [ ] TestSameTimestampDeleteNotEffective passes (verifies delete_ts ==
insert_ts is correctly rejected in StorageV2 lazy path)
- [ ] Load collection with int64 PK fields, verify reduced RSS
- [ ] Load sorted-by-pk segments, verify Contain() and delete work
correctly
- [ ] Concurrent segment loading does not deadlock on TimestampIndex
access


🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
Co-authored-by: Buqian Zheng <zhengbuqian@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 11:05:39 +08:00
91cf2cce39 enhance: add visibilityFilterEnabled and bloomFilterEnabled toggles for querynode optimization (#48701)
## Summary
- Add `common.visibilityFilterEnabled` toggle to bypass row visibility
filtering (timestamp, delete, and TTL) on querynode. When disabled, all
rows are returned regardless of insert/delete timestamps, improving
performance for workloads that don't need timestamp consistency.
- Add `common.bloomFilterEnabled` toggle to skip bloom filter/PK stats
loading on querynode, reducing memory for workloads without delete or
search-by-id. Delete forwarding falls back to broadcast mode when
disabled.

issue: #48703

## Test plan
- [ ] Unit tests for bloom filter disabled path
(`TestLoadSegmentsWithoutBloomFilter`, `TestLoadWithoutBloomFilter`)
- [ ] Unit tests for nil candidate broadcast in delete forwarding
- [ ] Unit tests for visibility filter bypass with
`visibilityFilterEnabled=false`
- [ ] Verify no nil pointer panics when bloom filter is disabled
- [ ] Integration test with `bloomFilterEnabled=false` and
`visibilityFilterEnabled=false`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 19:49:41 +08:00
sparknackandGitHub d8bc52d470 enhance: loading overhead estimation and LoadingOverheadConfig for caching layer (#48773)
## Summary

- Change \`estimated_byte_size_of_cell\` return semantics from
\`{loaded, total_loading}\` to \`{loaded, loading_overhead}\` across
**all** translators
- Integrate with milvus-common \`LoadingOverheadConfig\` API to cap
total loading overhead per group via \`LoadingOverheadTracker\`
- Add cell-batch loading constants (\`kChannelCapacityMultiplier\`,
\`kLoadingOverheadInflationRatio\`) to \`memory_planner.h\`
- Update milvus-common to \`sparknack/milvus-common\` loading-opt branch
(\`b2efad3\`)

issue: #48772

## Changes

### 1. Overhead semantics change (all translators)
All \`estimated_byte_size_of_cell\` implementations updated so the
second element is pure overhead (temporary buffers during loading), not
total loading cost:

| Translator | mmap overhead | non-mmap overhead |
|-----------|--------------|-------------------|
| ChunkTranslator | \`{2x mem, 1x disk}\` | \`{1x mem, 0}\` |
| DefaultValueChunkTranslator | \`{0, 0}\` | \`{0, 0}\` |
| InterimSealedIndexTranslator | build buffer only | build buffer only |
| SealedIndexTranslator | \`max - final\` | \`max - final\` |
| TextMatchIndexTranslator | temp mem during load | temp disk during
load |
| BsonInvertedIndexTranslator | temp mem (download) | temp disk (local
file) |
| GroupChunkTranslator | via LoadingOverheadConfig | via
LoadingOverheadConfig |
| ManifestGroupTranslator | via LoadingOverheadConfig | via
LoadingOverheadConfig |

### 2. LoadingOverheadConfig for cell-batch translators
\`GroupChunkTranslator\` and \`ManifestGroupTranslator\` set
\`Meta::loading_overhead\` with:
- \`upper_bound\`: \`max_inflight * max_cell_size * inflation_ratio\`
- \`group\`: per-translator-type + CellDataType

This prevents N concurrent column group loads from each reserving full
overhead independently.

### 3. Cell-batch loading constants
Added to \`memory_planner.h\`:
- \`kChannelCapacityMultiplier = 1.5\` — bounded channel capacity
relative to pool size
- \`kLoadingOverheadInflationRatio = 1.2\` — safety margin for overhead
estimation

### 4. milvus-common dependency
Points to \`sparknack/milvus-common\` loading-opt branch (\`b2efad3\`)
which adds:
- \`LoadingOverheadConfig\` struct in \`Translator.h\`
- \`LoadingOverheadTracker\` for per-group overhead capping
- Updated \`CacheSlot\` and \`DList\` to integrate tracker

## Test plan

- [ ] Existing unit tests pass
- [ ] Load collection with multiple column groups, verify reduced
overhead reservation in logs
- [ ] Verify LoadingOverheadTracker metrics show capped overhead


🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-04-08 14:17:38 +08:00
sparknackandGitHub a5185b5ff6 enhance: cancel async warmup before replacing or clearing indexes (#48366)
issue: https://github.com/milvus-io/milvus/issues/47902

When indexes are replaced (e.g., during reload) or cleared (e.g., during
segment release), any in-flight async warmup tasks on the old index must
be cancelled first. Without this, warmup tasks could race with the index
teardown, leading to wasted work.

This change:
- Adds cancel_warmup/cancel_and_erase/cancel_and_clear helpers for
scalar, ngram, and json indexes
- Calls CancelWarmup() on old indexes before erase/clear in
LoadScalarIndex, DropIndex, DropJSONIndex, and ClearData
- Deduplicates ngram and json index replacement logic

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-04-01 17:47:39 +08:00
sparknackandGitHub 3e1d75af72 enhance: bump milvus-common to 5983a18 with warmup timeout and runtime config support (#48505)
issue: #48507

Update milvus-common to 5983a18 which adds warmup loading timeout,
runtime config hot-reload via TieredStorageConfig, and DList reservation
fixes. Wire through the new warmup_loading_timeout parameter and add
UpdateTieredStorageConfig CGO binding with config change callbacks for
runtime updates.

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-03-30 20:19:31 +08:00
sparknackandGitHub 6dc8418eac enhance: add async warmup policy support for caching layer (#47627)
issue: #47902

Integrate milvus-common commit 7b54b6e which adds
CacheWarmupPolicy_Async and a prefetch thread pool for background cache
warmup. This enables segments to be marked as loaded immediately while
cache warming happens asynchronously, reducing load latency.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-03-10 14:45:23 +08:00
sparknackandGitHub 9f1a26384a enhance: eliminate redundant timestamp copy in sealed segments (#47689)
issue: #47872

Replace `ConcurrentVector<Timestamp>` with a lightweight `TimestampData`
class that pins column chunks directly (zero-copy) for StorageV2, and
falls back to owned `std::vector` for StorageV1.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-03-05 13:07:22 +08:00
sparknackandGitHub 49ec7b375e enhance: remove some redundant data copy in segcore (#47623)
issue: #44452

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-02-10 17:06:42 +08:00
sparknackandGitHub dbfae98dbc enhance: optimize index load async process (#47575)
issue: #47298

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-02-10 15:46:41 +08:00
sparknackandGitHub 446593f502 enhance: use differentiate load priorities by scenario (#47410)
issue: #43040

Implement intelligent LoadPriority assignment based on operation
scenarios,
allowing QueryNodes to prioritize critical operations over background
tasks.

**Background:**
Previously, all segment load operations used the same priority, which
could
cause issues when urgent operations (like search requests) competed with
background tasks (like balance) for resources.

**Solution:**
Centralize LoadPriority decisions in Checkers, with each Checker
understanding
its operational context and assigning appropriate priorities:

| Scenario | LoadPriority | Rationale |

|-----------------------|------------------------|------------------------------------|
| Recovery | HIGH | Restore data availability ASAP |
| User Load / Refresh | replica.LoadPriority() | Respect user's
configured priority |
| Stopping Balance | HIGH | Drain nodes quickly for shutdown |
| Normal Balance | LOW | Background optimization |
| Manual Balance | LOW | User maintenance, not urgent |
| Handoff | LOW | Growing→sealed, can wait |
| Index Update | LOW | Background maintenance |
| Stats Update | LOW | Background maintenance |

**Implementation:**

1. SegmentChecker: Determine priority by collection state
   - Check if segment exists in currentTarget (recovery vs new segment)
   - Check `collection.IsRefreshed()` to distinguish handoff from import

2. BalanceChecker: Add `isStoppingBalance` flag
   - Stopping balance uses HIGH to accelerate node draining
   - Normal balance uses LOW to avoid interfering with user operations

3. IndexChecker: Always use LOW for index/stats updates

4. Manual Balance: Manual balance uses LOW directly

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-02-05 17:29:51 +08:00
sparknackandGitHub a1708ae08a fix: fix DefaultValueChunk bugs for variable-length types and vectors (#47344)
issue: #45999
fix: #46000

1. Variable-length types (String, JSON, Array) buffer sharing bug:
StringChunk constructor calculates null bitmap size and offsets position
based on row_nums parameter. When sharing a buffer built for N rows with
a chunk claiming M rows (M != N), the offsets pointer would be wrong.
Fix: use separate buffers for primary cells and tail cell when they have
different row counts.

2. Vector types using wrong Arrow builder: Used BinaryBuilder
(variable-length) but ChunkWriter expects FixedSizeBinaryArray. Fix: use
CreateArrowBuilder(data_type, element_type, dim) which creates
FixedSizeBinaryBuilder.

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-02-03 18:27:53 +08:00
sparknackandGitHub b22240828b enhance: add loading timeout and cancellation support (#47033)
issue: #45353

This feature enables graceful cancellation of loading operations:
    
1. Add OpContext propagation through caching layer:
- Add `OpContext*` parameter to `get_cells()` in all Translator
implementations
- Add seperate `loadingTimeoutMs` configuration for cache slot loading
timeout

2. Add cancellation checks in load phases.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-01-23 18:47:32 +08:00
sparknackandGitHub f09f47f65c enhance: make DefaultValueChunk multi-cells to save memory usage (#46000)
issue: #45999 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
- Core invariant: DefaultValueChunkTranslator assumes a constant
per-value byte size (value_size()) for a field and therefore models
default-value storage as multiple deterministic, fixed-size cells
(num_cells(), cell_id_of(uid) == uid). A single contiguous
primary_buffer_ is built (optionally persisted to mmap) and sliced
per-cell; this invariant enables safe sharing of the same underlying
bytes across multiple Chunk views.
- Removed/simplified logic: per-field direct file_path writes and
duplicated make_chunk write paths were collapsed into a buffer-first
flow (ChunkBuffer + create_chunk_buffer + make_chunk_from_buffer). This
removes redundant per-field mmap/write code and allows multiple Chunk
instances to reuse a shared ChunkBuffer/ChunkMmapGuard instead of
performing independent writes.
- Why no data loss or regression: byte layout, alignment, padding and
per-row content are preserved because create_chunk_buffer implements the
same alignment/padding and writes identical bytes previously produced by
the direct make_chunk path; make_chunk_from_buffer constructs Chunk
views over those same bytes. DefaultValueChunkTranslator uses
deterministic math (total_rows_, num_rows_until_chunk_,
primary_cell_rows_) to slice rows—no rows are dropped, reordered, or
altered. Concrete code paths: callers that used create_group_chunk →
per-field make_chunk now use create_group_chunk → create_chunk_buffer →
make_chunk_from_buffer; DefaultValueChunkTranslator’s get_cells(),
estimated_byte_size_of_cell(), and value_size() produce the same
observable outputs as before for single-cell cases and correct per-cell
outputs for multi-cell cases.
- Enhancement / scope: adds multi-cell default-value chunks and optional
mmap-backed persistence plus shared-memory ChunkBuffer support. Changes
touch DefaultValueChunkTranslator (multi-cell behavior, value_size(),
primary_buffer_, mmap_dir_path_), ChunkWriter (ChunkBuffer,
create_chunk_buffer, make_chunk_from_buffer), and
ChunkedSegmentSealedImpl (per-field mmap decision and mmap_dir_path
propagation); comprehensive tests (mmap/non-mmap, nullable,
multi/single-cell) validate correctness.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-01-13 19:53:27 +08:00
sparknackandGitHub 2ea16b2f6d enhance: add caching layer resource management for streaming node (#46465)
issue: #41435

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added segment resource tracking and automatic memory/disk accounting
during inserts, deletes, loads and reopen.
  * Exposed a configuration to set interim index memory expansion rate.
* Added explicit loaded-resource charge/refund operations and Bloom
filter resource lifecycle management.

* **Bug Fixes**
* Ensured consistent memory-size vs. row-count calculations across
segment operations.
* Improved resource refunding and cleanup when segments are released or
closed.

* **Tests**
* Added comprehensive resource-tracking and concurrency tests, plus
Bloom filter accounting tests.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-01-12 15:47:27 +08:00
sparknackandGitHub e45db3dce6 fix: milvus-common update (#46641)
issue: #41435

- fix: avoid double destruction with placement new

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Pull Request Summary

**Bug Fix: milvus-common dependency update to address double destruction
with placement new**

- **Root Cause Resolution:** Updates the milvus-common library
dependency from commit 4d7781d to fbe5cf7 to fix a double destruction
issue that occurs when placement new is used for object construction.
The upstream fix ensures proper lifecycle management of objects
constructed with placement new semantics, preventing accidental
re-destruction of objects allocated in pre-allocated memory regions.

- **No Logic Changes in Milvus Core:** This PR contains only a
CMakeLists.txt version bump in
`internal/core/thirdparty/milvus-common/CMakeLists.txt`; no Milvus
codebase logic is modified, removed, or simplified. The fix is entirely
contained within the milvus-common library dependency fetched during the
build process.

- **Data Integrity and Behavior Preservation:** No behavior regression
or data loss is introduced. The change is a pure dependency update to
pull in an upstream bug fix. All memory management and object lifecycle
handling improvements are confined to the milvus-common library,
remaining transparent to Milvus core operations.

- **Issue Resolution:** Addresses issue #41435 by integrating the
corrected milvus-common version that prevents double destruction bugs
occurring in code paths that use placement new for memory-efficient
object construction.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2026-01-09 11:11:25 +08:00
sparknackandGitHub 0a2f8d4f63 enhance: map multi row groups into one cache cell (#46249)
issue: #45486

Introduce row group batching to reduce cache cell granularity and
improve
memory&disk efficiency. Previously, each parquet row group mapped 1:1 to
a cache
cell. Now, up to `kRowGroupsPerCell` (4) row groups are merged into one
cell.
This reduces the number of cache cells (and associated overhead) by ~4x
while
maintaining the same data granularity for loading.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Switched to cell-based grouping that merges multiple row groups for
more efficient multi-file aggregation and reads.
* Chunk loading now combines multiple source batches/tables per cell and
better supports mmap-backed storage.

* **New Features**
* Exposed helpers to query row-group ranges and global row-group offsets
for diagnostics and testing.
* Translators now accept chunk-type and mmap/load hints to control
on-disk vs in-memory behavior.

* **Bug Fixes**
* Improved bounds checks and clearer error messages for out-of-range
cell requests.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-12-23 14:57:18 +08:00
sparknackandGitHub 27e14d034f fix: prohibit hot-reloading of tiered storage parameters (#46437)
issue: #46443

Add `Forbidden: true` to all tiered storage related parameters to
prevent runtime configuration changes via etcd. These parameters are
marked as refreshable:"false" but that tag was only documentation - the
actual prevention requires the Forbidden field.

Without this fix, if tiered storage parameters are modified at runtime:
- Go side would read the new values dynamically
- C++ caching layer would still use the old values (set at InitQueryNode
time)
- This mismatch could cause resource tracking issues and anomalies

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-12-19 14:59:16 +08:00
sparknackandGitHub 5fb420b156 fix: milvus-common update (#45929)
issue: #41435

fix some usage tracking bugs in caching layer.

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-12-10 14:53:13 +08:00
sparknackandGitHub 8ef35de7ca enhance: always use buffered io for high load priority (#45900)
issue: #43040

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-29 00:03:08 +08:00
sparknackandGitHub 4b14ab14e3 enhance: mmap once for each group chunk (#45487)
issue: #45486

This commit refactors the chunk writing system by introducing a
two-phase
approach: size calculation followed by writing to a target. This enables
efficient group chunk creation where multiple fields share a single mmap
region, significantly reducing the number of mmap system calls and VMAs.

- Optimize `mmap` usage: single `mmap` per group chunk instead of per
field
- Split ChunkWriter into two phases:
  - `calculate_size()`: Pre-compute required memory without allocation
  - `write_to_target()`: Write data to a provided ChunkTarget
- Implement `ChunkMmapGuard` for unified mmap region lifecycle
management
  - Handles `munmap` and file cleanup via RAII
  - Shared via `std::shared_ptr` across multiple chunks in a group

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-26 10:37:08 +08:00
sparknackandGitHub 0392db6976 enhance: add cancellation checking in each operator and expr (#45354)
issue: #45353

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-26 10:15:07 +08:00
sparknackandGitHub 16acf8829b enhance: expr: only prefetch chunks once (#45554)
issue: https://github.com/milvus-io/milvus/issues/43611

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-18 15:51:41 +08:00
sparknackandGitHub 9d75d0393e enhance: some optimization of scalar field fetching in tiered storage scenarios (#45360)
issue: #43611

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-11 17:17:41 +08:00
sparknackandGitHub f815f57b82 enhance: check both eviction and warmup when estimate segment loading size (#45222)
issue: #44857

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-10 14:15:36 +08:00
sparknackandGitHub 9032bb7668 enhance: unify the aligned buffer for both buffered and direct I/O (#45323)
issue: #43040

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-06 10:53:33 +08:00
sparknackandGitHub 40b5e6b134 fix: avoid potential race conditions when updating the executor (#45230)
issue: #43040

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-11-04 14:25:33 +08:00
sparknackandGitHub 935160840c enhance: add a disk quota for the loaded binlog size to prevent load failure of querynode (#44893)
issue: #41435

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-19 19:44:01 +08:00
sparknackandGitHub 4bd30a74ca enhance: cachinglayer: add mmap and eviction support for TextMatchIndex (#44806)
issue: #41435, #44502

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-17 14:42:02 +08:00
sparknackandGitHub 3d3fa44745 fix: milvus-common update (#44798)
issue: #44501

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-15 11:24:00 +08:00
sparknackandGitHub df6a4dc1a0 fix: cachinglayer: avoid eviction during json handling (#44812)
issue: #44797

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-13 22:07:58 +08:00
sparknackandGitHub c8a4d6e2ef enhance: add cachinglayer management for TextMatchIndex (#44741)
issue: #41435, #44502

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-13 14:37:58 +08:00
sparknackandGitHub 6d5b41644b enhance: remove logical usage checks during segment loading (#44743)
issue: #41435

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-13 14:21:58 +08:00
sparknackandGitHub 7e750190b6 enhance: add a size getter for tantivy inverted index (#44609)
issue: #41435

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-10-10 17:43:57 +08:00
sparknackandGitHub c8eae818e0 fix: milvus-common update (#44637)
issue: #41435

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-09-29 22:37:45 +08:00
sparknackandGitHub 14c085374e fix: set mmap_file_raii_ to nullptr when mmap is disabled (#44516)
issue: #44510
related: #44501

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-09-24 11:50:03 +08:00
sparknackandGitHub ab64afba2f enhance: add storage resource usage for scalar search (#44414)
issue: #44212

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-09-22 14:28:06 +08:00
sparknackandGitHub 060fc61e80 fix: milvus-common commits update (#44339)
issue: #41435
related: #44268

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-09-12 12:43:57 +08:00
sparknackandGitHub e821468d2a fix: milvus-common commit update (#44304)
issue: #41435 
related: #44268

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-09-11 10:19:56 +08:00
sparknackandGitHub 4a01c726f3 enhance: cachinglayer: some metric and params update (#44276)
issue: #41435

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-09-10 11:03:57 +08:00
sparknackandGitHub 70c8114e85 enhance: cachinglayer: resource management for segment loading (#43846)
issue: #41435

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-08-29 11:37:50 +08:00
sparknackandGitHub 4fae074d56 enhance: add write rate limit for disk file writer (#43912)
issue: #43040

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-08-25 10:27:47 +08:00
sparknackandGitHub 9a31d88d49 fix: cachinglayer: config: align the watermark ratio in the YAML file… (#43910)
issue: #41435

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-08-18 17:53:44 +08:00
sparknackandGitHub 169be30a76 enhance: cachinglayer: reserve resource for inevictable cachecell (#43602)
issue: #41435

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-08-08 10:35:49 +08:00
sparknackandGitHub 544c7c0600 enhance: update cachinglayer default cache ratio to 0.3 (#43723)
issue: #41435

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-08-05 01:35:39 +08:00
sparknackandGitHub bdd65871ea enhance: tiered storage: estimate segment loading resource usage while considering eviction (#43323)
issue: #41435 

After introducing the caching layer's lazy loading and eviction
mechanisms, most parts of a segment won't be loaded into memory or disk
immediately, even if the segment is marked as LOADED. This means
physical resource usage may be very low. However, we still need to
reserve enough resources for the segments marked as LOADED. Thus, the
logic of resource usage estimation during segment loading, which based
on physcial resource usage only for now, should be changed.

To address this issue, we introduced the concept of logical resource
usage in this patch. This can be thought of as the base reserved
resource for each LOADED segment.

A segment’s logical resource usage is derived from its final evictable
and inevictable resource usage and calculated as follows:

```
SLR = SFPIER + evitable_cache_ratio * SFPER
```

it also equals to

```
SLR = (SFPIER + SFPER) - (1.0 - evitable_cache_ratio) * SFPER
```

`SLR`: The logical resource usage of a segment.
`SFPIER`: The final physical inevictable resource usage of a segment.
`SFPER`: The final physical evictable resource usage of a segment.
`evitable_cache_ratio`: The ratio of a segment's evictable resources
that can be cached locally. The higher the ratio, the more physical
memory is reserved for evictable memory.

When loading a segment, two types of resource usage are taken into
account.

First is the estimated maximum physical resource usage:

```
PPR = HPR + CPR + SMPR - SFPER
```

`PPR`: The predicted physical resource usage after the current segment
is allowed to load.
`HPR`: The physical resource usage obtained from hardware information.  
`CPR`: The total physical resource usage of segments that have been
committed but not yet loaded. When one new segment is allow to load,
`CPR' = CPR + (SMR - SER)`. When one of the committed segments is
loaded, `CPR' = CPR - (SMR - SER)`.
`SMPR`: The maximum physical resource usage of the current segment.
`SFPER`: The final physical evictable resource usage of the current
segment.

Second is the estimated logical resource usage, this check is only valid
when eviction is enabled:

```
PLR = LLR + CLR + SLR
```

`PLR`: The predicted logical resource usage after the current segment is
allowed to load.
`LLR`: The total logical resource usage of all loaded segments. When a
new segment is loaded, `LLR` should be updated to `LLR' = LLR + SLR`.
`CLR`: The total logical resource usage of segments that have been
committed but not yet loaded. When one new segment is allow to load,
`CLR' = CLR + SLR`. When one of the committed segments is loaded, `CLR'
= CLR - SLR`.
`SLR`: The logical resource usage of the current segment.

Only when `PPR < PRL && PLR < PRL` (`PRL`: Physical resource limit of
the querynode), the segment is allowed to be loaded.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-08-01 21:31:37 +08:00
sparknackandGitHub 4aabe23a45 enhance: update flat_hash_map.hpp to a modified version (#43506)
issue: #41435

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-07-31 20:09:36 +08:00
sparknackandGitHub 81694739ef fix: revert ska::flat_hash_set to std::unordered_set to address an un… (#43428)
issue: #43388

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-07-21 17:39:40 +08:00
sparknackandGitHub 9b4081e110 enhance: cachinglayer: some performance optimization (#42858)
issue: #41435

We compared the performance using the modified test_sealed.cpp, which
randomly accesses all rows in all chunks and counts the number of runs
within 3s.

## performance data comparison (ops/second)

chunk config: 1x1000

| Field Type | w/o cachinglayer (commit 640f526301) | w/ cachinglayer |
w/ cachinglayer + opt |
|---|---|---|---|
| Bool field | 82428 | -63.6% (29983) | +2.7% (84675) |
| Int8 field | 82228 | -63.3% (30166) | +2.4% (84163) |
| Int16 field | 82572 | -63.8% (29867) | +1.8% (84036) |
| Int32 field | 82797 | -63.7% (30031) | +1.5% (84043) |
| Int64 field | 81077 | -62.9% (30107) | +0.6% (81604) |
| Float field | 82678 | -63.4% (30266) | +1.8% (84146) |
| Double field | 81925 | -63.4% (29974) | +0.2% (82097) |
| Varchar field | 19933 | -19.6% (16027) | +18.9% (23690) |
| JSON field | 16519 | -96.8% (533) | +2.5% (16927) |
| Int array field | 7325 | -13.7% (6321) | -1.4% (7220) |
| Long array field | 6347 | -8.9% (5781) | -0.1% (6344) |
| Bool array field | 8275 | -14.0% (7116) | +0.4% (8311) |
| String array field | 2281 | -5.0% (2168) | +0.2% (2287) |
| Double array field | 6427 | -13.3% (5574) | -2.0% (6301) |
| Float array field | 7291 | -13.0% (6346) | -1.5% (7183) |
| Vector field | 27487 | -40.4% (16371) | -4.7% (26192) |
| Float16 vector field | 49773 | -54.6% (22601) | -5.9% (46834) |
| BFloat16 vector field | 49783 | -53.1% (23350) | -5.7% (46934) |
| Int8 vector field | 63871 | -59.0% (26179) | -6.2% (59926) |

---

chunk config: 10x1000

| Field Type | w/o cachinglayer (commit 640f526301) | w/ cachinglayer |
w/ cachinglayer + opt |
|---|---|---|---|
| Bool field | 3659 | -48.6% (1879) | +110.1% (7686) |
| Int8 field | 3410 | -45.3% (1864) | +123.9% (7636) |
| Int16 field | 3647 | -48.6% (1874) | +110.1% (7661) |
| Int32 field | 3647 | -48.8% (1866) | +109.6% (7645) |
| Int64 field | 3645 | -48.9% (1863) | +107.8% (7573) |
| Float field | 3647 | -49.0% (1861) | +109.5% (7639) |
| Double field | 3640 | -45.1% (1998) | +108.4% (7586) |
| Varchar field | 1594 | -23.9% (1213) | +20.6% (1922) |
| JSON field | 1202 | -26.5% (884) | +16.1% (1396) |
| Int array field | 602 | -12.3% (528) | +12.7% (678) |
| Long array field | 529 | -12.2% (465) | +7.5% (569) |
| Double array field | 537 | -13.0% (467) | +6.4% (571) |
| Vector field | 1520 | -37.9% (943) | -5.5% (1437) |
| Float16 vector field | 2607 | -47.0% (1382) | +6.4% (2774) |
| BFloat16 vector field | 2586 | -46.5% (1383) | +8.8% (2813) |
| Int8 vector field | 3101 | -47.3% (1633) | +41.9% (4400) |

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-07-17 11:20:51 +08:00
sparknackandGitHub 7e855f1046 enhance: add disk file writer with Direct IO support (#42665)
issue: #43040 

This patch introduces a disk file writer that supports Direct IO.

Currently, it is exclusively utilized during the QueryNode load process.

Below is its parameters:

1. `common.diskWriteMode`
This parameter controls the write mode of the local disk, which is used
to write temporary data downloaded from remote storage.
Currently, only QueryNode uses 'common.diskWrite*' parameters. Support
for other components will be added in the future.
The options include 'direct' and 'buffered'. The default value is
'buffered'.

2. `common.diskWriteBufferSizeKb`
Disk write buffer size in KB, only used when disk write mode is
'direct', default is 64KB.
Current valid range is [4, 65536]. If the value is not aligned to 4KB,
it will be rounded up to the nearest multiple of 4KB.

3. `common.diskWriteNumThreads`
This parameter controls the number of writer threads used for disk write
operations. The valid range is [0, hardware_concurrency].
It is designed to limit the maximum concurrency of disk write operations
to reduce the impact on disk read performance.
For example, if you want to limit the maximum concurrency of disk write
operations to 1, you can set this parameter to 1.
The default value is 0, which means the caller will perform write
operations directly without using an additional writer thread pool.
In this case, the maximum concurrency of disk write operations is
determined by the caller's thread pool size.

Both parameters can be updated during runtime.

---------

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-07-02 22:18:44 +08:00
sparknackandGitHub 8ccb875e41 enhance: add simde package (#40943)
issue: #40942

Add simde package, which can make porting SIMD code to other
architectures much easier.

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-04-21 12:18:40 +08:00
sparknackandGitHub 3f2f57c67f fix: add collection flush before sparse searching in pytest (#40522)
issue: #40501

Signed-off-by: Shawn Wang <shawn.wang@zilliz.com>
2025-03-10 22:10:05 +08:00