Distributed key-value store as a pluggable Node subsystem. More...
#include "librats/util/rats_export.h"#include "librats/node/peer_network.h"#include "librats/peer/peer.h"#include "librats/peer/peer_id.h"#include "librats/core/bytes.h"#include "librats/util/json.h"#include <string>#include <vector>#include <functional>#include <map>#include <memory>#include <mutex>#include <unordered_map>#include <atomic>#include <chrono>#include <thread>#include <optional>#include <condition_variable>Go to the source code of this file.
Classes | |
| struct | librats::StorageEntry |
| Storage entry - represents a single key-value pair in the database. More... | |
| struct | librats::StorageChangeEvent |
| Storage change event - passed to change callbacks. More... | |
| struct | librats::StorageConfig |
| Storage configuration. More... | |
| struct | librats::StorageStatistics |
| Storage statistics. More... | |
| class | librats::StorageManager |
| StorageManager - Distributed key-value storage with peer synchronization. More... | |
Namespaces | |
| namespace | librats |
Typedefs | |
| using | librats::StorageChangeCallback = std::function< void(const StorageChangeEvent &)> |
| Callback function types for storage events. | |
| using | librats::StorageSyncCompleteCallback = std::function< void(bool success, const std::string &error_message)> |
Enumerations | |
| enum class | librats::StorageValueType : uint8_t { librats::BINARY = 0x01 , librats::STRING = 0x02 , librats::INT64 = 0x03 , librats::DOUBLE = 0x04 , librats::JSON = 0x05 } |
| Value types supported by the distributed storage. More... | |
| enum class | librats::StorageOperation : uint8_t { librats::OP_PUT = 0x01 , librats::OP_DELETE = 0x02 } |
| Storage operation types for change events. More... | |
| enum class | librats::StorageSyncStatus { librats::NOT_STARTED , librats::IN_PROGRESS , librats::COMPLETED , librats::FAILED } |
| Storage synchronization status. More... | |
Functions | |
| uint32_t | librats::storage_calculate_crc32 (const void *data, size_t length) |
| std::string | librats::storage_value_type_to_string (StorageValueType type) |
| StorageValueType | librats::string_to_storage_value_type (const std::string &str) |
Distributed key-value store as a pluggable Node subsystem.
A replicated key-value database with Last-Write-Wins (LWW) conflict resolution, typed values, binary on-disk persistence, and peer synchronization. It is a Subsystem: it reaches the mesh only through PeerNetwork (never the Node), exactly like PubSub/FileTransfer.
Replication model — an epidemic LWW broadcast:
deleted=true) and sends it to every connected peer.Backpressure — why a snapshot is a stream, not a message: A database is unbounded, a peer's send queue is not. One message carrying the whole store stops being sendable at the connection's low-water mark, gets the peer dropped as a slow consumer past its high-water mark, and is not even representable past the block-size ceiling — and since both ends request a snapshot on connect, two of them cross on every single link. So a snapshot is served as a sequence of bounded SYNC_CHUNK messages walking the (ordered) key space, one chunk at a time, and the next chunk is only produced while PeerNetwork::peer_writable() says there is room. Every send() return value is honoured: a peer that fills up stops receiving individual entries and is instead owed a fresh snapshot, which the sync thread starts once on_peer_writable says the link has drained. Losing live updates to a congested peer is safe precisely because the store is LWW — the snapshot that follows carries the winning state either way.
All of that runs on this module's own sync thread. Serialising even one chunk happens off the reactor thread, so a reactor never spends time (or holds storage_mutex_) proportional to the size of the database.
Wire format (MessageType::Storage payload, opcode in byte 0): ENTRY: [1][StorageEntry.serialize()] SYNC_REQUEST: [2] SYNC_CHUNK: [3][flags:u8][count:u32][StorageEntry.serialize()] * count flags bit0 (LAST) marks the final chunk of a snapshot; a snapshot of an empty store is one chunk with count 0.
The class is also usable standalone (no network attached) as a local, persistent key-value store; all network operations no-op until attach().
Definition in file storage.h.