Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ jobs:
run: |
bazel coverage //:test_kvs_cpp \
--collect_code_coverage \
--instrument_test_targets \
--combined_report=lcov \
--experimental_generate_llvm_lcov \
--nocache_test_results \
Expand Down
4 changes: 2 additions & 2 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ alias(

test_suite(
name = "test_kvs_cpp",
tests = ["//tests/cpp:test_kvs_cpp"],
tests = ["//src/cpp/tests:test_kvs_cpp"],
visibility = ["//visibility:public"],
)

test_suite(
name = "bm_kvs_cpp",
tests = ["//tests/cpp:bm_kvs_cpp"],
tests = ["//src/cpp/tests:bm_kvs_cpp"],
visibility = ["//visibility:public"],
)
2 changes: 1 addition & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ archive_override(
bazel_dep(name = "score-baselibs", version = "0.0.0")
git_override(
module_name = "score-baselibs",
commit = "f0a394a602986ddf7abac6a238b9d44535a4b597",
commit = "ae349b99cafc1e79d98c0391a851fc5664c04ebc",
remote = "https://github.com/eclipse-score/baselibs.git",
)
22 changes: 6 additions & 16 deletions src/cpp/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,19 @@
# *******************************************************************************

# The filegroup is used to collect all source files for the tests.
filegroup(
name = "kvs_srcs",
srcs = glob([
"src/*.cpp",
"inc/**/*.hpp",
]),
visibility = [
"//tests/cpp:__pkg__",
],
)

cc_library(
name = "kvs_cpp",
srcs = glob(["src/*.cpp"]),
hdrs = glob([
"inc/**/*.hpp",
]),
srcs = [
"inc/internal/kvs_helper.hpp",
"src/kvs.cpp",
],
hdrs = ["inc/kvs.hpp"],
includes = ["inc"],
visibility = ["//:__pkg__"],
deps = [
"@score-baselibs//score/filesystem:filesystem",
"@score-baselibs//score/json:interface",
"@score-baselibs//score/json:json_parser",
"@score-baselibs//score/json",
"@score-baselibs//score/result:result",
],
)
3 changes: 0 additions & 3 deletions src/cpp/inc/internal/kvs_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ uint32_t parse_hash_adler32(std::istream& in);
uint32_t calculate_hash_adler32(const std::string& data);
std::array<uint8_t,4> get_hash_bytes_adler32(uint32_t hash);
std::array<uint8_t,4> get_hash_bytes(const std::string& data);
score::Result<std::unordered_map<std::string, KvsValue>> parse_json_data(const std::string& data);
score::Result<std::unordered_map<std::string, KvsValue>> open_json(const std::string& prefix, OpenJsonNeedFile need_file);
score::ResultBlank write_json_data(const std::string& filename_prefix, const std::string& buf);
score::Result<KvsValue> any_to_kvsvalue(const score::json::Any& any);
score::Result<score::json::Any> kvsvalue_to_any(const KvsValue& kv);

Expand Down
76 changes: 54 additions & 22 deletions src/cpp/inc/kvs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ enum class MyErrorCode : score::result::ErrorCode {
MutexLockFailed,

/* Invalid value type*/
InvalidValueType
InvalidValueType,
};

class MyErrorDomain final : public score::result::ErrorDomain
Expand Down Expand Up @@ -180,7 +180,11 @@ class KvsValue final{

/* Enum to represent the type of the value*/
enum class Type {
Number,
i32,
u32,
i64,
u64,
f64,
Boolean,
String,
Null,
Expand All @@ -189,7 +193,11 @@ class KvsValue final{
};

/* Constructors for each type*/
explicit KvsValue(double number) : value(number), type(Type::Number) {}
explicit KvsValue(int32_t number) : value(number), type(Type::i32) {}
explicit KvsValue(uint32_t number) : value(number), type(Type::u32) {}
explicit KvsValue(int64_t number) : value(number), type(Type::i64) {}
explicit KvsValue(uint64_t number) : value(number), type(Type::u64) {}
explicit KvsValue(double number) : value(number), type(Type::f64) {}
explicit KvsValue(bool boolean) : value(boolean), type(Type::Boolean) {}
explicit KvsValue(const std::string& str) : value(str), type(Type::String) {}
explicit KvsValue(std::nullptr_t) : value(nullptr), type(Type::Null) {}
Expand All @@ -200,13 +208,13 @@ class KvsValue final{
Type getType() const { return type; }

/* Access the underlying value (use std::get to retrieve the value)*/
const std::variant<double, bool, std::string, std::nullptr_t, Array, Object>& getValue() const {
const std::variant<int32_t, uint32_t, int64_t, uint64_t, double, bool, std::string, std::nullptr_t, Array, Object>& getValue() const {
return value;
}

private:
/* The underlying value*/
std::variant<double, bool, std::string, std::nullptr_t, Array, Object> value;
std::variant<int32_t, uint32_t, int64_t, uint64_t, double, bool, std::string, std::nullptr_t, Array, Object> value;

/* The type of the value*/
Type type;
Expand Down Expand Up @@ -234,15 +242,14 @@ class KvsValue final{
* - `reset_key`: Resets a key to its default value if available.
* - `has_default_value`: Checks if a default value exists for a specific key.
* - `set_value`: Sets the value for a specific key in the KVS.
* - `set_default_value`: Sets a default value for a specific key.
* - `remove_key`: Removes a specific key from the KVS.
* - `flush`: Flushes the KVS to storage.
* - `flush_default`: Flushes the default values to storage.
* - `snapshot_count`: Retrieves the number of available snapshots.
* - `snapshot_max_count`: Retrieves the maximum number of snapshots allowed.
* - `snapshot_restore`: Restores the KVS from a specified snapshot.
* - `get_kvs_filename`: Retrieves the filename associated with a snapshot.
* - `get_kvs_hash_filename`: Retrieves the hash filename associated with a snapshot.
* - `get_hash_filename`: Retrieves the hash filename associated with a snapshot.
*
* Private Members:
* - `kvs_mutex`: A mutex for ensuring thread safety.
Expand All @@ -264,7 +271,7 @@ class KvsValue final{
*
* int main() {
* // Open kvs
* auto open_res = KvsBuilder("Process_Name", 0)
* auto open_res = KvsBuilder(0)
* .need_defaults_flag(true)
* .need_kvs_flag(true)
* .build();
Expand Down Expand Up @@ -305,8 +312,6 @@ class Kvs final {
* It allows the caller to specify whether default values and an existing KVS are required
* or optional during the opening process.
*
* @param process_name The name of the process that is opening the KVS. This is used to create a unique directory for the KVS instance.
* Important: It must be unique for each application to avoid conflicts.
* @param id The instance ID of the KVS. This uniquely identifies the KVS instance.
* @param need_defaults A flag of type OpenNeedDefaults indicating whether default values
* are required or optional.
Expand All @@ -315,6 +320,8 @@ class Kvs final {
* @param need_kvs A flag of type OpenNeedKvs indicating whether the KVS is required or optional.
* - OpenNeedKvs::Required: The KVS must already exist.
* - OpenNeedKvs::Optional: An empty KVS will be used if no KVS exists.
* @param dir The directory path where the KVS files are located. It is passed as an rvalue reference to avoid unnecessary copying.
* Use "" or "." for the current directory.
* @return A Result object containing either:
* - A Kvs object if the operation is successful.
* - An ErrorCode if an error occurs during the operation.
Expand All @@ -326,7 +333,7 @@ class Kvs final {
* - ErrorCode::ValidationFailed: Validation of the KVS data failed.
* - ErrorCode::ResourceBusy: The KVS resource is currently in use.
*/
static score::Result<Kvs> open(const std::string&& process_name, const InstanceId& id, OpenNeedDefaults need_defaults, OpenNeedKvs need_kvs);
static score::Result<Kvs> open(const InstanceId& instance_id, OpenNeedDefaults need_defaults, OpenNeedKvs need_kvs, const std::string&& dir);

/**
* @brief Sets whether the key-value store should flush its contents to
Expand Down Expand Up @@ -468,9 +475,11 @@ class Kvs final {
/**
* @brief Retrieves the number of snapshots currently stored in the key-value store.
*
* @return The total count of snapshots as a size_t value.
* @return A score::Result object that indicates the success or failure of the operation.
* - On success: The total count of snapshots as a size_t value.
* - On failure: Returns an ErrorCode describing the error.
*/
size_t snapshot_count() const;
score::Result<size_t> snapshot_count() const;


/**
Expand Down Expand Up @@ -503,9 +512,11 @@ class Kvs final {
* @brief Retrieves the filename associated with a given snapshot ID in the key-value store.
*
* @param snapshot_id The identifier of the snapshot for which the filename is to be retrieved.
* @return A String with the filename associated with the snapshot ID.
* @return score::ResultBlank
* - On success: A score::filesystem::Path with the filename (path) associated with the snapshot ID.
* - On failure: An error code describing the reason for the failure.
*/
std::string get_kvs_filename(const SnapshotId& snapshot_id) const;
score::Result<score::filesystem::Path> get_kvs_filename(const SnapshotId& snapshot_id) const;


/**
Expand All @@ -516,9 +527,11 @@ class Kvs final {
* store metadata or integrity information for the snapshot.
*
* @param snapshot_id The identifier of the snapshot for which the hash filename is requested.
* @return A String with the filename of the hash file associated with the snapshot ID.
* @return score::ResultBlank
* - On success: A score::filesystem::Path with the filename (path) of the hash file associated with the snapshot ID.
* - On failure: An error code describing the reason for the failure.
*/
std::string get_kvs_hash_filename(const SnapshotId& snapshot_id) const;
score::Result<score::filesystem::Path> get_hash_filename(const SnapshotId& snapshot_id) const;

private:
/* Private constructor to prevent direct instantiation */
Expand All @@ -535,11 +548,21 @@ class Kvs final {
std::unordered_map<std::string, KvsValue> default_values;

/* Filename prefix */
std::string filename_prefix;
score::filesystem::Path filename_prefix;

/* Flush on exit flag for written Keys */
std::atomic<bool> flush_on_exit;


/* Filesystem handling */
std::unique_ptr<score::filesystem::Filesystem> filesystem;

/* Json handling */
std::unique_ptr<score::json::IJsonParser> parser;
std::unique_ptr<score::json::IJsonWriter> writer;

score::Result<std::unordered_map<std::string, KvsValue>> parse_json_data(const std::string& data);
score::Result<std::unordered_map<std::string, KvsValue>> open_json(const score::filesystem::Path& prefix, OpenJsonNeedFile need_file);
score::ResultBlank write_json_data(const std::string& buf);
};


Expand All @@ -553,7 +576,7 @@ class KvsBuilder final {
* @brief Constructs a KvsBuilder for the given KVS instance.
* @param instance_id Unique identifier for the KVS instance.
*/
explicit KvsBuilder(std::string&& process_name, const InstanceId& instance_id);
explicit KvsBuilder(const InstanceId& instance_id);

/**
* @brief Specify whether default values must be loaded.
Expand All @@ -569,20 +592,29 @@ class KvsBuilder final {
*/
KvsBuilder& need_kvs_flag(bool flag);

/**
* @brief Specify the directory where KVS files are stored.
* @param dir The directory path as a string.
* Use "" or "." for the current directory.
*
* @return Reference to this builder (for chaining).
*/
KvsBuilder& dir(std::string&& dir_path);

/**
* @brief Builds and opens the Kvs instance with the configured options.
*
* Internally calls Kvs::open() with the selected flags and directory.
*
* @return A score::Result<Kvs> containing the opened store or an ErrorCode.
*/
score::Result<Kvs> build() const;
score::Result<Kvs> build();

private:
InstanceId instance_id; ///< ID of the KVS instance
bool need_defaults; ///< Whether default values are required
bool need_kvs; ///< Whether an existing KVS is required
std::string process_name; ///< Process name for the KVS files
std::string directory; ///< Directory where to store the KVS Files
};

#endif /* SCORE_LIB_KVS_KVS_HPP */
Loading