Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3f963bb
global and local build config with profiling flags.
harish876 Nov 15, 2024
804dcd1
integrated basic memory hook for RSS calculation
harish876 Nov 15, 2024
b67fa88
edited script to generate callgraph using gprof
harish876 Nov 15, 2024
4404af5
enabling level db as default storage engine
harish876 Nov 15, 2024
33c16f2
systemd telegraf script to stream prometheus node_exporter data to In…
harish876 Nov 15, 2024
7c35fe8
added lmdb storage engine interface and partially implemented.
harish876 Nov 16, 2024
ccade23
bootstrapping script to run perf tools
harish876 Nov 30, 2024
c625f78
adding process exporter to bootstrapping script
harish876 Nov 30, 2024
e1ce45d
Added LRU Cache and Observabiity stats
harish876 Dec 9, 2024
676a5d3
Merge pull request #1 from harish876/memory-hooks-integration
harish876 Jan 12, 2025
491b254
lry cache controlled using settings
harish876 Feb 12, 2025
4adc82f
Merge branch 'apache:master' into master
harish876 Feb 12, 2025
7eb9fff
removing lmdb implementation
harish876 Feb 12, 2025
d8cbe16
removing unecessary scripts
harish876 Feb 12, 2025
71975f2
Resolving comments for build flags and memory leak
harish876 Feb 17, 2025
35ed786
resolved error. options.block_cache_ integration still not working
harish876 Feb 17, 2025
b9b3363
added UT's for TC's. removed logs from stats and changed lru implemen…
harish876 Feb 19, 2025
0d02a14
reverting configs and removing unwanted files
harish876 Feb 19, 2025
8348689
removing unwanted tst logs
harish876 Feb 19, 2025
0a85b15
refactor: rename GetMetrics to UpdateMetrics and improve cache handli…
harish876 Mar 7, 2025
ccb268d
feat: add LevelDB block cache support and corresponding tests.
harish876 Mar 7, 2025
4cd5b88
feat: enhance LevelDB block cache with configurable capacity and upda…
harish876 Mar 7, 2025
a642ef8
refactor: update transaction summary variable names for consistency
harish876 Mar 7, 2025
08203e3
build: optimize compilation flags by adding optimization level
harish876 Mar 7, 2025
94d2a72
build: remove debugging flags from kv_service and api_tools builds
harish876 Mar 14, 2025
a759dda
build: remove profiling flags from set_random_data binary
harish876 Mar 14, 2025
a0a136f
build: remove pyroscope monitoring from kv service startup script
harish876 Mar 15, 2025
32b5758
build: include string header in lru_cache implementation
harish876 Mar 15, 2025
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
2 changes: 1 addition & 1 deletion .bazelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
build --cxxopt='-std=c++17' --copt=-O3 --jobs=40
build --cxxopt='-std=c++17' --copt="-pg" --linkopt="-pg" --strip=never --jobs=40
#build --action_env=PYTHON_BIN_PATH="/usr/bin/python3.10"
#build --action_env=PYTHON_LIB_PATH="/usr/include/python3.10"

6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ sdk_validator/venv
__pycache__
MODULE.*
apache_release
*.out.*
*.data.*
*.pb.*
.cache/
resdb/
100*_db/
16 changes: 16 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
workspace(name = "com_resdb_nexres")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "hedron_compile_commands",
#Replace the commit hash (4f28899228fb3ad0126897876f147ca15026151e) with the latest commit hash from the repo
url = "https://github.com/hedronvision/bazel-compile-commands-extractor/archive/4f28899228fb3ad0126897876f147ca15026151e.tar.gz",
strip_prefix = "bazel-compile-commands-extractor-4f28899228fb3ad0126897876f147ca15026151e",
)
load("@hedron_compile_commands//:workspace_setup.bzl", "hedron_compile_commands_setup")
hedron_compile_commands_setup()
load("@hedron_compile_commands//:workspace_setup_transitive.bzl", "hedron_compile_commands_setup_transitive")
hedron_compile_commands_setup_transitive()
load("@hedron_compile_commands//:workspace_setup_transitive_transitive.bzl", "hedron_compile_commands_setup_transitive_transitive")
hedron_compile_commands_setup_transitive_transitive()
load("@hedron_compile_commands//:workspace_setup_transitive_transitive_transitive.bzl", "hedron_compile_commands_setup_transitive_transitive_transitive")
hedron_compile_commands_setup_transitive_transitive_transitive()

load("//:repositories.bzl", "nexres_repositories")

nexres_repositories()
Expand Down
5 changes: 4 additions & 1 deletion chain/storage/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,14 @@ cc_library(
name = "leveldb",
srcs = ["leveldb.cpp"],
hdrs = ["leveldb.h"],
linkopts = ["-pg","-g","-ggdb"], # Enable profiling during linking
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only open this debug opts if needed.
Most of time, we dont to debug the code.

deps = [
":storage",
"//chain/storage/proto:kv_cc_proto",
"//chain/storage/proto:leveldb_config_cc_proto",
"//common:comm",
"//common/lru:lru_cache",
"//platform/statistic:stats",
"//third_party:leveldb",
],
)
Expand All @@ -64,4 +67,4 @@ cc_test(
":memory_db",
"//common/test:test_main",
],
)
)
40 changes: 40 additions & 0 deletions chain/storage/leveldb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
#include "chain/storage/leveldb.h"

#include <glog/logging.h>
#include <unistd.h>

#include "chain/storage/proto/kv.pb.h"
#include "leveldb/options.h"

namespace resdb {
namespace storage {
Expand Down Expand Up @@ -50,6 +52,14 @@ ResLevelDB::ResLevelDB(std::optional<LevelDBInfo> config) {
path = (*config).path();
}
}
if ((*config).enable_block_cache()) {
LRUCache<std::string, std::string>* block_cache =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When to destroy this pointer?
It looks like there is a memory leak.

You can use unique_pointer instead.

new LRUCache<std::string, std::string>(1000);
block_cache_ =
std::unique_ptr<LRUCache<std::string, std::string>>(block_cache);
LOG(ERROR) << "initialized block cache" << std::endl;
}
global_stats_ = Stats::GetGlobalStats();
CreateDB(path);
}

Expand All @@ -74,15 +84,22 @@ ResLevelDB::~ResLevelDB() {
if (db_) {
db_.reset();
}
if (block_cache_) {
block_cache_->Flush();
}
}

int ResLevelDB::SetValue(const std::string& key, const std::string& value) {
if (block_cache_) {
block_cache_->Put(key, value);
}
batch_.Put(key, value);

if (batch_.ApproximateSize() >= write_batch_size_) {
leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_);
if (status.ok()) {
batch_.Clear();
GetMetrics();
return 0;
} else {
LOG(ERROR) << "flush buffer fail:" << status.ToString();
Expand All @@ -94,7 +111,17 @@ int ResLevelDB::SetValue(const std::string& key, const std::string& value) {

std::string ResLevelDB::GetValue(const std::string& key) {
std::string value = "";
std::string cached_result = "";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something wrong here?

if (block_cache_) {
std::string cached_result = block_cache_->Get(key);
}
if (cached_result != "") {
LOG(ERROR) << "Cache Hit for key: " << key << cached_result;
GetMetrics();
return cached_result;
}
leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value);
GetMetrics();
if (status.ok()) {
return value;
} else {
Expand Down Expand Up @@ -134,6 +161,19 @@ std::string ResLevelDB::GetRange(const std::string& min_key,
return values;
}

void ResLevelDB::GetMetrics() {
if (!block_cache_) {
return;
}
std::string stats;
std::string approximate_size;
db_->GetProperty("leveldb.stats", &stats);
db_->GetProperty("leveldb.approximate-memory-usage", &approximate_size);
LOG(ERROR) << "LevelDB Stats" << stats << " : " << approximate_size << "\n";
global_stats_->SetStorageEngineMetrics(block_cache_->GetCacheHitRatio(),
stats, approximate_size);
}

bool ResLevelDB::Flush() {
leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_);
if (status.ok()) {
Expand Down
8 changes: 8 additions & 0 deletions chain/storage/leveldb.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@

#include "chain/storage/proto/leveldb_config.pb.h"
#include "chain/storage/storage.h"
#include "common/lru/lru_cache.h"
#include "leveldb/db.h"
#include "leveldb/write_batch.h"
#include "platform/statistic/stats.h"

namespace resdb {
namespace storage {
Expand Down Expand Up @@ -65,6 +67,8 @@ class ResLevelDB : public Storage {
std::vector<std::pair<std::string, int>> GetTopHistory(
const std::string& key, int top_number) override;

void GetMetrics();

bool Flush() override;

private:
Expand All @@ -75,6 +79,10 @@ class ResLevelDB : public Storage {
::leveldb::WriteBatch batch_;
unsigned int write_buffer_size_ = 64 << 20;
unsigned int write_batch_size_ = 1;
std::unique_ptr<LRUCache<std::string, std::string>> block_cache_;

protected:
Stats* global_stats_ = nullptr;
};

} // namespace storage
Expand Down
2 changes: 2 additions & 0 deletions chain/storage/proto/leveldb_config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ message LevelDBInfo {
uint32 write_buffer_size_mb = 2;
uint32 write_batch_size = 3;
string path = 4;
optional bool enable_block_cache = 5;
optional uint32 block_cache_capacity = 6;
}
27 changes: 27 additions & 0 deletions common/lru/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#

package(default_visibility = ["//visibility:public"])

cc_library(
name = "lru_cache",
srcs = ["lru_cache.cpp"],
hdrs = ["lru_cache.h"],
linkopts = ["-pg","-g","-ggdb"], # Enable profiling during linking
copts = ["-pg"],
)
101 changes: 101 additions & 0 deletions common/lru/lru_cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "lru_cache.h"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some UTs.


#include <algorithm>

namespace resdb {

template <typename KeyType, typename ValueType>
LRUCache<KeyType, ValueType>::LRUCache(int capacity) {
m_ = capacity;
cache_hits_ = 0;
cache_misses_ = 0;
}

template <typename KeyType, typename ValueType>
LRUCache<KeyType, ValueType>::~LRUCache() {
um_.clear();
dq_.clear();
}

template <typename KeyType, typename ValueType>
ValueType LRUCache<KeyType, ValueType>::Get(KeyType key) {
if (!um_.count(key)) {
cache_misses_++;
return ValueType();
}

auto it = std::find(dq_.begin(), dq_.end(), key);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

performance issue?

dq_.erase(it);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dq_.erase(it);
if ( it != dq_.end()){
dq_.erase(it);
}

dq_.push_front(key);

cache_hits_++;
return um_.at(key);
}

template <typename KeyType, typename ValueType>
void LRUCache<KeyType, ValueType>::Put(KeyType key, ValueType value) {
int s = dq_.size();

if (!um_.count(key)) {
if (s == m_) {
um_.erase(dq_.back());
dq_.pop_back();
}
// Insert the new key and value in the map and add it as most recently
// used
um_[key] = value;
dq_.push_front(key);
} else {
// If the key is already in the cache, just update it and move it to the
// front
um_[key] = value;
auto it = std::find(dq_.begin(), dq_.end(), key);
dq_.erase(it);
dq_.push_front(key);
}
}

template <typename KeyType, typename ValueType>
void LRUCache<KeyType, ValueType>::SetCapacity(int new_capacity) {
if (new_capacity < m_) {
while (dq_.size() > new_capacity) {
um_.erase(dq_.back());
dq_.pop_back();
}
}
m_ = new_capacity;
}

template <typename KeyType, typename ValueType>
void LRUCache<KeyType, ValueType>::Flush() {
um_.clear();
dq_.clear();
cache_hits_ = 0;
cache_misses_ = 0;
}

template <typename KeyType, typename ValueType>
int LRUCache<KeyType, ValueType>::GetCacheHits() const {
return cache_hits_;
}

template <typename KeyType, typename ValueType>
int LRUCache<KeyType, ValueType>::GetCacheMisses() const {
return cache_misses_;
}

template <typename KeyType, typename ValueType>
double LRUCache<KeyType, ValueType>::GetCacheHitRatio() const {
int total_accesses = cache_hits_ + cache_misses_;
if (total_accesses == 0) {
return 0.0;
}
return static_cast<double>(cache_hits_) / total_accesses;
}

// Explicit instantiations of the template class for commonly used types
template class LRUCache<int, int>;
template class LRUCache<std::string, int>;
template class LRUCache<int, std::string>;
template class LRUCache<std::string, std::string>;
} // namespace resdb
46 changes: 46 additions & 0 deletions common/lru/lru_cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <deque>
#include <unordered_map>

using namespace std;

namespace resdb {

template <typename KeyType, typename ValueType>
class LRUCache {
public:
// Constructor to initialize the cache with a given capacity
LRUCache(int capacity);

// Destructor
~LRUCache();

// Get the value of the key if present in the cache
ValueType Get(KeyType key);

// Insert or update the key-value pair
void Put(KeyType key, ValueType value);

// Method to change the cache capacity
void SetCapacity(int new_capacity);

// Method to flush the cache (clear all entries)
void Flush();

// Method to get the cache hit count
int GetCacheHits() const;

// Method to get the cache miss count
int GetCacheMisses() const;

// Method to get the cache Hit Ratio
double GetCacheHitRatio() const;

private:
int m_; // Cache capacity
int cache_hits_; // Cache hits count
int cache_misses_; // Cache misses count

deque<KeyType> dq_; // To maintain most and least recently used items
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unordered_map<KeyType, ValueType> um_; // Key-value map
};
} // namespace resdb
Binary file added gmon.out
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this file won't be committed.

Binary file not shown.
3 changes: 3 additions & 0 deletions platform/statistic/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package(default_visibility = [
"//platform:__subpackages__",
"//service:__subpackages__",
"//chain/storage:__subpackages__",
])

cc_library(
Expand Down Expand Up @@ -53,4 +54,6 @@ cc_library(
cc_binary(
name = "set_random_data",
srcs = ["set_random_data.cpp"],
copts = ["-pg"],
linkopts = ["-pg"],
)
Loading