3741 Commits

Author SHA1 Message Date
xzfc
d9b4de9be6 fix typo 2026-04-07 21:13:58 +00:00
xzfc
26c4b77a5c don't use Middle English words in error messages 2026-04-07 21:13:58 +00:00
xzfc
ad6d946327 rusdoc: use stable URLs 2026-04-07 21:13:58 +00:00
xzfc
a1a005c7d5 rustdoc: syntax/path fixes 2026-04-07 21:13:58 +00:00
xzfc
3be620d2b7 rustdoc: add doc for generic_consts
(Copied from closed PR #8458)
2026-04-07 20:54:40 +00:00
xzfc
a62c472107 rustdoc: fix misplaced doc comments for HnswGraphConfig 2026-04-07 20:54:04 +00:00
xzfc
2d9d953a45 UniversalIO: generic RequestId (#8601)
* IoUringState: generic `RequestId`

* UniversalRead: generic `RequestId`

* Simplify `gridstore::Pages::get_page_value_ranges`

Now we don't need two separate `SmallVec`s as we can put `buffer_offset`
into `RequestId`.

* Better doc comment

* Rename `RequestId` -> `Meta`
2026-04-07 17:10:40 +00:00
Krzysztof Teodorowski
07f4970ecb Add regression test for optimizer config refresh (#8607) 2026-04-07 15:27:37 +02:00
xzfc
8e07ccb7c3 IoUringState: replace HashMap with flat slice (#8599) 2026-04-07 12:31:55 +00:00
xzfc
1b236286e9 Separate GeoHash/GeoHashRaw (#8618)
* GeoHash: convert to tuple struct for consistency

* GeoHash: clarify code

* Separate `GeoHash`/`GeoHashRaw`
2026-04-07 11:59:35 +00:00
dependabot[bot]
d3e5738df8 build(deps): bump pyo3 from 0.28.2 to 0.28.3 (#8611)
Bumps [pyo3](https://github.com/pyo3/pyo3) from 0.28.2 to 0.28.3.
- [Release notes](https://github.com/pyo3/pyo3/releases)
- [Changelog](https://github.com/PyO3/pyo3/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pyo3/pyo3/compare/v0.28.2...v0.28.3)

---
updated-dependencies:
- dependency-name: pyo3
  dependency-version: 0.28.3
  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-04-07 10:13:32 +02:00
dependabot[bot]
14963e4115 build(deps): bump arc-swap from 1.9.0 to 1.9.1 (#8612)
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 1.9.0 to 1.9.1.
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v1.9.0...v1.9.1)

---
updated-dependencies:
- dependency-name: arc-swap
  dependency-version: 1.9.1
  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-04-07 10:13:17 +02:00
xzfc
38d5439078 UIO read benchmark (#8575) 2026-04-03 12:31:36 +00:00
Roman Titov
5739daa53a Improvements to io_uring (#8592)
* Cleanup `IoUringGuard`

* Cleanup `IoUringRuntime`

* Simplify imports

* Extract `io_error_context` into `error` sub-module

* Rename `IoUringFile::uses_o_direct` into `direct_io`

* Rename `IoUringRequest::Read` fields

* Minor cleanups

* Cleanup `IoUringPool` 😵‍💫

* Track file index during multi-file operations as part of `IoUringState`
2026-04-03 05:09:30 +00:00
Arnaud Gourlay
e4d5cd3b55 Exclude down resharded shards during select (#8596)
* Exclude down resharded shards during select

* act on a single consistent snapshot of the resharding state
2026-04-02 16:47:59 +02:00
Roman Titov
e43acaf9ab Better IoUringReadIter (#8586)
Co-authored-by: generall <andrey@vasnetsov.com>
2026-04-01 19:55:50 +02:00
Arnaud Gourlay
a4059c15af Remove unused dependency crates (#8589) 2026-04-01 18:15:18 +02:00
Arnaud Gourlay
cc45d9d5bd Upgrade raft-rs to latest revision (#8588) 2026-04-01 15:46:57 +02:00
Kyamran Shakhaev
ee7baa668f Use OperationError funcs (#8587)
* Use OperationError funcs

* Inline variable

* Inline variable

---------

Co-authored-by: Tim Visée <tim+github@visee.me>
2026-04-01 15:25:11 +02:00
dependabot[bot]
3acd7fffa9 build(deps): bump sha2 from 0.10.9 to 0.11.0 (#8558)
* build(deps): bump sha2 from 0.10.9 to 0.11.0

Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.10.9 to 0.11.0.
- [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.10.9...sha2-v0.11.0)

---
updated-dependencies:
- dependency-name: sha2
  dependency-version: 0.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: adapt to sha2 0.11.0 API changes

sha2 0.11.0 switched from GenericArray to hybrid_array::Array for hash
output, which no longer implements LowerHex. Replace `format!("{:x}")`
with explicit per-byte hex formatting.

Made-with: Cursor

* fix: replace write_all with update for sha2 0.11.0 compatibility

sha2 0.11.0 removed the std::io::Write impl on hashers.
Use Digest::update() instead of Write::write_all().

Made-with: Cursor

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <agent@cursor.com>
2026-04-01 14:05:49 +02:00
qdrant-cloud-bot
6812e6fbfb Update gpu-allocator to v0.28.0 (#8583)
Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-04-01 12:04:13 +02:00
Andrey Vasnetsov
f5474ef248 Propagate HardwareCounterCell through MmapMapIndex::get_values (#8574)
* Propagate HardwareCounterCell through MmapMapIndex::get_values

Previously, `MmapMapIndex::get_values` used `ConditionedCounter::never()`,
which silently skipped all hardware IO counter tracking for mmap map index
value reads. This propagates a real `HardwareCounterCell` through the full
call chain so that disk IO from `values_iter` is properly measured.

Changes:
- `MmapMapIndex::get_values` now accepts `&HardwareCounterCell`, creates a
  `ConditionedCounter` via `make_conditioned_counter`, and measures the
  `deleted` bitvec access (matching `check_values_any` behavior).
- `MapIndex::get_values` forwards the counter to the `Mmap` variant.
- `FacetIndex::get_point_values` trait method now accepts `&HardwareCounterCell`,
  propagated through `FacetIndexEnum` and both impls (MapIndex, BoolIndex).
- `indexed_variable_retriever` accepts and forwards the counter to
  `IntMapIndex`, `KeywordIndex`, and `UuidMapIndex` calls.
- `SegmentBuilder::update` and `_get_ordering_value` accept and propagate
  the counter instead of creating disposable instances.

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

* feat: add test

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Daniel Boros <dancixx@gmail.com>
2026-04-01 10:26:20 +02:00
xzfc
5e7a3b0593 IoUringFile: don't use io_uring for single operations (#8576) 2026-04-01 00:27:51 +00:00
Kyamran Shakhaev
050d5b9777 Use CollectionError funcs (#8570)
* Use CollectionError funcs

* Fix typo
2026-03-31 20:20:14 +02:00
xzfc
0b0df145b3 Drop RocksDB (#8529)
* Skip broken tests

* Add rocksdb dropper

This is a temporary tool. It will be removed later in this PR.

* [automated] Drop rocksdb

This commit is made by running tools/rocksdb/drop.sh

* Touch-up after ast-grep

The previous automated commit removed items, but not their comments.
Also, some blocks are left with only one item.
Also, ast-grep can't handle macros like `vec![]`.

This commit completes the job.

* Remove RocksDB dropper

* Remove mentions of rocksdb feature in CI

* Fix clippy warnings

These `FIXME` comments added previously in this PR by ast-grep by
"peeling" cfg_attr like this:

    -#[cfg_attr(not(feature = "rocksdb"), expect(...))]
    +#[expect(...)] // FIXME(rocksdb): ...

This commit removes these allow/expect attributes and fixes clippy
lints.

* Remove leftover rocksdb-related code

Removed:
- Cargo.toml: rocksdb cargo feature flag and dependencies.
- code: rocksdb-related items that was not under feature flag.
- flags.rs: rocksdb-related qdrant feature flags.

Disabled:
- Some benchmarks because these do not compile now.

* Print warning if rocksdb leftovers found in snapshots

* Remove Clone from tokenizer

* Regenerate openapi.json
2026-03-31 18:08:39 +00:00
Andrey Vasnetsov
f473e83ed0 universal io iterator (#8535)
* [AI] Implement low-level iterator for universal-io implementation of io_uring

* [AI] io_uring pool

* fmt

* [AI] refactor io_uring into multiple files

* [AI] implement IoUringReadMultiIter

* [AI] replace file_indices Vec -> AHashMap to prevent memory growth

* fmt

* Guard populate() when file uses O_DIRECT

O_DIRECT bypasses the page cache, so reading the whole file to warm
it is pointless — return early as a no-op.

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

* Update comment about O_DIRECT in concurrent read iter test

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

* fix: apply submit_and_wait retry loop to read iterators

On older kernels, submit_and_wait may return before completions are
available. Apply the same retry loop to the iterator step() methods
to prevent premature iterator termination.

Made-with: Cursor

* do not step every time

* [AI] unify iterators

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-31 15:54:52 +02:00
Kyamran Shakhaev
420c52758d Use StorageError funcs (#8565) 2026-03-31 15:28:51 +02:00
dependabot[bot]
70182a7c20 build(deps): bump object_store from 0.13.1 to 0.13.2 (#8556)
Bumps [object_store](https://github.com/apache/arrow-rs-object-store) from 0.13.1 to 0.13.2.
- [Changelog](https://github.com/apache/arrow-rs-object-store/blob/main/CHANGELOG-old.md)
- [Commits](https://github.com/apache/arrow-rs-object-store/compare/v0.13.1...v0.13.2)

---
updated-dependencies:
- dependency-name: object_store
  dependency-version: 0.13.2
  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-31 09:40:46 +02:00
qdrant-cloud-bot
f7dd3ae896 Fix io_uring submit_and_wait returning before completions on older kernels (#8547)
Loop `submit_and_wait(1)` until the completion queue is non-empty in
`UniversalRead::read` and `UniversalWrite::write`. On some earlier
kernel versions, `submit_and_wait` may return before the requested
number of events have completed, which would cause the subsequent
`.expect()` to panic.

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-30 21:45:24 +02:00
qdrant-cloud-bot
4d828e8454 Bump edge packages (Python + Rust) to 0.6.1 (#8545)
Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-30 17:22:18 +00:00
Andrey Vasnetsov
ecae89ef4d Fix edge sparse vector search panic on score postprocessing (#8543)
* Fix edge sparse vector search panic on score postprocessing

The distance lookup for score postprocessing only checked dense vector
configs, causing a panic when searching sparse vectors. Fall back to
Distance::Dot for sparse vectors, matching the full server behavior.

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

* Fix formatting

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

* Address PR review: return error instead of panic, fix example

- Replace panic! with OperationError::service_error for unknown vector
  names in edge search, avoiding process crash on bad client input
- Update stale "panics" comments and add assertions in sparse-search example

Made-with: Cursor

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-30 16:02:18 +02:00
Ivan Boldyrev
90ee161edd POINT_TO_TOKENS_COUNT_FILE is not immutable (#8542)
Remove this file from `MapInvertedIndex::immutable_files`, as it is
modified.
2026-03-30 19:33:16 +07:00
Daniel Boros
974fcb63c7 Feat/storage api over universal io (#8311)
* feat: add storage_read_service proto definition

* feat: update qdrant tonic definition

* feat: add list_files

* feat: add read_bytes

* feat: add read_bytes_stream

* feat: add read_batch & read_whole api

* feat: add read_multi

* fix: mod.rs

* feat: update resolve_path

* feat: add path resolve

* feat: add more tests and fix stream api

* feat: better error handling

* feat: add collection_base_path

* fix: potential EOF error

* fix: nested runtime panic on tests

* fix: github actions

* fix: auth tests

* fix: coderabbit pr review

* fix: linter

* fix: clippy

* fix: range validation and path resolve

* fix: linter

* fix: clippy

* fix: clippy

* fix: universal io error

* fix: incoming changes

* fix: compiler error

* feat: spilt impl

* fix: pr review

* fix: linter

* fix: dev changes

* fix: linter

* review fixes

* fmt

* chore: fix naming

* fix: pr reviews

* fix: rebase dev

* fix: clippy

* fix: tests

---------

Co-authored-by: generall <andrey@vasnetsov.com>
2026-03-29 23:08:16 +02:00
Bhagirath Kapdi
fb704e5d13 Feature/strict mode search max batchsize (#8469)
* feat: add search_max_batchsize to strict mode config

* added test case for search_max_batchsize

* Changes for fixing CI issue dure openapi

* Modify check_strict_mode_batch

---------

Co-authored-by: Arnaud Gourlay <arnaud.gourlay@gmail.com>
2026-03-26 16:26:09 +01:00
Luis Cossío
fa8b441454 Allow shorter reads in IoUring (#8466)
* use assume_init_vec

* allow shorter reads at EOF

* add prevent_caching openoption, allow short read dynamically

* codespell

* fix rebase
2026-03-26 11:56:22 -03:00
xzfc
50e4796597 Add TypedStorage wrapper (#8508)
* Remove UniversalRead::is_empty

Reason: Less methods to override in wrappers. And I don't think this
method makes much sense.

* Move common::universal_io::{ => wrappers}::read_only

* Update ReadOnly wrapper

Implement missing methods, and follow the code style of the upcoming
TypedStrorage wrapper.

* Add TypedStorage

* Use TypedStorage

* Add reminder comments

* Clarify TypedStorage use-case
2026-03-26 14:10:19 +00:00
qdrant-cloud-bot
a5b1d5f702 fix: correct inverted dedup logic and missing unwrap in geo index (#8514)
Two bugs introduced in 9a14ed7:

1. `HashSet::insert` returns `true` when the value is *new*, but the
   code assigned it to `already_seen` and skipped on `true` — inverting
   the deduplication so every unique geohash was skipped during removal.

2. `filter()` returns `OperationResult<Option<Box<dyn Iterator>>>`;
   the new tests called `.unwrap()` once (unwrapping the Result) but
   missed the second `.unwrap()` for the Option, causing a compile error.

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-26 12:31:15 +00:00
Roman Titov
69b70ee401 Small optimization for MmapFile (#8511) 2026-03-26 12:19:35 +01:00
qdrant-cloud-bot
9a14ed7088 Add reproducing test for spurious geo index warning on duplicate geo values (#8404)
* Add reproducing test for spurious geo index warning on duplicate geo values

When a point has multiple geo values that produce the same max-precision
geohash (e.g. duplicate coordinates in a multi-value geo field),
`InMemoryGeoMapIndex::remove_point` logs a spurious warning:
"Geo index error: no points for hash X was found".

The root cause is an asymmetry between `point_to_values` (stores all
values including duplicates) and `points_map` (uses a HashSet, so
duplicates are collapsed). During removal the loop processes each value
individually — the first iteration removes the `points_map` entry, and
subsequent iterations for the same hash can't find it.

This commit adds:
- A `debug_assert!` in `remove_point` (matching the existing pattern in
  `decrement_hash_value_counts`) to make the issue detectable in tests.
- `test_remove_point_with_duplicate_geo_values` — reproduces the bug by
  adding a point with `[BERLIN, BERLIN]` then removing it.
- `test_frequent_add_remove_geo_points` — exercises repeated add/remove
  cycles to cover the user-reported scenario.

Made-with: Cursor

* fix: redulplicate hash IDs, replace warn with debug assertion

* fmt

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
Co-authored-by: generall <andrey@vasnetsov.com>
2026-03-26 11:54:27 +01: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
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