mem.rs
Overview
The mem.rs file implements an in-memory key-value storage system, encapsulated in the MemStore struct. This store provides a thread-safe, mutable hash map for storing and retrieving Aerospike record bins keyed by a composite string derived from Aerospike's Key structure. It serves as a simple and efficient temporary storage layer within the application, primarily useful for testing, caching, or scenarios where persistence is not required.
The main functionality includes storing (put) and retrieving (get) sets of bins (fields and values) associated with Aerospike keys, with thread-safe access ensured via a mutex lock. The file also provides string formatting for debugging purposes and implements the KeyValueStore trait to integrate seamlessly with other system components expecting this interface.
Structures and Functions
MemStore
Description
MemStore is a thread-safe, in-memory key-value store. It uses an Arc to enable shared ownership across threads and a parking_lot::Mutex to serialize mutable access to an underlying HashMap. The map keys are string representations of Aerospike keys, and the values are ValueMap instances representing sets of bins.
Fields
inner: Arc<parking_lot::Mutex<HashMap<String, ValueMap>>>
A reference-counted, mutex-guarded hash map storing the key-value data.
Methods
new() -> Self
Creates a new, empty MemStore.
Usage Example:
let store = MemStore::new();
Debug trait implementation
Formats the MemStore contents for debugging, showing each stored key and its bins with their values converted to strings. Binary blobs are represented by their length for readability.
Default trait implementation
Returns a new instance by calling MemStore::new(). This allows for default initialization semantics.
Helper Functions
key_to_string(key: &Key) -> String
Converts an Aerospike Key into a unique string by concatenating the namespace, set name, and user key parts separated by dots (.). If the user key is not present, it defaults to an empty string.
Purpose:
Creates a string key usable as a HashMap key.
Example:
For a key with namespace "test", set "users", and user key "alice", the output string will be "test.users.alice".
value_to_string(value: &Value) -> String
Converts an Aerospike Value to a readable string representation. If the value is a binary blob, it returns a string indicating the blob's length (e.g., "[32]"). For other types, it calls the value’s own to_string() method.
Trait Implementation: KeyValueStore for MemStore
The MemStore implements the KeyValueStore trait, which defines the interface for basic key-value operations.
get(&self, key: &Key, _values: &Bins, _label: &'static str) -> anyhow::Result<Option<ValueMap>>
Retrieves the bins associated with the given Key. It locks the internal hash map, converts the key to string form, and attempts to find matching entries. Returns an Option<ValueMap> wrapped in a Result.
Parameters:
key: AerospikeKeyto look up._values: Requested bins (unused in this implementation)._label: A static label string (unused in this implementation).
Returns:
Ok(Some(ValueMap))if found, orOk(None)if no entry exists.Errors:
None expected; always returnsOk.
put(&self, key: &Key, values: &[Bin], _until: bool, _label: &'static str) -> anyhow::Result<()>
Stores a set of bins for the provided Key. It converts the key to a string and inserts or replaces the corresponding entry in the internal map.
Parameters:
key: AerospikeKeyto store.values: Slice ofBinstructs representing the field names and values._until: Boolean flag (unused here)._label: Static label string (unused here).
Returns:
Ok(())on success.Errors:
None expected; always returnsOk.
Debug-only Methods
In debug builds, the trait requires counting database reads and writes. These are marked with todo!() macros and are currently unimplemented:
db_reads(&self) -> usizedb_writes(&self) -> usize
Implementation Details and Algorithms
Thread Safety:
The inner data structure is protected by aparking_lot::Mutex, which offers fast locking mechanisms suitable for concurrent access. The use of anArcallows cloning and sharing theMemStoreinstance safely across threads.Key Stringification:
To index the hash map, Aerospike's compositeKeyis serialized into a single string that uniquely identifies a record. This avoids the need for implementing complex hashing or equality traits on theKeytype directly.Value Conversion for Debugging:
Binary data in values can be large or non-printable, so the debug formatter replaces them with length indicators to keep logs concise and readable.
Interaction with Other Components
Trait Compatibility:
By implementing theKeyValueStoretrait,MemStorefits into a pluggable storage architecture, allowing it to be substituted transparently with other persistent or remote stores.Data Types Used:
Key,Bin,Bins, andValueare from the Aerospike client library, representing record keys and data fields.ValueMapis an application-specific type alias or struct representing a map from bin names to values.
Integration Points:
Theputandgetmethods support the core data access patterns typically used in Aerospike client operations, enabling testing or local caching without external dependencies.
Diagram: Structure of MemStore
classDiagram
class MemStore {
-inner: Arc<Mutex<HashMap<String, ValueMap>>>
+new()
+get()
+put()
+db_reads()
+db_writes()
+fmt()
}
MemStore ..|> KeyValueStore
This diagram shows MemStore with its main field and methods, illustrating its implementation of the KeyValueStore trait. The internal use of a thread-safe hash map is also highlighted.