87 Commits

Author SHA1 Message Date
xzfc
a1a005c7d5 rustdoc: syntax/path fixes 2026-04-07 21:13:58 +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
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
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
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
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
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
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
dependabot[bot]
ec18513bdf build(deps): bump lz4_flex from 0.12.0 to 0.13.0 (#8420)
Bumps [lz4_flex](https://github.com/pseitz/lz4_flex) from 0.12.0 to 0.13.0.
- [Release notes](https://github.com/pseitz/lz4_flex/releases)
- [Changelog](https://github.com/PSeitz/lz4_flex/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pseitz/lz4_flex/compare/0.12.0...0.13.0)

---
updated-dependencies:
- dependency-name: lz4_flex
  dependency-version: 0.13.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-17 07:17:08 +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
Andrey Vasnetsov
64cc539f9b strictly read only mmap (#8350)
* [AI] Implement generic to make pure read-only universal io mmap version

* fmt

* [AI + manual nits] /simplify (#8351)

---------

Co-authored-by: Luis Cossío <luis.cossio@outlook.com>
2026-03-12 13:18:15 +01:00
xzfc
d8383861b2 Test edge examples on CI (#8318)
* lib/edge/publish/cargo: improve target directory discovery

Don't hardcode workspace root, ask cargo instead.

* Fix warning in qdrant-edge amalgamation

`cargo check` in `lib/edge/publish` produces the following warning:

    warning: type `PointerUpdates` is more private than the item `gridstore::tracker::Tracker::<S>::write_pending`

* lib/edge/publish/examples: fix compiler warnings

* refactor: lib/edge/publish/examples: put DATA_DIRECTORY into lib.rs

To match python examples that have the same constant in `common.py`.

* Use `lib/edge/data` dir for both Python and Rust examples

Before this commit, `lib/edge/publish/data` and `lib/edge/python/data`
were used. I'd like Python and Rust to use the same prepared resources
in the future.

* Add lib/edge/Justfile with recipes to build/run examples

I constantly keep forgetting how to compile and run edge stuff.
Also, this would be used in CI in subsequent commits.

* doc: lib/edge/README.md: Combine Rust and Python Edge readmes

Also now we can rename `creates-io-readme.md` to `README.md` like
reasonable people.

* doc: Add qdrant-edge-py README.md

Since the previous commit removed qdrant-edge-py README.md, we need to
add something in its place instead.
The new README is adapted from Rust edge README.
And the previous README wasn't good anyway, see [1], it mentions maturin
which is irrelevant for users.

[1]: https://pypi.org/project/qdrant-edge-py/0.5.0/

* GHA: Add "Setup Qdrant" composite action

We need running Qdrant instance to test edge examples on CI. We can't
use docker for this because we want to run tests on Windows and macOS.
OTOH, this action downloads binaries for all platforms provided in
https://github.com/qdrant/qdrant/releases/tag/v1.17.0

* GHA: Use single worflow for python and rust edge examples

Merge workflows to reuse build cache. Also, modernize it by using `uv`,
and recently introduced `setup-qdrant` and Justfile. Also, make it run
on three platforms (only on merges).

* GHA: edge-{py,rust}-release: also run examples before publishing

Use similar approach as in the previous commit. But note that this time
we build/test also on ARM Linux and Windows.
2026-03-11 17:13:46 +00:00
qdrant-cloud-bot
d9702ef30f chore: remove unused dependencies reported by cargo-machete (#8347)
- gridstore: remove memmap2
- common: remove ahash
- edge: remove serde_json from dependencies
- examples (lib/edge/publish/examples): remove anyhow

Made-with: Cursor

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-10 11:05:30 +01:00
Andrey Vasnetsov
7083e7f2b6 gridstore live reload (#8287)
* [manual] live reload functions for gridstore-read

* [AI] tests for life reload

* fmt

* Address CodeRabbit review (PR 8287)

- gridstore/mod: acquire pages read lock once in files() loop
- universal_io/mmap: use fs_err::exists() to propagate IO errors
- pages: fix live_reload last_page_id underflow when pages is empty

Made-with: Cursor

* review changes

* thx coderabbit

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
Co-authored-by: Luis Cossío <luis.cossio@outlook.com>
2026-03-04 18:30:21 +01:00
Andrey Vasnetsov
77b296d579 storage-backend dependent file listing (#8286) 2026-03-04 14:18:58 +01:00
Luis Cossío
a7e78730a6 [gridstore] simplify page range calculation (#8285)
* simplify page range calculation

* smol fix

---------

Co-authored-by: generall <andrey@vasnetsov.com>
2026-03-03 16:17:03 -03:00
Andrey Vasnetsov
b6c1987038 MultiFile Universal UI in gridstore pages (#8256)
* [manual] implement Pages for read-only

* Simpler `ReadMulti`/`WriteMulti` interface (#8263)

* [manual] Dumbify `ReadMulti`/`WriteMulti` interface

* fixup! [manual] Dumbify `ReadMulti`/`WriteMulti` interface

🤷‍♀️

* fixup! [manual] Dumbify `ReadMulti`/`WriteMulti` interface

Remove `VecMultiUniversalIo`

* [manual] review fix + silplify json load option

* [AI] split read and write + revome *Multi traits

* [AI] implement write for pages

* [AI] integrate pages into gridstore

---------

Co-authored-by: Roman Titov <ffuugoo@users.noreply.github.com>
2026-03-03 14:50:44 +01:00
Andrey Vasnetsov
13ded7ab14 feat(gridstore): migrate Tracker to universal IO (#8253)
* feat(gridstore): migrate Tracker to universal IO

- Tracker<S> generic over S: UniversalRead<u8> + UniversalWrite<u8>
- Replace MmapSlice<u8> with S; use S::open, read, write, flusher, populate
- On file growth: flush, create_and_ensure_length, re-open S
- Map UniversalIoError::NotFound to tracker file missing error
- get_raw returns Result<Option<Option<ValuePointer>>>; get returns Result<Option<ValuePointer>>
- has_pointer, unset, write_pending return Result where needed
- flusher returns crate::gridstore::Flusher (universal_io Flusher mapped to GridstoreError)
- Type alias Tracker = Tracker<MmapUniversal<u8>> in lib.rs
- Tests use TestTracker = Tracker<MmapUniversal<u8>>; mapping_len/mmap_file_size .unwrap()

Made-with: Cursor

* refactor(gridstore): review follow-ups – generic view, From conversion, iter errors

- GridstoreView: use Tracker<S> with same S as Page (S: UniversalRead + UniversalWrite)
- Tracker: use ? and .map_err(Into::into) instead of .map_err(GridstoreError::from)
- View iter: propagate tracker read errors via Err(e) instead of silently skipping

Made-with: Cursor

* Split Tracker into read/write impl blocks; GridstoreView only requires UniversalRead

- Tracker: impl<S> for files/pointer_count, impl<S: UniversalRead<u8>> for
  get/get_raw/iter_pointers/has_pointer/populate and test helpers,
  impl<S: UniversalRead+UniversalWrite> for new/open/write_pending/set/unset
  and other write methods (like Page).
- GridstoreView: require S: UniversalRead<u8> only so read-only views don't
  need UniversalWrite.

Made-with: Cursor

* Move Tracker::open to read-only impl; add FILE_NAME/tracker_file_name to unbound impl

open() only uses S::open and storage.read(), so it belongs in impl<S: UniversalRead<u8>>.
read_config_and_tracker can thus use a read-only tracker open. FILE_NAME and
tracker_file_name moved to unbound impl so both read and write sections use them.

Made-with: Cursor

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-02 18:03:59 +01:00
Andrey Vasnetsov
82c49df611 feat(universal_io): add read_whole and read_json_via for config files (#8251)
* feat(universal_io): add read_whole and read_json_via for config files

- Extend UniversalRead with read_whole() for single-access whole-file read
- Default impl uses len() + read(0..len()); MmapUniversal overrides with one slice
- Add UniversalIoError::SerdeJson for JSON deserialization errors
- Add read_json_via<S,T>(path, options) in common::universal_io
- Gridstore: use read_json_via for config in read_config_and_tracker
- Segment: use read_json_via in ChunkedVectors::load_config, handle NotFound
- Segment: extend From<UniversalIoError> for OperationError with SerdeJson variant

Made-with: Cursor

* feat(universal_io): add UniversalIoError::NotFound for file-not-found

- Add NotFound { path } variant so callers can match without io::ErrorKind
- MmapUniversal::open maps io::ErrorKind::NotFound to NotFound { path }
- ChunkedVectors::load_config matches NotFound => Ok(None)
- OperationError From<UniversalIoError> handles NotFound

Made-with: Cursor

* style: apply cargo fmt

Made-with: Cursor

* fix(common): satisfy clippy explicit_auto_deref in read_json_via

Use &bytes instead of &*bytes; auto-deref handles Cow

Made-with: Cursor

---------

Co-authored-by: Cursor Agent <agent@cursor.com>
2026-03-02 16:38:17 +01:00
Luis Cossío
9444b0f07e Gridstore iter: re-fix livelock (#8248)
* release read locks after every batch

* break infinite loop

* oopsie
2026-02-27 22:02:35 +01:00
Luis Cossío
5403ea68ab Chunked vectors with UniversalWrite storage (#8233)
* use CowMultiVector as return type from storages

* add advice to OpenOptions

* Implement ChunkedVectors with generic storage

* rename ChunkedVectors->VolatileChunkedVectors and ChunkedMmapVectors-> ChunkedVectors

* propagate everywhere

fix tests

* [auto] rename BytesRange -> ElementsRange

* [auto] rename BytesOffset -> ElementOffset

* coderabbit nits

---------

Co-authored-by: generall <andrey@vasnetsov.com>
2026-02-27 12:47:15 -03:00
Andrey Vasnetsov
7084b5dd91 read write gridstore (#8244)
* [WIP] read and write separattion

* Introduce GridstoreView which contains ephermal representation of data and implements search functions

* fmt

* hide test-only method + add missing file

* fmt

* [AI] do not Copy config

* review nits

* thx coderabbit

---------

Co-authored-by: Luis Cossío <luis.cossio@outlook.com>
2026-02-26 21:57:40 +01:00
Andrey Vasnetsov
03c0fa2cf7 Universal IO: gridstore pages (#8223)
* [manunal] Gridstore page use universal IO

* fmt

* Apply review feedback for universal IO gridstore pages (#8230)

* Apply review feedback from PR #8223

- Use `super::Result` import in mmap.rs instead of fully-qualified `crate::universal_io::Result`
- Restructure ValuePointer destructuring in get_value and delete_value to
  first match Some(pointer), then destructure separately

* Replace Either<E, GridstoreError> with E: From<GridstoreError> in Gridstore::iter

Use a trait bound instead of Either to combine callback and gridstore
errors, allowing `?` to work directly on GridstoreError. This simplifies
callers by removing Either matching and io::Error conversion workarounds.

---------

Co-authored-by: qdrant-claw <qdrant-claw@users.noreply.github.com>

---------

Co-authored-by: qdrant-claw <qdrant-claw@users.noreply.github.com>
2026-02-25 19:46:00 +01:00
dependabot[bot]
18a7587d4b build(deps): bump rand_distr from 0.5.1 to 0.6.0 (#8148)
* build(deps): bump rand_distr from 0.5.1 to 0.6.0

Bumps [rand_distr](https://github.com/rust-random/rand_distr) from 0.5.1 to 0.6.0.
- [Release notes](https://github.com/rust-random/rand_distr/releases)
- [Changelog](https://github.com/rust-random/rand_distr/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand_distr/compare/0.5.1...0.6.0)

---
updated-dependencies:
- dependency-name: rand_distr
  dependency-version: 0.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

* Migrate main code base to rand 0.10

* Migrate tests

* Migrate benches

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: timvisee <tim@visee.me>
2026-02-25 14:15:04 +01:00
Ivan Pleshkov
9f1a6be223 Gridstore non-blocking flush (#8188)
* gridstore unblocked flush

* review remarks
2026-02-23 12:18:14 +01:00
Tim Visée
e160308255 Don't lock Gridstore bitmask for full duration of flush (#8169) 2026-02-18 16:29:04 +01:00
xzfc
4cabb7fd8e Merge io and memory into common (#8155)
* Unify parking_lot/arc_lock feature

* Move lib/common/{io,memory}/* -> lib/common/common/*

- Mmap-related items are grouped into `common::mmap` sub-module:
  - `memory/src/chunked_utils.rs`      -> `common/src/mmap/chunked.rs`
  - `memory/src/madvise.rs`            -> `common/src/mmap/advice.rs`
  - `memory/src/mmap_ops.rs`           -> `common/src/mmap/ops.rs`
  - `memory/src/mmap_type_readonly.rs` -> `common/src/mmap/mmap_readonly.rs`
  - `memory/src/mmap_type.rs`          -> `common/src/mmap/mmap_rw.rs`
- Filesystem-related items are grouped into `common::fs` sub-module:
  - `common/src/fs.rs`          -> `common/src/fs/sync.rs`
  - `io/src/file_operations.rs` -> `common/src/fs/ops.rs`
  - `io/src/move_files.rs`      -> `common/src/fs/move.rs`
  - `io/src/safe_delete.rs`     -> `common/src/fs/safe_delete.rs`
  - `memory/src/checkfs.rs`     -> `common/src/fs/check.rs`
  - `memory/src/fadvise.rs`     -> `common/src/fs/fadvise.rs`
- Rest is moved straight into `common`:
  - `io/src/storage_version.rs` -> `common/src/storage_version.rs`

The old `io` and `memory` are now hollow crates that re-export items
from `common`. These hollow crates will be removed in next commits.

* Replace uses of `io` and `memory` with new paths in `common`

Since `io` and `memory` are just re-exports of `common`, these
replacements are no-op.

* Remove `io` and `memory` crates
2026-02-17 10:58:59 +01:00
xzfc
6bced54ca1 Chore: promote dependencies to workspace level (#8061)
* Promote `env_logger` to workspace dependency

* Promote `anyhow` to workspace dependency

* Promote `rmp-serde` to workspace dependency

* Promote `tinyvec` to workspace dependency

* Promote `async-trait` to workspace dependency

* Promote `url` to workspace dependency

* Promote `self_cell` to workspace dependency

* Promote `cc` to workspace dependency

* Promote `bitpacking` to workspace dependency
2026-02-05 16:02:28 +01:00
Ivan Boldyrev
984a9e8bd1 Fix gridstore Option unsoundness (#8011)
* Implement `Optional<T>` type

Define a type with the same presumed layout as `Option<T>`, but with defined behavior.

* Make `transmute_*` functions unsafe

The functions `memory::mmap_ops::transmute_*` are inherently unsafe, but
are not marked as are.  Their usage is documented, but it is not always clear
if the code is correct.

* Add `CsrHeader` to resolve another unsoundness

Tuples have no defined layout.
2026-02-03 17:57:09 +07:00
Andrey Vasnetsov
64040511bc gridstore iter livelock (#7983)
* granular lock for writing and flushing pending updates in gridstore tracker

* avoid grigstore tracker lock in iterator
2026-01-26 11:47:26 +01:00
Luis Cossío
9fca971d93 More graceful handle of flush cancellation (#7798)
* Reapply "return an error when cancelling a flush (#7781)" (#7799)

This reverts commit 4a1103acb7.

* log::trace cancellation of components

* gracefully handle flush cancellation inside segment flusher

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

Co-authored-by: Tim Visée <tim+github@visee.me>

* don't wrap cancellation errors

---------

Co-authored-by: Tim Visée <tim+github@visee.me>
2026-01-21 10:06:50 -03:00
Luis Cossío
0c1917b4ae Give lower probability to rare operations (#7876) 2026-01-06 17:14:15 -03:00
Tim Visée
4a1103acb7 Revert "return an error when cancelling a flush (#7781)" (#7799)
This reverts commit 2f443ec055.
2025-12-18 16:45:30 +01:00
Luis Cossío
2f443ec055 return an error when cancelling a flush (#7781)
* return an error when cancelling a flush

* fix test

* less verbosity
2025-12-17 10:21:20 -03:00
Arnaud Gourlay
2e66577148 Gridstore noisy log into assert (#7795) 2025-12-17 13:46:44 +01:00
Arnaud Gourlay
5175d9f64a Enrich Gridstore model testing (#7789)
* Enrich Gridstore model testing

* better

* no clear on Windows

* less windows

* sigh

* change strategy

* never give up

* x100 scale down for Windows

* last touch

* decrease for others too

* remove Iter test - the quadratic cost is not worth it

* Revert "remove Iter test - the quadratic cost is not worth it"

This reverts commit f0e98cb33b.

* try with limited Iter

* less logging as it is hurting crasher

* tracker.mapping_len() is slow

* hard limit good enough for now
2025-12-17 11:55:27 +01:00
Luis Cossío
a89f309645 new GridstoreError (#7780)
* create GridstoreError

* review nit
2025-12-16 12:04:25 -03:00
Luis Cossío
4e91702fe8 Introduce IsAliveLock (#7751)
* introduce IsAliveLock

* add tests

* rename to mark_dead

* update gridstore comment

* Update some comments

* Add must_use attribute to lock_if_alive

* Rename mark_dead to blocking_mark_dead

* make the handle take a `Weak` reference

* make dropping explicit

* use `Mutex::lock_arc` instead

* less nesting

* clippy

---------

Co-authored-by: timvisee <tim@visee.me>
2025-12-15 12:22:30 -03:00
Tim Visée
aadadd172e Gridstore: split pointer updates set/unset, simplify draining (#7749)
* Separate set and unset lists for each Gridstore pointer update

This makes the list of pointer updates much easier to grasp. The
simplification is desired because this exact structure has been a cause
for bugs multiple times now.

* Add more aggressive debug assertions

* Use consistent terminology

* Correct removal of set

* Simplify drain function

* Add safe guard to ignore empty pointer updates

* Rework tracker getter, explicitly branch variants

* Patch transmute, require Sized type

* rename and adjust comments

- set/unset is now current/to_free
- adjusted descriptions and comments for this nomenclature too

* clippy

* clippyyy

not 4, not 2, but 3 spaces

---------

Co-authored-by: Luis Cossío <luis.cossio@outlook.com>
2025-12-11 18:07:15 +01:00
Arnaud Gourlay
cb70be4969 Test Gridstore corruption on flush (#7713)
* Gridstore decompress failure

* more logs

* more logs

* hardening

* clean

* no compression

* cleanup

* typo

* misc

* wait for flush & less logs

* add compression type to the mix

* optimize
2025-12-11 15:13:16 +01:00
Tim Visée
14ebe94c90 Fix Gridstore flushing, correctly implement drain persist (#7741)
* Fix Gridstore tracker drain and persist not working properly

* Patch existing test

* Add new test to assert buggy scenario we found

* Mention PR in test
2025-12-11 10:27:40 +01:00
Arnaud Gourlay
21d52ba832 Optimize gridstore flush (#7740)
* Optimize gridstore flush

* lovely early return
2025-12-10 19:42:57 +01:00
Tim Visée
bdd3871f29 Fix flusher data race in Gridstore (#7702)
* Add lease structure to invalidate pending flushers after wipe/clear

* We don't use bitmask as barrier anymore

* Add missing early return

* Add test

* Replace flush lease with is alive boolean we also use elsewhere

* Reimplement test, now it does fail on the old implementation

* In test, cover both new fixed and old broken flushing

* Remove old test case because it is flaky

* Fix clippy

* Fix outdated comment
2025-12-09 11:23:56 +01:00
Arnaud Gourlay
76bfa2ef7c Fix to run all tests on CI (#7732)
* Fix to run all tests on CI

* adjust for macos since we bumped rocksdb

* more flags
2025-12-09 11:09:52 +01:00
Luis Cossío
d79cd9b99b activate fs-err features for nicer error messages (#7665)
* activate fs-err features for nicer error messages

* use in entire workspace
2025-12-02 10:40:36 -03:00
dependabot[bot]
35817f11bc build(deps): bump lz4_flex from 0.11.5 to 0.12.0 (#7660)
Bumps [lz4_flex](https://github.com/pseitz/lz4_flex) from 0.11.5 to 0.12.0.
- [Release notes](https://github.com/pseitz/lz4_flex/releases)
- [Changelog](https://github.com/PSeitz/lz4_flex/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pseitz/lz4_flex/compare/0.11.5...0.12.0)

---
updated-dependencies:
- dependency-name: lz4_flex
  dependency-version: 0.12.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>
2025-12-01 19:25:26 -03:00
Tim Visée
4010e7219f Add runtime flag to disable opening multiple mmaps on the same file (#7614)
* Fix delete_page not dropping sequential mmap

* In Gridstore Page, support using a single mmap

* In Gridstore Page, only open multiple mmaps if supported at runtime

* Support opening single mmap in UniversalMmapChunk

* Rename environment var, log warning when QDRANT_NO_MULTI_MMAP is set

* Support opening single mmap in MmapDenseVectors

* Remove unused result response

* Import LazyLock
2025-12-01 18:34:05 +01:00
Arnaud Gourlay
eba78a6728 Fix Gridstore has pointer lookup to account for nature of pending operation (#7638) 2025-12-01 10:55:44 +01:00
Luis Cossío
6ca3e46638 Fix wiping of Gridstore (#7627)
* fix wiping of gridstore

* clippy

* address @timvisee's review
2025-11-27 11:38:19 -03:00