2021-10-03 18:07:04 +08:00
|
|
|
// Copyright 2021 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.
|
|
|
|
|
2018-04-27 17:23:40 +08:00
|
|
|
#pragma once
|
|
|
|
|
2019-04-23 17:00:49 +08:00
|
|
|
#include <filesystem>
|
2018-08-14 17:34:00 +08:00
|
|
|
#include <map>
|
2018-04-30 19:34:41 +08:00
|
|
|
#include <memory>
|
2019-04-23 17:00:49 +08:00
|
|
|
#include <optional>
|
2018-04-27 17:23:40 +08:00
|
|
|
#include <string>
|
2018-08-14 17:34:00 +08:00
|
|
|
#include <vector>
|
2018-04-27 17:23:40 +08:00
|
|
|
|
|
|
|
#include "utils/exceptions.hpp"
|
|
|
|
|
2020-01-24 17:45:05 +08:00
|
|
|
namespace kvstore {
|
2018-04-27 17:23:40 +08:00
|
|
|
|
|
|
|
class KVStoreError : public utils::BasicException {
|
|
|
|
public:
|
|
|
|
using utils::BasicException::BasicException;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Abstraction used to manage key-value pairs. The underlying implementation
|
|
|
|
* guarantees thread safety and durability properties.
|
|
|
|
*/
|
|
|
|
class KVStore final {
|
|
|
|
public:
|
2018-06-12 17:29:22 +08:00
|
|
|
KVStore() = delete;
|
|
|
|
|
2018-04-27 17:23:40 +08:00
|
|
|
/**
|
|
|
|
* @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.
|
|
|
|
*/
|
2019-04-23 17:00:49 +08:00
|
|
|
explicit KVStore(std::filesystem::path storage);
|
2018-04-27 17:23:40 +08:00
|
|
|
|
2018-06-12 17:29:22 +08:00
|
|
|
KVStore(const KVStore &other) = delete;
|
|
|
|
KVStore(KVStore &&other);
|
|
|
|
|
|
|
|
KVStore &operator=(const KVStore &other) = delete;
|
|
|
|
KVStore &operator=(KVStore &&other);
|
|
|
|
|
|
|
|
~KVStore();
|
|
|
|
|
2018-04-27 17:23:40 +08:00
|
|
|
/**
|
|
|
|
* 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(const std::string &key, const std::string &value);
|
|
|
|
|
2018-08-14 17:34:00 +08:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2018-04-27 17:23:40 +08:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2019-04-23 17:00:49 +08:00
|
|
|
std::optional<std::string> Get(const std::string &key) const noexcept;
|
2018-04-27 17:23:40 +08:00
|
|
|
|
|
|
|
/**
|
2018-06-12 17:29:22 +08:00
|
|
|
* Deletes the key and corresponding value from storage.
|
2018-04-27 17:23:40 +08:00
|
|
|
*
|
|
|
|
* @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(const std::string &key);
|
|
|
|
|
2018-08-14 17:34:00 +08:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2018-06-12 17:29:22 +08:00
|
|
|
/**
|
|
|
|
* 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 = "");
|
|
|
|
|
2018-08-14 17:34:00 +08:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2021-02-18 22:32:43 +08:00
|
|
|
bool PutAndDeleteMultiple(const std::map<std::string, std::string> &items, const std::vector<std::string> &keys);
|
2018-08-14 17:34:00 +08:00
|
|
|
|
2018-06-12 17:29:22 +08:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2021-07-22 22:22:08 +08:00
|
|
|
size_t Size(const std::string &prefix = "") const;
|
2018-06-12 17:29:22 +08:00
|
|
|
|
2019-03-29 21:14:08 +08:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2021-02-18 22:32:43 +08:00
|
|
|
bool CompactRange(const std::string &begin_prefix, const std::string &end_prefix);
|
2019-03-29 21:14:08 +08:00
|
|
|
|
2018-06-12 17:29:22 +08:00
|
|
|
/**
|
|
|
|
* 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>.
|
|
|
|
*/
|
2021-02-18 22:32:43 +08:00
|
|
|
class iterator final : public std::iterator<std::input_iterator_tag, // iterator_category
|
|
|
|
std::pair<std::string, std::string>, // value_type
|
|
|
|
long, // difference_type
|
|
|
|
const std::pair<std::string, std::string> *, // pointer
|
|
|
|
const std::pair<std::string, std::string> & // reference
|
|
|
|
> {
|
2018-06-12 17:29:22 +08:00
|
|
|
public:
|
2021-02-18 22:32:43 +08:00
|
|
|
explicit iterator(const KVStore *kvstore, const std::string &prefix = "", bool at_end = false);
|
2018-06-12 17:29:22 +08:00
|
|
|
|
|
|
|
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_;
|
|
|
|
};
|
|
|
|
|
2021-07-22 22:22:08 +08:00
|
|
|
iterator begin(const std::string &prefix = "") const { return iterator(this, prefix); }
|
2018-06-12 17:29:22 +08:00
|
|
|
|
2021-07-22 22:22:08 +08:00
|
|
|
iterator end(const std::string &prefix = "") const { return iterator(this, prefix, true); }
|
2018-06-12 17:29:22 +08:00
|
|
|
|
2018-04-27 17:23:40 +08:00
|
|
|
private:
|
2018-06-12 17:29:22 +08:00
|
|
|
struct impl;
|
|
|
|
std::unique_ptr<impl> pimpl_;
|
2018-04-27 17:23:40 +08:00
|
|
|
};
|
|
|
|
|
2020-01-24 17:45:05 +08:00
|
|
|
} // namespace kvstore
|