Skip to content

Commit 63e9747

Browse files
update kvs build to avoid reopen opened instance.
- avoid openening same instance if from builder. Fixes #63
1 parent 1b3590e commit 63e9747

File tree

4 files changed

+69
-19
lines changed

4 files changed

+69
-19
lines changed

src/cpp/src/kvs.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "kvs.hpp"
1818

1919
//TODO Default Value Handling TBD
20-
//TODO Add Score Logging
2120
//TODO Replace std libs with baselibs
2221
//TODO String Handling in set_value TBD: (e.g. set_value("key", "value") is not correct, since KvsValue() expects a string ptr and not a string)
2322

src/cpp/src/kvsbuilder.cpp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,31 @@
1414

1515
namespace score::mw::per::kvs {
1616

17+
//Definition of static member variables
18+
std::unordered_map<size_t, std::shared_ptr<Kvs>> KvsBuilder::kvs_instances;
19+
KvsBuilder* KvsBuilder::latest_instance = nullptr;
20+
std::mutex KvsBuilder::kvs_instances_mutex; ///< Mutex for synchronizing access to KVS instances
21+
std::mutex KvsBuilder::latest_instance_mutex; ///< Mutex for synchronizing access to KVS Builder
22+
1723
/*********************** KVS Builder Implementation *********************/
1824
KvsBuilder::KvsBuilder(const InstanceId& instance_id)
1925
: instance_id(instance_id)
2026
, need_defaults(false)
2127
, need_kvs(false)
2228
, directory("./data_folder/") /* Default Directory */
23-
{}
29+
{
30+
std::lock_guard<std::mutex> lock(latest_instance_mutex);
31+
latest_instance = this;
32+
}
33+
34+
KvsBuilder::~KvsBuilder() {
35+
std::lock(latest_instance_mutex, kvs_instances_mutex);
36+
std::lock_guard<std::mutex> latest_lock(latest_instance_mutex, std::adopt_lock);
37+
std::lock_guard<std::mutex> kvs_instances_lock(kvs_instances_mutex, std::adopt_lock);
38+
if (latest_instance == this) {
39+
kvs_instances.clear();
40+
}
41+
}
2442

2543
KvsBuilder& KvsBuilder::need_defaults_flag(bool flag) {
2644
need_defaults = flag;
@@ -38,22 +56,38 @@ KvsBuilder& KvsBuilder::dir(std::string&& dir_path) {
3856
}
3957

4058

41-
score::Result<Kvs> KvsBuilder::build() {
42-
score::Result<Kvs> result = score::MakeUnexpected(ErrorCode::UnmappedError);
59+
score::Result<std::shared_ptr<Kvs>> KvsBuilder::build() {
4360

4461
/* Use current directory if empty */
45-
if ("" == directory) {
62+
if (directory.empty()) {
4663
directory = "./";
4764
}
4865

49-
result = Kvs::open(
66+
//Lock the mutex before accessing the cache
67+
std::lock_guard<std::mutex> lock(kvs_instances_mutex);
68+
69+
auto it = kvs_instances.find(instance_id.id);
70+
if(it != kvs_instances.end()) {
71+
/* Return existing instance */
72+
return score::Result<std::shared_ptr<Kvs>>(it->second);
73+
}
74+
75+
auto opened_kvs = Kvs::open(
5076
instance_id,
5177
need_defaults ? OpenNeedDefaults::Required : OpenNeedDefaults::Optional,
5278
need_kvs ? OpenNeedKvs::Required : OpenNeedKvs::Optional,
5379
std::move(directory)
5480
);
5581

56-
return result;
82+
if(opened_kvs.has_value()) {
83+
auto kvs_ptr = std::make_shared<Kvs>(std::move(opened_kvs.value()));
84+
kvs_instances.insert({instance_id.id, kvs_ptr});
85+
return score::Result<std::shared_ptr<Kvs>>(kvs_ptr);
86+
}
87+
else {
88+
return score::Result<std::shared_ptr<Kvs>>(score::Unexpected(opened_kvs.error()));
89+
}
90+
5791
}
5892

5993
} /* namespace score::mw::per::kvs */

src/cpp/src/kvsbuilder.hpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
#define SCORE_LIB_KVS_KVSBUILDER_HPP
1515

1616
#include <string>
17+
#include <unordered_map>
18+
#include <mutex>
1719
#include "kvs.hpp"
18-
1920
namespace score::mw::per::kvs {
2021

2122
/**
@@ -64,6 +65,11 @@ class KvsBuilder final {
6465
*/
6566
explicit KvsBuilder(const InstanceId& instance_id);
6667

68+
/**
69+
* @brief Destroys the KvsBuilder instance.
70+
*/
71+
~KvsBuilder();
72+
6773
/**
6874
* @brief Specify whether default values must be loaded.
6975
* @param flag True to require default values; false to make them optional.
@@ -94,13 +100,18 @@ class KvsBuilder final {
94100
*
95101
* @return A score::Result<Kvs> containing the opened store or an ErrorCode.
96102
*/
97-
score::Result<Kvs> build();
103+
score::Result<std::shared_ptr<Kvs>> build();
98104

99105
private:
100-
InstanceId instance_id; ///< ID of the KVS instance
101-
bool need_defaults; ///< Whether default values are required
102-
bool need_kvs; ///< Whether an existing KVS is required
103-
std::string directory; ///< Directory where to store the KVS Files
106+
InstanceId instance_id; ///< ID of the KVS instance
107+
bool need_defaults; ///< Whether default values are required
108+
bool need_kvs; ///< Whether an existing KVS is required
109+
std::string directory; ///< Directory where to store the KVS Files
110+
static std::mutex kvs_instances_mutex; ///< Mutex for synchronizing access to KVS instances
111+
static std::mutex latest_instance_mutex; ///< Mutex for synchronizing access to KVS Builder
112+
static std::unordered_map<size_t, std::shared_ptr<Kvs>> kvs_instances; ///< Map of KVS instances
113+
static KvsBuilder* latest_instance;
114+
104115
};
105116

106117
} /* namespace score::mw::per::kvs */

src/cpp/tests/test_kvs_builder.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,33 @@ TEST(kvs_kvsbuilder, kvsbuilder_build) {
4343
builder.need_kvs_flag(false);
4444
result_build = builder.build();
4545
EXPECT_TRUE(result_build);
46-
result_build.value().flush_on_exit = false;
47-
EXPECT_EQ(result_build.value().filename_prefix.CStr(), "./kvsbuilder/kvs_"+std::to_string(instance_id.id));
46+
result_build.value()->flush_on_exit = false;
47+
EXPECT_EQ(result_build.value()->filename_prefix.CStr(), "./kvsbuilder/kvs_"+std::to_string(instance_id.id));
4848
}
4949

5050
TEST(kvs_kvsbuilder, kvsbuilder_directory_check) {
5151

5252
/* Test the KvsBuilder with all configurations for the current working directory */
53-
KvsBuilder builder(instance_id);
53+
InstanceId id(10);
54+
KvsBuilder builder(id);
5455
builder.dir("");
5556
auto result_build = builder.build();
5657
EXPECT_TRUE(result_build);
57-
EXPECT_EQ(result_build.value().filename_prefix.CStr(), "./kvs_"+std::to_string(instance_id.id));
58+
EXPECT_EQ(result_build.value()->filename_prefix.CStr(), "./kvs_"+std::to_string(id.id));
59+
5860

61+
InstanceId id1(20);
5962
builder.dir("./");
63+
builder.instance_id = id1;
6064
result_build = builder.build();
6165
EXPECT_TRUE(result_build);
62-
EXPECT_EQ(result_build.value().filename_prefix.CStr(), "./kvs_"+std::to_string(instance_id.id));
66+
EXPECT_EQ(result_build.value()->filename_prefix.CStr(), "./kvs_"+std::to_string(id1.id));
6367

68+
InstanceId id2(30);
6469
builder.dir(".");
70+
builder.instance_id = id2;
6571
result_build = builder.build();
6672
EXPECT_TRUE(result_build);
67-
EXPECT_EQ(result_build.value().filename_prefix.CStr(), "./kvs_"+std::to_string(instance_id.id));
73+
EXPECT_EQ(result_build.value()->filename_prefix.CStr(), "./kvs_"+std::to_string(id2.id));
6874

6975
}

0 commit comments

Comments
 (0)