split.rs

Overview

This file implements a storage wrapper called SplitValueStore that transparently splits large data values (bins) into smaller chunks before storage, and merges those chunks back into a single logical record on retrieval. This is useful for working with storage backends that impose size limits on individual records or bins.

The splitting and merging logic ensures that large blobs stored as individual bins do not exceed a configurable maximum size (max_size). The file also provides utility functions and an internal helper struct to manage the splitting and chunking process efficiently and correctly.


Key Components

Constant


Struct: SplitValueStore

A generic wrapper around an inner KeyValueStore implementation that automatically splits large bin values into chunks before putting, and merges them back after getting.

Methods:

Usage Example:

let inner_store = ...; // Some KeyValueStore implementation
let split_store = SplitValueStore::new(inner_store, 1000); // max chunk size 1000 bytes

// Put large bins
split_store.put(&key, &bins, true, "label")?;

// Get and automatically merged
let record = split_store.get(&key, &Bins::Some(vec!["bin1".to_string()]), "label")?;

Internal Helper: Split<'k, 'b>

Manages the process of splitting bins into chunks, grouping chunks into multiple records, and generating the keys/bins for each chunk.


Functions

split_bins(key: &Key, bins: &[Bin], max_size: usize) -> anyhow::Result<Option<Vec<(Key, Vec<Bin>)>>>


merge_bins(store: &(impl KeyValueStore + ?Sized), key: &Key, values: &Bins, record: &mut ValueMap, label: &'static str) -> anyhow::Result<()>


chunk_key(key: &Key, i: usize) -> anyhow::Result<Key>


next_chunk(bin: &Bin, offset: usize, max_size: usize) -> anyhow::Result<(usize, Bin)>


Implementation Details & Algorithms


Interaction with Other System Components


Diagram: Structure of split.rs

classDiagram
class SplitValueStore {
-inner: Inner
-max_size: usize
+new(inner, max_size)
+get(key, values, label)
+put(key, bins, until_success, label)
+batch_get(gets, label)
+db_reads()
+db_writes()
}
class Split {
-max_size: usize
-key: &Key
-records: Vec<(Key, Vec<Bin>)>
-bins: Vec<Bin>
-size: usize
+new(key, max_size)
+add_bin(bin_size, bin)
+flush_record()
+into_records()
}
SplitValueStore --> "1" Split : uses
SplitValueStore ..> KeyValueStore : implements
Split --> Bin : manages bins
Split --> Key : manages keys

Additional Notes


For further details on key concepts like KeyValueStore trait, Aerospike Key and Bin types, and error handling patterns, see the relevant topics on KeyValueStore Interface, Aerospike Data Types, and Error Handling.