Commit Graph

5577 Commits

Author SHA1 Message Date
Cursor Agent
edd1f75a9b Add comprehensive code navigation documentation
Create hierarchical documentation under docs/code-nav/ to serve as
an architectural map and onboarding guide for developers and AI agents.

30 markdown files organized into:
- Architecture.md: high-level overview, deployment modes, layered
  architecture, data flow, on-disk structure, key design decisions
- Navigation.md: entry point linking all docs with descriptions
- components/ (15 files): segment, collection, shard, storage,
  vector-storage, payload-storage, id-tracker, indexes,
  payload-indexes, quantization, segment-optimizer, consensus,
  replication, api-layer, rbac-and-auth
- execution-paths/ (6 files): upsert, search, collection-create,
  snapshot, optimization, startup
- utilities/ (7 files): wal, gridstore, sparse-index, posting-list,
  gpu, edge, common-utils

Every file references actual Rust types, file paths, and function
names. All files are under 500 lines and cross-linked throughout.

Made-with: Cursor
2026-03-26 08:01:52 +00:00
Roman Titov
bcdf2d2577 Replace MmapUniversal with MmapFile (#8505) 2026-03-25 19:37:45 +01:00
Luis Cossío
3af9349e83 impl populate for CachedSlice (#8462)
* impl populate

* nits
2026-03-25 13:59:02 -03:00
Roman Titov
a7550f893f Universal MmapFile that can read any T (#8493) 2026-03-25 16:57:53 +01:00
qdrant-cloud-bot
f87025e476 Validate collection names in snapshot endpoints (#8503)
Snapshot endpoints used raw `web::Path<String>` / `web::Path<(String, ...)>`
instead of validated path types, allowing invalid collection names (including
NUL bytes) to bypass `validate_collection_name` checks and reach the
filesystem, causing 500 errors.

Replace all raw path extractors with `valid::Path<CollectionPath>` and new
validated structs (`CollectionSnapshotPath`, `CollectionShardPath`,
`CollectionShardSnapshotPath`) that enforce legacy collection-name validation,
consistent with the rest of the API.

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-25 16:54:03 +01:00
Luis Cossío
7f106ce397 impl UniversalRead for local disk cache (#8368)
* checkout from `ssd-cache-wip`

* impl UniversalRead for CachedFile

* use `CachedSlice` for `UniversalRead` implementation

* block exhaustion test

* fix block exhaustion error

* fix alignment on owned path

* merge CachedFile into CachedSlice

* propagate io errors

* self-review

- log warning if long wait
- Option for RequestState
- clippy

* handle coderabbit's comments

* fix num read bytes check

* don't allocate twice for cache misses

* not for windows, sorry

* no more dead code

* use atomic for file id

* update cache controller description

* rebase fixes

* Self: Sized

* Use imports

* Remove with_global (unused)

* Add TODO

* move common::disk_cache -> universal_io::disk_cache

---------

Co-authored-by: xzfc <xzfcpw@gmail.com>
2026-03-25 11:39:26 -03:00
Jojii
6fc6bcc5b3 Don't insert deferred points into sparse index (#8435)
* Don't insert deferred points into sparse index

# Conflicts:
#	lib/segment/src/segment/tests.rs
#	lib/segment/src/segment_constructor/segment_constructor_base.rs

# Conflicts:
#	lib/segment/src/segment_constructor/segment_constructor_base.rs

* Clippy

* Assert consistency of deferred_internal_id var

* Return before SparseVector conversion in case of deferred point

* Use debug_assert instead
2026-03-25 15:37:32 +01:00
qdrant-cloud-bot
401cb7f12c Add #[must_use] to RAII guard and task handle types (#8499)
* Add `#[must_use]` to RAII guard and task handle types

These types rely on being held for a scope — dropping them immediately is
almost always a bug:

- `StoppingGuard`: sets `is_stopped` flag on drop
- `UpdateGuard`: decrements update counter on drop
- `UpdatesGuard`: releases mutex preventing concurrent updates on drop
- `ClockGuard`: marks clock as inactive on drop
- `IsAliveGuard`: releases liveness lock on drop
- `ScopeTrackerGuard`: decrements scope counter on drop
- `CancellableAsyncTaskHandle`: detaches task on drop
- `StoppableTaskHandle`: may abort task on drop (AbortOnDropHandle)

Made-with: Cursor

* Remove redundant function-level #[must_use] now covered by type

With ScopeTrackerGuard marked #[must_use] at the type level, the
function-level attributes on measure_scope(), measure(),
track_create_snapshot_request(), and count_snapshot_creation() are
redundant and trigger clippy::double_must_use.

Made-with: Cursor

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-25 14:51:38 +01:00
qdrant-cloud-bot
ccf6f7a680 Add REST API for reading audit logs across the cluster (#8498)
* Add REST API for reading audit logs across the cluster

Introduces a new `GET /audit/logs` endpoint that retrieves audit log
entries from all peers in the cluster. The API supports filtering by
time range (time_from/time_to), dynamic key=value field filters, and
a built-in limit parameter to prevent reading too many logs at once.

- Add `audit_reader` module in storage crate for efficient file-based
  log retrieval, selecting only files whose date range overlaps the
  query window
- Add `GetAuditLog` internal gRPC RPC for cross-peer log retrieval
- Add `GET /audit/logs` REST endpoint restricted to management access
- Aggregate and sort results from all peers by timestamp (newest first)

Made-with: Cursor

* [AI] Update filter_files_by_time_range make it aware of the log rotation granulatity (either hourly or daily)

* [AI] For AuditLogParams, try to use DateTime types natively into serde, instead of manual parsing

* [AI] Refactor API into separate file, propagate timeout, use spawn-blocking

* [AI] introduce cancellation token

* [AI] move timestamp to constant

* small manual fixes

* review fixes part 1

* review: switch to POST instead of GET

* [AI] review: sorting update

* [AI] use strict typing

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
Co-authored-by: Andrey Vasnetsov <andrey@vasnetsov.com>
2026-03-25 12:46:53 +01:00
xzfc
63c2e7b8d6 Propagate OperationResult (#8433) 2026-03-25 10:36:07 +00:00
qdrant-cloud-bot
dcd5f7a7ed Add struct destructuring to catch missing fields at compile time (#8497)
Destructure structs in conversions, key/match functions, and config
builders so the compiler will error when new fields are added but not
handled. This prevents a common class of bugs where a newly added
struct field is silently ignored.

Covered spots:
- RecommendPointGroups → RecommendGroupsRequestInternal (15 fields)
- ShardTransferTelemetry ↔ ShardTransferInfo (7 fields, both directions)
- ReshardingTelemetry ↔ ReshardingInfo (6 fields, both directions)
- HwMeasurementAcc → HardwareUsage (7 fields, 3 call sites)
- VectorParams destructuring in optimizers_builder and config (7 fields)
- SparseVectorParams destructuring in optimizers_builder (2 fields)
- ShardTransfer → ShardTransferRestart (5 fields)
- ReshardState::matches and ReshardState::key (5 fields each)
- ShardTransfer::key and ShardTransferRestart::key (4 fields each)
- SnapshotDescription → grpc (4 fields)
- WithLookup REST → internal (3 fields)
- SegmentConfigV5 → SegmentConfig (5 fields)

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-24 15:53:56 +01:00
Jojii
1a2406dacb Fix deferred point count across multiple shards (#8496)
* Fix deferred point count across multiple shards

* Count def-points correctly if first shard has no def-points
2026-03-24 13:50:02 +01:00
Ivan Pleshkov
81f53c9ad5 Deferred updates by filter (#8485)
* deferred updates by filter

* Don't use points.retain()

---------

Co-authored-by: jojii <jojii@gmx.net>
2026-03-24 11:59:56 +01:00
Ivan Boldyrev
2a0b95b08d Further split segment traits (#8434)
* Refactor: `SearchSegmentEntry` for search ops

* Move `has_deferrend_points_method`

to `SearchSegmentEntry`

* Reorg imports

* Renamings per review

* fixup! Renamings per review

* `StorageSegmentEntry` trait

It contains methods dealing with storage and syncronization

* Move index methods from `ReadSegmentEntry`

to `SegmentEntry`

* Add `_concurrent` suffix to some methods

* move field index methods into NonAppendableSegmentEntry

---------

Co-authored-by: generall <andrey@vasnetsov.com>
2026-03-24 10:02:53 +01:00
qdrant-cloud-bot
45b551a72c build(deps): sync Cargo.toml version floors with Cargo.lock (#8495)
Bump minimum version requirements to match what Cargo.lock already
resolved to. No functional change — these versions were already being
used at build time.

- ahash: 0.8.11 -> 0.8.12
- charabia: 0.9.7 -> 0.9.9
- chrono: 0.4.43 -> 0.4.44
- config: 0.15.13 -> 0.15.22
- crc: 3.3.0 -> 3.4.0
- fs-err: 3.2.2 -> 3.3.0
- futures-util: 0.3.31 -> 0.3.32
- num_threads: 0.1.6 -> 0.1.7
- quickcheck: 1.0.3 -> 1.1.0
- regex: 1.11.3 -> 1.12.3
- rustls: 0.23.35 -> 0.23.37
- rustls-pki-types: 1.12.0 -> 1.14.0
- slog: 2.7.0 -> 2.8.2
- tokio: 1.49.0 -> 1.50.0
- tower: 0.5.2 -> 0.5.3

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-24 09:24:31 +01:00
dependabot[bot]
7d6814dae4 build(deps): bump quick_cache from 0.6.19 to 0.6.21 (#8491)
Bumps [quick_cache](https://github.com/arthurprs/quick-cache) from 0.6.19 to 0.6.21.
- [Release notes](https://github.com/arthurprs/quick-cache/releases)
- [Commits](https://github.com/arthurprs/quick-cache/compare/v0.6.19...v0.6.21)

---
updated-dependencies:
- dependency-name: quick_cache
  dependency-version: 0.6.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-24 07:52:16 +01:00
dependabot[bot]
45d3759c62 build(deps): bump env_logger from 0.11.9 to 0.11.10 (#8492)
Bumps [env_logger](https://github.com/rust-cli/env_logger) from 0.11.9 to 0.11.10.
- [Release notes](https://github.com/rust-cli/env_logger/releases)
- [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/env_logger/compare/v0.11.9...v0.11.10)

---
updated-dependencies:
- dependency-name: env_logger
  dependency-version: 0.11.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-24 07:51:29 +01:00
dependabot[bot]
656196e952 build(deps): bump arc-swap from 1.8.2 to 1.9.0 (#8490)
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 1.8.2 to 1.9.0.
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v1.8.2...v1.9.0)

---
updated-dependencies:
- dependency-name: arc-swap
  dependency-version: 1.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 16:28:11 -03:00
dependabot[bot]
d794ebeeb2 build(deps): bump config from 0.15.21 to 0.15.22 (#8489)
Bumps [config](https://github.com/rust-cli/config-rs) from 0.15.21 to 0.15.22.
- [Changelog](https://github.com/rust-cli/config-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/config-rs/compare/v0.15.21...v0.15.22)

---
updated-dependencies:
- dependency-name: config
  dependency-version: 0.15.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 16:26:15 -03:00
dependabot[bot]
e870f30b28 build(deps): bump zerocopy from 0.8.42 to 0.8.47 (#8488)
Bumps [zerocopy](https://github.com/google/zerocopy) from 0.8.42 to 0.8.47.
- [Release notes](https://github.com/google/zerocopy/releases)
- [Changelog](https://github.com/google/zerocopy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google/zerocopy/compare/v0.8.42...v0.8.47)

---
updated-dependencies:
- dependency-name: zerocopy
  dependency-version: 0.8.47
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 16:25:52 -03:00
qdrant-cloud-bot
424bc2c265 Enable async_scorer in integration tests (#8487)
* Enable async_scorer in integration tests

Enable `async_scorer=true` for all openapi and shell-based integration
tests by setting the environment variable in `integration-tests.sh`.
This exercises the io_uring vector storage path (on Linux) across all
vector configurations tested there, with graceful fallback if io_uring
is unavailable on the CI runner.

Made-with: Cursor

* Scope async_scorer to test_points_search consensus test only

Revert the blanket async_scorer=true from integration-tests.sh to keep
the normal mmap path covered. Instead, enable it via extra_env in just
the test_points_search consensus test, so we exercise the io_uring path
without losing coverage of the non-io_uring path on Linux.

Made-with: Cursor

* Parametrize test_points_search for sync/async scorer modes

Use pytest.mark.parametrize to run test_points_search twice: once with
the default scorer (sync_scorer) and once with async_scorer=true. This
exercises both the normal mmap and io_uring paths in a single test.

Made-with: Cursor

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-23 18:08:55 +01:00
Arnaud Gourlay
8179c3bec0 Test all shard transfer methods for deferred points (#8447)
* Test all shard transfer methods for deferred points

* WAL delta carries deferred points

* add point count assertions

- snapshot: asserts target_visible == source_visible — deferred state preserved exactly
- stream_records: asserts target_visible >= source_visible — points may not be deferred on target
2026-03-23 18:07:54 +01:00
tellet-q
ca6beee059 Adjust debug ShardTransferRestart logline format to match ShardTransfer's (#8387)
* Adjust debug logline's format of
ShardTransferRestart to match with ShardTransfer

* Convert into shardtransfer

* Deconstruct ShardTransferRestart struct
2026-03-23 16:21:27 +01:00
Excellencedev
3230f1d952 Implement Per collection metrics for Promethus (#8214)
* Implement Per-Collection Prometheus Metrics

* Update config/config.yaml

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update tests/per_collection_metrics_test.sh

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update tests/per_collection_metrics_test.sh

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix ci

* comment

* Update tests/per_collection_metrics_test.sh

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* adress revew

* fix: linter

* refactor: cardinality limit, anonymize fix, cleanup

- Add max_per_collection_metrics config (default 256) to bound
  per-collection label cardinality
- Fix anonymize: strip per_collection_responses entirely instead of
  leaking hashed collection names
- Move CollectionName into requests_telemetry, remove
  telemetry_context.rs
- Add unit tests for cardinality limits
- Add integration test assertions for default mode
- Regenerate OpenAPI spec
- Document why internal gRPC doesn't attach CollectionName

* avoid cloning

* fix: address pr reviews

* fix: linter

* fix: linter

* feat: enforce {name} in actix api

* chore: remove empty line

* feat: add actix pre-commit hook

* feat: potential enforce tonic collection name

* feat: use proc_macro instead

* feat: use collection_name instead of name

* feat: add tonic telemetry tests

* fix: linter

* fix: linter

* chore: remove unneccessary clone

* fix: use collection_name everywhere

* fix: python tests and openapi

* chore: simplify collection_name tests

* actix collection_name enforcign: use relative path in test + avoid grep

* fix: remove macro

* chore: add some comment to telemetry_wrapper

* fix: clippy

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Daniel Boros <dancixx@gmail.com>
Co-authored-by: generall <andrey@vasnetsov.com>
2026-03-23 15:19:02 +01:00
Krzysztof Teodorowski
d116e3c158 fix(wal-delta): enforce cutoff before equal-clock pruning (#8346) (#8475) 2026-03-23 15:07:18 +01:00
Andrey Vasnetsov
fe54b9c131 [AI] use collback to read bytes from vector storage (#8484) 2026-03-23 13:50:07 +01:00
Arnaud Gourlay
f1f03bb3e8 Fix shard transfer fallback for deferred points (#8465) 2026-03-23 13:16:01 +01:00
Andrey Vasnetsov
77e5c326e9 [AI] implement wait override (#8476) 2026-03-23 13:13:55 +01:00
xzfc
6ddb81d1b6 Propagate OperationResult [3/4]: estimate_cardinality (#8446) 2026-03-23 11:51:48 +00:00
qdrant-cloud-bot
250ea4573a Fix panic from itertools format_with in optimizer log (#8480)
The `tracing-log` formats the message twice. The formatter returned by
Itertools::format_with panics when formatted twice.
2026-03-23 11:31:30 +00:00
qdrant-cloud-bot
9f34161036 build(deps): bump tar from 0.4.41 to 0.4.45 (#8482)
Bumps [tar](https://github.com/alexcrichton/tar-rs) from 0.4.41 to 0.4.45.
- [Commits](https://github.com/alexcrichton/tar-rs/compare/0.4.41...0.4.45)

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-23 11:37:54 +01:00
Andrey Vasnetsov
344425e714 remove incorrect assertion (#8481) 2026-03-23 10:41:16 +01:00
Tim Visée
8b1ca256f5 Allow peer to bootstrap with used URI if empty (#8301)
* [ai] Allow peer to bootstrap with existing URI if peer has no shards

Prompt:

I have a Qdrant cluster in distributed mode with some nodes registered
in consensus. If I bootstrap a new node with an URL that is already used
it is rejected and an error is returned. I would like to change this
behavior and allow this to happen. This would effectively replace a peer
because internally we'd drop the existing peer first, and then we'd add
the new peer so we can reuse the same peer URL. We must still reject
bootstrapping with the same URL if the peer that used the URL before us
still has any shards on it.

* [ai] Add test to assert new behavior, can rejoin if empty

Prompt:

Add two tests to assert the new behavior.

The first test should:
- create a cluster
- create a collection
- bootstrap a new peer
- kill and delete the local data for this peer without removing it from consensus
- bootstrap a new peer but reuse the URI of the peer we just killed to rejoin
- bootstrapping is expected to succeed

The second test should:
- create a cluster
- create a collection
- bootstrap a new peer but reuse the URI of the last node
- bootstrapping is expected to fail because the node being replaced has data on it

* [ai] Attempt to fix new tests

* Reformat

* [ai] Fix deadlock when rejoining with same peer URI

* [ai] Add test to ensure existing peer stops consensus on replace
2026-03-23 09:59:49 +01:00
Andrey Vasnetsov
4c41ddfdd0 account for deferred points in proxies (#8477) 2026-03-23 09:54:07 +01:00
Andrey Vasnetsov
8733d9f516 [AI] use T in immutable_dense_vectors (#8472) 2026-03-20 22:24:49 +01:00
Andrey Vasnetsov
454f11b515 Fix io_uring reads: use byte offset (#8470)
* [AI] use byte offset instead of element range

* [AI] change ElementOffset -> ByteOffset
2026-03-20 21:03:23 +01:00
Ivan Pleshkov
ed13a5b496 Delete points by filter with deferred (#8389)
* delete_points_by_filter with deferred

* versions check

* tests

* Check for deferred points in first loop

* fix after rebase

* refactor

* fix tests

* fix build after rebase

* refactor

* fix test

* refactor

* fix after rebase

* refactor

---------

Co-authored-by: timvisee <tim@visee.me>
2026-03-20 15:13:22 +01:00
Jojii
6425323d3f Deferred point count in metrics (#8415) 2026-03-20 12:57:24 +01:00
Andrey Vasnetsov
5594d50807 propagate WAL errors (#8460)
* [AI] propagate WAL errors

* review fixes
2026-03-20 12:07:37 +01:00
Arnaud Gourlay
3855113ef6 Fix panic in WAL replay (#8454) 2026-03-20 11:36:02 +01:00
Roman Titov
04e9bbc4b2 Dense vector storage based on universal I/O IoUringFile (#8452) 2026-03-20 11:16:12 +01:00
Ivan Pleshkov
70d305a978 Chunked points deduplication (#8464)
* batched points deduplication

* chunks
2026-03-20 11:01:05 +01:00
Andrey Vasnetsov
e3567d730e Fix condition deserialization issue (#8455)
* [AI] fix cbor deserialization error

* fmt

* Address review feedback

- Use let-chains for cleaner Condition deserialization logic
- Add WAL-level roundtrip test for delete-by-filter with UUID has_id

Made-with: Cursor

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-20 09:50:25 +01:00
xzfc
6aa5e44776 edge 0.6.0 (#8459) 2026-03-19 20:52:20 +00:00
xzfc
7bd5759105 Touch-up UIO traits (#8457)
* UIO traits: require Sized

I don't think we ever going to add unsized implementation. So, lets,
require it on the whole trait rather than on individual methods.

* Move `AccessPattern` to the `common` package

Was: segment::vector_storage::vector_storage_base::AccessPattern
Now: common::generic_consts::AccessPattern

* UIO traits: replace `bool` with `AccessPattern`
2026-03-19 20:28:21 +00:00
Ivan Boldyrev
9146dc4bfe Explicit point_mappings guard (#8261)
Instead of `IdTracker` to have `iter_*` methods, it now has a `point_mappings()` method, returning a guard to `PointMapping` value.  It prepares for moving the point_mappings under a lock to allow parallel searches and deletions.

Also, an incorrect unsafe in `Segment::iter_points` is replaced by a safe version with `self_cell`.
2026-03-20 03:07:21 +07:00
Luis Cossío
ad8334928d Use UniversalIo for MmapBitSlice (#8339)
* feat(universal_io): add storage-agnostic BitSliceStorage with read/write support`

Add BitSliceStorage<S> generic over
UniversalRead<u64>/UniversalWrite<u64>,
providing bit-level read and write operations over u64-element storage.

Read operations (S: UniversalRead<u64>):
- read_all: returns Cow<BitSlice> (zero-copy for mmap, owned for others)
- get_bit: single bit read via u64 element fetch
- read_bit_range: arbitrary bit range read

Write operations (S: UniversalWrite<u64>):
- set_bit / replace_bit: single bit write (skips write if unchanged)
- write_bit_range: arbitrary bit range write from BitSlice source
- fill_bit_range: fill range with a value
- set_bits_batch: batch individual bit updates coalesced by element
- flusher: flush underlying storage

* refactor: replace MmapBitSlice with BitSliceStorage in MmapBitSliceBufferedUpdateWrapper

Migrate all deleted-flag bitslice storage from the legacy MmapBitSlice
(Deref-based mmap wrapper) to BitSliceStorage<MmapUniversal<u64>>
(storage-agnostic universal IO backend).

Updated consumers:
- MmapMapIndex
- MmapNumericIndex
- MmapGeoMapIndex
- MmapInvertedIndex (fulltext)
- ImmutableIdTracker
- Benchmark

Additionally:
- Add BitSliceStorage::create(path, num_bits) to encapsulate
  file creation + sizing + open (eliminates duplicated size math
  across 5 call sites)
- Add MmapBitSliceStorage type alias for
BitSliceStorage<MmapUniversal<u64>>
- Add count_ones() convenience method
- Use set_bits_batch() in wrapper flusher and all build paths
  instead of per-bit set_bit() loops (coalesces u64 read-modify-writes)
- Fix silent error swallowing in wrapper get(): log + debug_assert
  on I/O errors instead of .ok().flatten()
- Remove dead bitmap_mmap_size function from immutable_id_tracker

* use bitvec's approach for offset

* less api

* misc improvements

* refactor write method

* move to segment crate

* handle creation of file outside of StoredBitSlice logic

* fix codespell

* document bitwise calculations

* coalesce more updates into a single write, batch all writes

* use native `extend_from_bitslice` instead of iterating.

* clarity refactor

* clippyyy

* use `u64` as BitStore everywhere

* assume iterator is sorted

* only use chunk_by for generating runs

* fix update wrapper flusher

* review fixes

* larger set bits batch test

* remove reintroduced file

* oops, fix new test

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: generall <andrey@vasnetsov.com>
2026-03-19 12:26:47 -03:00
Jojii
c015b86515 Add deferred point count to UpdateQueueInfo (#8414)
* Add deferred point count to UpdateQueueInfo

* Hide if prevent_unoptimized is false

* Clippy

* Openapi

* Iterate over appendable segments only

* Only calculate deferred point count if prevent_unoptimized is true

* Rebase fixes

* Codespell
2026-03-19 15:27:23 +01:00
Jojii
356040312b Correct calculation of deferred point counts (#8366)
* Don't account for deferred points in some places

# Conflicts:
#	lib/collection/src/shards/local_shard/scroll.rs

* Add in QueryContext

* Cover more places

* Coderabbit review remarks

* Properly count amount of deleted deferred points (#8386)

* Properly count amount of deleted deferred points

* Prevent double-counting of the same point

* Remove hints to estimations

* Properly handle counts in ProxySegment

* Add tests and fix deleted point count issue

* Adjusts tests + fix issues

* Separte fields for deferred points in telemetry (SegmentInfo)

* Remove deferred_points_count()

* openapi

* Fix test by manually calculating visible points

* Adjust ProxySegment test to revertion of SegmentInfo

* Throw error if collection was not found in telemetry (e2e Test)

* Update lib/segment/src/segment/segment_ops.rs

Co-authored-by: Andrey Vasnetsov <andrey@vasnetsov.com>

* Make new fields in API optional

* Don't take range if no deferred point exist

* Review remarks

---------

Co-authored-by: Andrey Vasnetsov <andrey@vasnetsov.com>
2026-03-19 11:33:09 +01:00
tellet-q
b10d1b9ebd Add a test for dirty shard crashloop (#8440)
* Add a test for dirty shard crashloop
2026-03-19 11:15:36 +01:00