GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 92.8% 64 / 0 / 69
Functions: 100.0% 10 / 0 / 10
Branches: 46.6% 41 / 0 / 88

storage/external/hps/raw_rocksdb.cc
Line Branch Exec Source
1 #include "storage/external/hps/raw_rocksdb.h"
2
3 #include <cstring>
4 #include <stdexcept>
5 #include <vector>
6
7 #include "rocksdb/db.h"
8 #include "rocksdb/env.h"
9 #include "rocksdb/options.h"
10 #include "rocksdb/slice.h"
11 #include "rocksdb/write_batch.h"
12
13 namespace recstore::storage {
14 namespace {
15
16 16 std::string EncodeKey(long long key) {
17 static_assert(sizeof(long long) == sizeof(uint64_t));
18 16 uint64_t encoded = static_cast<uint64_t>(key);
19
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 std::string out(sizeof(encoded), '\0');
20 16 std::memcpy(out.data(), &encoded, sizeof(encoded));
21 32 return out;
22 }
23
24 14 void CheckStatus(const rocksdb::Status& status, const char* operation) {
25
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 if (!status.ok()) {
26 throw std::runtime_error(
27 std::string(operation) + " failed: " + status.ToString());
28 }
29 14 }
30
31 } // namespace
32
33 class RawRocksDBBackend::Impl {
34 public:
35 4 Impl(const std::string& path, size_t value_size, bool use_mem_env)
36 4 : value_size_(value_size) {
37
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (value_size_ == 0) {
38 throw std::invalid_argument("RawRocksDBBackend value_size must be > 0");
39 }
40
41
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 rocksdb::Options options;
42 4 options.create_if_missing = true;
43
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (use_mem_env) {
44
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 mem_env_.reset(rocksdb::NewMemEnv(rocksdb::Env::Default()));
45
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!mem_env_) {
46 throw std::runtime_error("RocksDB NewMemEnv returned null");
47 }
48 2 options.env = mem_env_.get();
49 }
50
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 options.IncreaseParallelism();
51
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 options.OptimizeLevelStyleCompaction();
52
53 4 rocksdb::DB* db = nullptr;
54
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 CheckStatus(rocksdb::DB::Open(options, path, &db), "RocksDB::Open");
55 4 db_.reset(db);
56 4 }
57
58 4 void Insert(size_t num_keys, const long long* keys, const char* values) {
59
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 rocksdb::WriteBatch batch;
60 4 std::vector<std::string> key_storage;
61
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 key_storage.reserve(num_keys);
62
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (size_t i = 0; i < num_keys; ++i) {
63
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 key_storage.push_back(EncodeKey(keys[i]));
64
1/2
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
8 batch.Put(rocksdb::Slice(key_storage.back()),
65 16 rocksdb::Slice(values + i * value_size_, value_size_));
66 }
67
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 CheckStatus(db_->Write(write_options_, &batch), "RocksDB::WriteBatch");
68 4 }
69
70 4 void Fetch(size_t num_keys,
71 const long long* keys,
72 char* values,
73 const MissCallback& on_miss) {
74 4 std::vector<std::string> key_storage;
75
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 key_storage.reserve(num_keys);
76 4 std::vector<rocksdb::Slice> key_slices;
77
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 key_slices.reserve(num_keys);
78
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (size_t i = 0; i < num_keys; ++i) {
79
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 key_storage.push_back(EncodeKey(keys[i]));
80
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 key_slices.emplace_back(key_storage.back());
81 }
82
83
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 std::vector<std::string> result_storage(num_keys);
84 const std::vector<rocksdb::Status> statuses =
85
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 db_->MultiGet(read_options_, key_slices, &result_storage);
86
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (size_t i = 0; i < num_keys; ++i) {
87
3/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 6 times.
8 if (statuses[i].IsNotFound()) {
88
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (on_miss) {
89
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 on_miss(i);
90 }
91 2 continue;
92 }
93
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 CheckStatus(statuses[i], "RocksDB::MultiGet");
94
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (result_storage[i].size() != value_size_) {
95 throw std::runtime_error("RocksDB value size mismatch");
96 }
97 12 std::memcpy(
98 6 values + i * value_size_, result_storage[i].data(), value_size_);
99 }
100 4 }
101
102 private:
103 struct DBDeleter {
104
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 void operator()(rocksdb::DB* db) const { delete db; }
105 };
106
107 size_t value_size_;
108 rocksdb::ReadOptions read_options_;
109 rocksdb::WriteOptions write_options_;
110 std::unique_ptr<rocksdb::Env> mem_env_;
111 std::unique_ptr<rocksdb::DB, DBDeleter> db_;
112 };
113
114 4 RawRocksDBBackend::RawRocksDBBackend(
115 4 const std::string& path, size_t value_size, bool use_mem_env)
116 4 : impl_(std::make_unique<Impl>(path, value_size, use_mem_env)) {}
117
118 4 RawRocksDBBackend::~RawRocksDBBackend() = default;
119
120 4 void RawRocksDBBackend::Insert(
121 size_t num_keys, const long long* keys, const char* values) {
122 4 impl_->Insert(num_keys, keys, values);
123 4 }
124
125 4 void RawRocksDBBackend::Fetch(size_t num_keys,
126 const long long* keys,
127 char* values,
128 const MissCallback& on_miss) {
129 4 impl_->Fetch(num_keys, keys, values, on_miss);
130 4 }
131
132 } // namespace recstore::storage
133