3#ifndef LIBZARR_STORE_HPP
4#define LIBZARR_STORE_HPP
30 enum class Kind : std::uint8_t {
72 std::vector<std::string>
keys;
90 virtual ~Store() =
default;
93 [[nodiscard]]
virtual std::optional<Bytes>
read(std::string_view key) = 0;
99 [[nodiscard]]
virtual std::optional<Bytes>
read_range(std::string_view key,
ByteRange range);
104 [[nodiscard]]
virtual std::optional<std::uint64_t>
size(std::string_view key) {
105 const auto value =
read(key);
109 return value->size();
118 [[nodiscard]]
virtual std::vector<std::optional<Bytes>>
read_many(
119 const std::vector<ReadRequest>& requests) {
120 std::vector<std::optional<Bytes>> out;
121 out.reserve(requests.size());
123 out.push_back(
read_range(req.key, req.range));
132 [[nodiscard]]
virtual bool exists(std::string_view key) = 0;
135 virtual void erase(std::string_view key) = 0;
142 [[nodiscard]]
virtual std::vector<std::string>
list_prefix(std::string_view prefix) = 0;
152 [[nodiscard]] std::optional<Bytes>
read(std::string_view key)
override {
153 const auto it = map_.find(key);
154 if (it == map_.end()) {
161 map_.insert_or_assign(std::string(key), std::move(value));
164 [[nodiscard]] std::optional<std::uint64_t>
size(std::string_view key)
override {
165 const auto it = map_.find(key);
166 if (it == map_.end()) {
169 return it->second.size();
172 [[nodiscard]]
bool exists(std::string_view key)
override {
return map_.find(key) != map_.end(); }
174 void erase(std::string_view key)
override {
175 const auto it = map_.find(key);
176 if (it != map_.end()) {
181 [[nodiscard]] std::vector<std::string>
list_prefix(std::string_view prefix)
override {
182 check_prefix(prefix);
183 std::vector<std::string> out;
184 for (
auto it = map_.lower_bound(prefix); it != map_.end() && starts_with(it->first, prefix);
186 out.push_back(it->first);
192 check_prefix(prefix);
194 for (
auto it = map_.lower_bound(prefix); it != map_.end() && starts_with(it->first, prefix);
196 const auto rest = std::string_view(it->first).substr(prefix.size());
197 const auto slash = rest.find(
'/');
198 if (slash == std::string_view::npos) {
199 out.
keys.emplace_back(rest);
203 const auto child = rest.substr(0, slash);
214 [[nodiscard]] std::size_t
key_count()
const {
return map_.size(); }
217 static bool starts_with(std::string_view text, std::string_view prefix) {
218 return text.size() >= prefix.size() && text.compare(0, prefix.size(), prefix) == 0;
221 static void check_prefix(std::string_view prefix) {
222 if (!prefix.empty() && prefix.back() !=
'/') {
223 throw error(
"store prefix must be empty or end with '/', got '" + std::string(prefix) +
"'");
227 std::map<std::string, Bytes, std::less<>> map_;
231 auto value =
read(key);
235 const std::uint64_t
size = value->size();
236 std::uint64_t begin = 0;
237 std::uint64_t count = 0;
238 switch (range.
kind) {
243 throw error(
"read_range: slice at offset " + std::to_string(range.
offset) +
" of length " +
244 std::to_string(range.
length) +
" out of bounds for \"" + std::string(key) +
245 "\" (" + std::to_string(
size) +
" bytes)");
252 throw error(
"read_range: suffix of length " + std::to_string(range.
length) +
253 " out of bounds for \"" + std::string(key) +
"\" (" + std::to_string(
size) +
260 const auto first = value->begin() +
static_cast<std::ptrdiff_t
>(begin);
261 return Bytes(first, first +
static_cast<std::ptrdiff_t
>(count));
DirListing list_dir(std::string_view prefix) override
Immediate children under prefix ("" or ending in '/').
Definition store.hpp:191
void write(std::string_view key, Bytes value) override
Create or replace the value at key.
Definition store.hpp:160
std::optional< std::uint64_t > size(std::string_view key) override
Definition store.hpp:164
std::vector< std::string > list_prefix(std::string_view prefix) override
All keys starting with prefix ("" or ending in '/'), sorted.
Definition store.hpp:181
std::optional< Bytes > read(std::string_view key) override
Full value at key, or std::nullopt if the key is absent.
Definition store.hpp:152
std::size_t key_count() const
Definition store.hpp:214
bool exists(std::string_view key) override
True if key holds a value.
Definition store.hpp:172
void erase(std::string_view key) override
Remove key; removing an absent key is a no-op.
Definition store.hpp:174
virtual bool exists(std::string_view key)=0
True if key holds a value.
virtual void flush()
Definition store.hpp:139
virtual void write(std::string_view key, Bytes value)=0
Create or replace the value at key.
virtual DirListing list_dir(std::string_view prefix)=0
Immediate children under prefix ("" or ending in '/').
virtual std::vector< std::optional< Bytes > > read_many(const std::vector< ReadRequest > &requests)
Definition store.hpp:118
virtual std::optional< Bytes > read_range(std::string_view key, ByteRange range)
Definition store.hpp:230
virtual std::optional< std::uint64_t > size(std::string_view key)
Definition store.hpp:104
virtual std::vector< std::string > list_prefix(std::string_view prefix)=0
All keys starting with prefix ("" or ending in '/'), sorted.
virtual void erase(std::string_view key)=0
Remove key; removing an absent key is a no-op.
virtual std::optional< Bytes > read(std::string_view key)=0
Full value at key, or std::nullopt if the key is absent.
Byte-range request for Store::read_range.
Definition store.hpp:28
Kind
Which part of the value to read.
Definition store.hpp:30
@ suffix
the final length bytes
@ slice
length bytes starting at offset
std::uint64_t offset
Start of the range; used by Kind::slice only.
Definition store.hpp:39
static constexpr ByteRange full()
The whole value.
Definition store.hpp:44
static constexpr ByteRange slice(std::uint64_t offset, std::uint64_t length)
Definition store.hpp:48
std::uint64_t length
Number of bytes; used by Kind::slice and Kind::suffix.
Definition store.hpp:41
static constexpr ByteRange suffix(std::uint64_t length)
Definition store.hpp:55
Kind kind
Which part of the value to read.
Definition store.hpp:37
Immediate children of a prefix, as returned by Store::list_dir.
Definition store.hpp:70
std::vector< std::string > keys
Child keys, relative to the queried prefix, sorted.
Definition store.hpp:72
std::vector< std::string > prefixes
Child prefixes ("directories"), relative, without trailing '/', sorted.
Definition store.hpp:74
std::string_view key
Key to read; must outlive the read_many call (as with any Store key).
Definition store.hpp:64
ByteRange range
Range within the value.
Definition store.hpp:66
std::vector< std::uint8_t > Bytes
Owned byte buffer used throughout the value-based public API.
Definition types.hpp:42