1843 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
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
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
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
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
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
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
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
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
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
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
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
Andrey Vasnetsov
fe54b9c131 [AI] use collback to read bytes from vector storage (#8484) 2026-03-23 13:50:07 +01:00
xzfc
6ddb81d1b6 Propagate OperationResult [3/4]: estimate_cardinality (#8446) 2026-03-23 11:51:48 +00:00
Andrey Vasnetsov
344425e714 remove incorrect assertion (#8481) 2026-03-23 10:41:16 +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
Roman Titov
04e9bbc4b2 Dense vector storage based on universal I/O IoUringFile (#8452) 2026-03-20 11:16:12 +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
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
xzfc
9aaa7c649b Propagate OperationResult [2/4]: SegmentEntry (#8445) 2026-03-19 05:40:49 +00:00
Arnaud Gourlay
4e7fb7a210 Fix panic in volatile_chunked_vectors (#8449)
* Fix panic in volatile_chunked_vectors

* better with a test
2026-03-18 17:38:54 +01:00
xzfc
7988eeef45 Propagate OperationResult [1/4]: payload_blocks (#8444) 2026-03-18 15:21:19 +00:00
xzfc
6e12a940be Use GeoHash instead of &GeoHash (#8443) 2026-03-18 10:23:00 +00:00
Roman Titov
a3d4570a12 Better IoUringFile errors (#8418) 2026-03-17 10:13:42 +01:00
qdrant-cloud-bot
6ddb60e5b5 Log individual payload index load time per field (#8390)
* Log individual payload index load time per field

Add per-field timing to `load_all_fields()` in `StructPayloadIndex`,
using the existing `LOAD_TIMING_LOG_TARGET` infrastructure. Each
payload field index that takes >= 5ms to load now gets its own log
line, making it easy to identify slow-loading fields.

Made-with: Cursor

* Move `log_load_timing` to common module and use everywhere

Move the `log_load_timing` helper from `segment_constructor_base` into
`common::defaults` so it can be reused across crates. Convert all raw
`log::debug!(target: LOAD_TIMING_LOG_TARGET, ...)` call sites to use
the shared function, giving consistent formatting and min-duration
suppression everywhere.

Made-with: Cursor

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-13 18:38:04 +01:00
qdrant-cloud-bot
5d148dcd61 Speed up slow unit tests (#8385)
Reduce test parameters across 5 areas to cut test runtime without
sacrificing coverage:

1. HNSW PQ tests: lower vector dimensionality from 131 to 64 for product
   quantization variants, cutting PQ codebook training time (~31s -> ~8s)

2. HNSW index build: use 2 threads instead of 1 for index construction;
   the tests only check accuracy above a threshold so determinism is not
   required

3. Search attempts: reduce from 10 to 5 query vectors per test

4. Rescoring: skip the expensive re-upsert-all-as-zeros rescoring check
   for PQ tests (already covered by scalar quantization variants)

5. Near-miss speedups:
   - WAL: reduce QuickCheck iterations from 100 to 50
   - Gridstore: halve operation counts, drop 64-byte block size case,
     reduce proptest cases for gap search
   - Continuous snapshot: reduce timeout from 20s to 10s

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-13 18:27:44 +01:00
qdrant-cloud-bot
f08d9cda65 Replace has_deferred_points with deferred_points_count in SegmentEntry (#8391)
* Replace `has_deferred_points` with `deferred_points_count` in SegmentEntry

Change the `SegmentEntry` trait method from returning a boolean to
returning the actual count of deferred points (`usize`). This gives
callers more information without needing a separate method, while
existing boolean checks simply compare against zero.

Made-with: Cursor

* Fix clippy collapsible_if warning in deferred_points_count

Made-with: Cursor

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-13 17:06:32 +01:00
qdrant-cloud-bot
2406dd9562 Suppress noisy zero-duration load timing logs (#8388)
Add a `log_load_timing` helper that checks elapsed time against a 5ms
threshold before logging. Sub-component loads faster than this round to
"0.00s" in the {:.2} format and are pure noise. The per-segment "total
loaded" line remains unconditional.

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-13 12:47:19 +01:00
Arnaud Gourlay
9074b9640b Integration test for deferred points (#8365)
* Integration test for deferred points

* test facets

* rework
2026-03-13 12:45:19 +01:00
qdrant-cloud-bot
33ed0dac9f Propagate deferred_internal_id into SegmentInfo and telemetry (#8382)
Add `deferred_internal_id` field to `SegmentInfo` so it is exposed
through segment telemetry. The field is optional and skipped from
serialization when `None`. It is excluded from anonymization via
`#[anonymize(false)]`.

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-13 12:31:19 +01:00
Jojii
59d5e069cf Use dedup() instead of unique() (#8376)
* Use dedup() instead of unique()

* Assert iterator to be ordered
2026-03-13 11:38:55 +01:00
Roman Titov
a3786cfacc Improvements for IoUringFile (#8300)
* Improvements for `IoUringFile`

- handle read and write requests more explicitly
- assert against partial reads/writes

* Implement `read_multi`/`write_multi`

* Implement `populate` and `clear_ram_cache`

* Rename internal structures as `IoUringSomething`

* [ai] Make `UniversalRead`/`UniversalWrite` impl generic over `T`

* Handle `io_uring` initialization error

* Check that `io_uring` is initialized and supported, when opening `IoUringFile`

* fixup! Check that `io_uring` is initialized and supported, when opening `IoUringFile`

Fix typo

* test for reading u64 from file with uring

* fmt

* clippy

* fix(io_uring): allocate Vec<MaybeUninit<T>> for reads to fix alignment for T (#8353)

* fix(io_uring): allocate Vec<MaybeUninit<T>> for reads to fix alignment for T

Refactor IoUringState::read to take generic T and item_offset/items_length
instead of byte_offset/byte_length. Allocate Vec<MaybeUninit<T>> so the
kernel writes into correctly aligned memory, then convert to Vec<T> in
finalize. Fixes bytemuck::cast_vec alignment panic for types like u64.

Made-with: Cursor

* refactor(io_uring): only make read/write methods generic, not state or runtime

- IoUringState and IoUringRuntime no longer generic over T
- read<T>() allocates Vec<MaybeUninit<T>>, transmutes to Vec<MaybeUninit<u8>> for storage
- finalize returns ReadBuffer; callers use .into_vec::<T>() to get Vec<T>
- Write path unchanged (callers pass bytes via bytemuck::cast_slice)

Made-with: Cursor

* Cleanup

* review n1

* review n2

* fmt

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
Co-authored-by: Roman Titov <ffuugoo@users.noreply.github.com>
Co-authored-by: Andrey Vasnetsov <andrey@vasnetsov.com>

* use AHash instead of just hash

* add ahash to deps

---------

Co-authored-by: Andrey Vasnetsov <andrey@vasnetsov.com>
Co-authored-by: qdrant-cloud-bot <111755117+qdrant-cloud-bot@users.noreply.github.com>
Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-12 22:40:59 +01:00