Conversation
Add MMapAllocator that allocates memory via mmap-backed files on a configurable path (e.g. NVMe/SSD). This enables placing secondary data structures on SSD while keeping primary data in RAM, reducing heap memory usage for large-scale vector search. - include/svs/core/allocator_mmap.h: MMapAllocator with configurable base path, access hints (Sequential/Random/Normal), and automatic file cleanup on deallocation. - tests/svs/core/test_allocator_mmap.cpp: Unit tests for allocation, deallocation, file creation, and access hint propagation. - tests/CMakeLists.txt: Register mmap allocator test.
- Add map_existing_at_offset() to MMapAllocationManager for read-only file mapping with byte offset (skips file headers) - Add use_existing_file() one-shot override to MMapAllocator so allocate() maps an existing binary file instead of creating a temp file - Propagate override fields through copy constructor - Enables zero-copy loading of saved index data without intermediate allocate-copy cycles, significantly reducing memory usage
Runtime API changes: - SSDConfig: Add primary_on_ssd, secondary_on_ssd, and primary_only fields for flexible per-component data placement and primary-only LeanVec mode - VamanaIndex::assemble_from_directory: Load pre-built indices with optional SSD-backed mmap for primary/secondary data components - VamanaIndexLeanVec::build: Add primary_only parameter to skip secondary data allocation (reduces memory, disables reranking) - DynamicVamanaIndex::assemble_from_directory: Same SSD support for mutable indices - DynamicVamanaIndexLeanVec::build: Add primary_only via DynamicIndexParams overloads - DynamicVamanaIndex::load: Add primary_only parameter for deserialization Implementation: - VamanaIndexImpl: SSD assembly with MMapAllocator, per-component on_ssd flags, and LeanVec primary_only loading via switch-case dispatch - DynamicVamanaIndexImpl: RAM and SSD assembly paths with primary_only support for LeanVec storage kinds - DynamicVamanaIndexLeanVecImpl: Store and forward primary_only through build and init paths - StorageFactory<LeanVecStorageType>::init: Accept primary_only, forward to LeanDataset::reduce - MMapAllocator: Add madvise(MADV_DONTNEED) eviction support Tests: - LeanVecPrimaryOnlyBuildAndSearch: Dynamic index build + self-recall - LeanVecPrimaryOnlyStaticBuild: Static Vamana with LeanVec4x8 primary_only - SSD assembly tests for FP32 and LVQ4x8 storage kinds - MMapAllocator zero-copy and eviction tests
rfsaliev
reviewed
Apr 17, 2026
| /// | ||
| /// Performs default initialization of the object. | ||
| /// | ||
| void construct(T* ptr) { ::new (static_cast<void*>(ptr)) T; } |
Member
There was a problem hiding this comment.
Seems like this code is incompatible with declared use_existing_file() behavior, which means "read-only".
| /// @brief Allocate memory | ||
| /// | ||
| /// Creates a memory-mapped file and returns a pointer to it. | ||
| /// If use_existing_file() was called, maps that file read-only instead. |
Member
There was a problem hiding this comment.
It seems like would be better to separate behavior for in-directory an 'existing file' allocations to different classes.
| /// Tracks memory-mapped allocations by keeping MMapPtr objects alive. | ||
| /// Thread-safe for concurrent allocations. | ||
| /// | ||
| class MMapAllocationManager { |
Member
There was a problem hiding this comment.
It looks like this class is fully-static (all fields are static).
And actually behaves as hidden global variables + helper functions.
According to that, there is no reason to define non-static methods like allocate() and map_existing_at_offset().
Suggesting to make all methods static and delete .ctor
Or implement the Singleton pattern.
Address PR #302 review: - MMapAllocator: writable temp-file backed only (used for build/save). construct() is a no-op + static_assert(is_trivially_default_constructible_v<T>): the mapped bytes are reinterpreted in place as already-valid T objects so load/save can round-trip without running constructors. - MMapFileViewAllocator: new class for read-only zero-copy file views. construct() is also a no-op + static_assert(is_trivially_default_constructible_v<T>), but here the mapping is PROT_READ, so placement-new would actively fault; the existing on-disk bytes already represent valid T objects. Two construction modes: * bound (path + offset) for direct use, and * config-only with late binding via with_file(path, offset) so load_container can resolve the on-disk file by UUID. - MMapAllocationManager: fully static (no instances; deleted ctor/dtor/copy). - Add is_mmap_file_view_allocator_v type trait; consumers use this to detect the late-binding allocator. - bindings/cpp SSD load paths (LVQ + LeanVec, both single and dual) switched to MMapFileViewAllocator without an explicit ssd_path arg (path resolved internally inside the load specialization).
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add MMapAllocator that allocates memory via mmap-backed files on a configurable path (e.g. NVMe/SSD). This enables placing secondary data structures on SSD while keeping primary data in RAM, reducing heap memory usage for large-scale vector search.