* Upgrade cppitertools, spdlog, fmt, rapidcheck * Make compilation work on both v4 and v5 toolchains
212 lines
6.1 KiB
C++
212 lines
6.1 KiB
C++
// Copyright 2024 Memgraph Ltd.
|
|
//
|
|
// Use of this software is governed by the Business Source License
|
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
|
// License, and you may not use this file except in compliance with the Business Source License.
|
|
//
|
|
// As of the Change Date specified in that file, in accordance with
|
|
// the Business Source License, use of this software will be governed
|
|
// by the Apache License, Version 2.0, included in the file
|
|
// licenses/APL.txt.
|
|
|
|
#pragma once
|
|
|
|
#include <filesystem>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "utils/exceptions.hpp"
|
|
|
|
namespace memgraph::kvstore {
|
|
|
|
class KVStoreError : public utils::BasicException {
|
|
public:
|
|
using utils::BasicException::BasicException;
|
|
SPECIALIZE_GET_EXCEPTION_NAME(KVStoreError)
|
|
};
|
|
|
|
/**
|
|
* Abstraction used to manage key-value pairs. The underlying implementation
|
|
* guarantees thread safety and durability properties.
|
|
*/
|
|
class KVStore final {
|
|
public:
|
|
KVStore() = delete;
|
|
|
|
/**
|
|
* @param storage Path to a directory where the data is persisted.
|
|
*
|
|
* NOTE: Don't instantiate more instances of a KVStore with the same
|
|
* storage directory because that will lead to undefined behaviour.
|
|
*/
|
|
explicit KVStore(std::filesystem::path storage);
|
|
|
|
KVStore(const KVStore &other) = delete;
|
|
KVStore(KVStore &&other);
|
|
|
|
KVStore &operator=(const KVStore &other) = delete;
|
|
KVStore &operator=(KVStore &&other);
|
|
|
|
~KVStore();
|
|
|
|
/**
|
|
* Store value under the given key.
|
|
*
|
|
* @param key
|
|
* @param value
|
|
*
|
|
* @return true if the value has been successfully stored.
|
|
* In case of any error false is going to be returned.
|
|
*/
|
|
bool Put(std::string_view key, std::string_view value);
|
|
|
|
/**
|
|
* Store values under the given keys.
|
|
*
|
|
* @param items
|
|
*
|
|
* @return true if the items have been successfully stored.
|
|
* In case of any error false is going to be returned.
|
|
*/
|
|
bool PutMultiple(const std::map<std::string, std::string> &items);
|
|
|
|
/**
|
|
* Retrieve value for the given key.
|
|
*
|
|
* @param key
|
|
*
|
|
* @return Value for the given key. std::nullopt in case of any error
|
|
* OR the value doesn't exist.
|
|
*/
|
|
std::optional<std::string> Get(std::string_view key) const noexcept;
|
|
|
|
/**
|
|
* Deletes the key and corresponding value from storage.
|
|
*
|
|
* @param key
|
|
*
|
|
* @return True on success, false on error. The return value is
|
|
* true if the key doesn't exist and underlying storage
|
|
* didn't encounter any error.
|
|
*/
|
|
bool Delete(std::string_view key);
|
|
|
|
/**
|
|
* Deletes the keys and corresponding values from storage.
|
|
*
|
|
* @param keys
|
|
*
|
|
* @return True on success, false on error. The return value is
|
|
* true if the keys don't exist and underlying storage
|
|
* didn't encounter any error.
|
|
*/
|
|
bool DeleteMultiple(const std::vector<std::string> &keys);
|
|
|
|
/**
|
|
* Delete all (key, value) pairs where key begins with a given prefix.
|
|
*
|
|
* @param prefix - prefix of the keys in (key, value) pairs to be deleted.
|
|
* This parameter is optional and is empty by default.
|
|
*
|
|
* @return True on success, false on error. The return value is
|
|
* true if the key doesn't exist and underlying storage
|
|
* didn't encounter any error.
|
|
*/
|
|
bool DeletePrefix(const std::string &prefix = "");
|
|
|
|
/**
|
|
* Store values under the given keys and delete the keys.
|
|
*
|
|
* @param items
|
|
* @param keys
|
|
*
|
|
* @return true if the items have been successfully stored and deleted.
|
|
* In case of any error false is going to be returned.
|
|
*/
|
|
bool PutAndDeleteMultiple(const std::map<std::string, std::string> &items, const std::vector<std::string> &keys);
|
|
|
|
/**
|
|
* Returns total number of stored (key, value) pairs. The function takes an
|
|
* optional prefix parameter used for filtering keys that start with that
|
|
* prefix.
|
|
*
|
|
* @param prefix - prefix on which the keys should be filtered. This parameter
|
|
* is optional and is empty by default.
|
|
*
|
|
* @return - number of stored pairs.
|
|
*/
|
|
size_t Size(const std::string &prefix = "") const;
|
|
|
|
/**
|
|
* Compact the underlying storage for the key range [begin_prefix,
|
|
* end_prefix].
|
|
* The actual compaction interval might be superset of
|
|
* [begin_prefix, end_prefix].
|
|
*
|
|
* @param begin_prefix - Compaction interval start.
|
|
* @param end_prefix - Compaction interval end.
|
|
*
|
|
* @return - true if the compaction finished successfully, false otherwise.
|
|
*/
|
|
bool CompactRange(const std::string &begin_prefix, const std::string &end_prefix);
|
|
|
|
/**
|
|
* Custom prefix-based iterator over kvstore.
|
|
*
|
|
* It filters all (key, value) pairs where the key has a certain prefix
|
|
* and behaves as if all of those pairs are stored in a single iterable
|
|
* collection of std::pair<std::string, std::string>.
|
|
*/
|
|
class iterator final {
|
|
public:
|
|
using iterator_concept [[maybe_unused]] = std::input_iterator_tag;
|
|
using value_type = std::pair<std::string, std::string>;
|
|
using difference_type = long;
|
|
using pointer = const std::pair<std::string, std::string> *;
|
|
using reference = const std::pair<std::string, std::string> &;
|
|
|
|
explicit iterator(const KVStore *kvstore, const std::string &prefix = "", bool at_end = false);
|
|
|
|
iterator(const iterator &other) = delete;
|
|
|
|
iterator(iterator &&other);
|
|
|
|
~iterator();
|
|
|
|
iterator &operator=(iterator &&other);
|
|
|
|
iterator &operator=(const iterator &other) = delete;
|
|
|
|
iterator &operator++();
|
|
|
|
bool operator==(const iterator &other) const;
|
|
|
|
bool operator!=(const iterator &other) const;
|
|
|
|
reference operator*();
|
|
|
|
pointer operator->();
|
|
|
|
void SetInvalid();
|
|
|
|
bool IsValid();
|
|
|
|
private:
|
|
struct impl;
|
|
std::unique_ptr<impl> pimpl_;
|
|
};
|
|
|
|
iterator begin(const std::string &prefix = "") const { return iterator(this, prefix); }
|
|
|
|
iterator end(const std::string &prefix = "") const { return iterator(this, prefix, true); }
|
|
|
|
private:
|
|
struct impl;
|
|
std::unique_ptr<impl> pimpl_;
|
|
};
|
|
|
|
} // namespace memgraph::kvstore
|