Skip to content

Commit 5dbb13b

Browse files
committed
feat rocks: rework RocksDB bindings
- Use std::optional for Get methods instead of empty strings when NotFound - Add RAII wrappers for RocksDB snapshots, iterators and write batches (rocks::Snapshot, rocks::Iterator, rocks::WriteBatch) - Ensure graceful DB shutdown: sync WAL and wait for compaction/close on the dedicated Rocks task processor - Link RocksDB privately from the rocks module (LINK_LIBRARIES_PRIVATE) BREAKING CHANGES: - storages::rocks::Client and storages::rocks::Component are removed - Component is now components::Rocks with GetDb() - Exception and RequestFailedException are removed in favor of StatusNokException - Config keys changed: db-path/task-processor -> db_path/max_background_jobs
1 parent af94aa9 commit 5dbb13b

24 files changed

Lines changed: 1166 additions & 223 deletions

rocks/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ include(SetupRocksDB)
55
userver_module(
66
rocks
77
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
8-
LINK_LIBRARIES RocksDB::rocksdb
8+
LINK_LIBRARIES_PRIVATE RocksDB::rocksdb
99
UTEST_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*_test.cpp"
1010
DEPENDS core
1111
)

rocks/include/userver/storages/rocks/client.hpp

Lines changed: 0 additions & 72 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
namespace rocksdb {
4+
class ColumnFamilyHandle;
5+
} // namespace rocksdb
6+
7+
USERVER_NAMESPACE_BEGIN
8+
9+
namespace storages::rocks {
10+
11+
using ColumnFamilyHandle = rocksdb::ColumnFamilyHandle*;
12+
13+
} // namespace storages::rocks
14+
15+
USERVER_NAMESPACE_END
Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,40 @@
11
#pragma once
22

33
/// @file userver/storages/rocks/component.hpp
4-
/// @brief @copybrief rocks::Rocks
4+
/// @brief @copybrief components::Rocks
55

6+
#include <string_view>
7+
#include <userver/storages/rocks/db_fwd.hpp>
68
#include <userver/components/component_base.hpp>
79
#include <userver/components/component_config.hpp>
810
#include <userver/components/component_context.hpp>
9-
#include <userver/engine/task/task_processor_fwd.hpp>
10-
#include <userver/storages/rocks/client_fwd.hpp>
1111

1212
USERVER_NAMESPACE_BEGIN
1313

14-
namespace storages::rocks {
14+
namespace components {
1515

16-
// clang-format off
17-
18-
/// @ingroup userver_components
19-
///
20-
/// @brief RocksDB client component.
21-
/// ## Static options:
22-
/// Name | Description | Default value
23-
/// ---------------------------------- | ------------------------------------------------ | ---------------
24-
/// task-processor | name of the task processor to run the blocking file operations | -
25-
/// db-path | path to database file | -
26-
27-
// clang-format on
28-
29-
class Component : public components::ComponentBase {
16+
/**
17+
* @brief Component for configuring and managing RocksDB.
18+
*/
19+
class Rocks final : public components::ComponentBase {
3020
public:
31-
Component(const components::ComponentConfig&, const components::ComponentContext&);
32-
33-
~Component() = default;
21+
static constexpr std::string_view kName = "rocks";
22+
static yaml_config::Schema GetStaticConfigSchema();
3423

35-
storages::rocks::ClientPtr MakeClient();
24+
/**
25+
* @brief Constructor of the Rocks class.
26+
*/
27+
Rocks(const components::ComponentConfig&, const components::ComponentContext&);
3628

37-
static yaml_config::Schema GetStaticConfigSchema();
29+
/**
30+
* @brief Return a pointer to the database instance.
31+
*/
32+
[[nodiscard]] const storages::rocks::DbPtr& GetDb() const;
3833

3934
private:
40-
storages::rocks::ClientPtr client_ptr_;
35+
storages::rocks::DbPtr db_ptr_;
4136
};
4237

43-
} // namespace storages::rocks
38+
} // namespace components
4439

4540
USERVER_NAMESPACE_END
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#pragma once
2+
3+
/// @file userver/storages/rocks/db.hpp
4+
/// @brief @copybrief storages::rocks::Db
5+
6+
#include <memory>
7+
#include <string>
8+
#include <optional>
9+
#include <string_view>
10+
#include <userver/storages/rocks/snapshot.hpp>
11+
#include <userver/storages/rocks/column_family.hpp>
12+
#include <userver/engine/task/task_processor_fwd.hpp>
13+
14+
USERVER_NAMESPACE_BEGIN
15+
16+
namespace storages::rocks::detail {
17+
class DbImpl;
18+
} // namespace storages::rocks::detail
19+
20+
namespace storages::rocks {
21+
22+
class WriteBatch;
23+
24+
struct DbOptions final {
25+
std::optional<std::string_view> compression;
26+
std::optional<int> compression_level;
27+
std::optional<std::string_view> bottommost_compression;
28+
std::optional<int> bottommost_compression_level;
29+
std::optional<bool> use_direct_reads;
30+
std::optional<bool> use_direct_io_for_flush_and_compaction;
31+
};
32+
33+
class Db final {
34+
public:
35+
Db(const std::string& db_path, int max_background_jobs, const std::vector<std::string>& column_families,
36+
const DbOptions& db_options, engine::TaskProcessor& task_processor);
37+
38+
[[nodiscard]] ColumnFamilyHandle GetColumnFamily(const std::string& name) const;
39+
40+
void Put(std::string_view key, std::string_view value);
41+
void Put(ColumnFamilyHandle column_family, std::string_view key, std::string_view value);
42+
43+
void Delete(std::string_view key);
44+
void Delete(ColumnFamilyHandle column_family, std::string_view key);
45+
46+
void Write(WriteBatch& write_batch);
47+
48+
[[nodiscard]] std::optional<std::string> Get(std::string_view key) const;
49+
[[nodiscard]] std::optional<std::string> Get(ColumnFamilyHandle column_family, std::string_view key) const;
50+
51+
[[nodiscard]] Snapshot GetSnapshot() const;
52+
53+
private:
54+
std::shared_ptr<detail::DbImpl> db_impl_;
55+
};
56+
57+
} // namespace storages::rocks
58+
59+
USERVER_NAMESPACE_END

rocks/include/userver/storages/rocks/client_fwd.hpp renamed to rocks/include/userver/storages/rocks/db_fwd.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
USERVER_NAMESPACE_BEGIN
66

77
namespace storages::rocks {
8-
9-
class Client;
10-
using ClientPtr = std::shared_ptr<Client>;
11-
8+
class Db;
9+
using DbPtr = std::shared_ptr<Db>;
1210
} // namespace storages::rocks
1311

1412
USERVER_NAMESPACE_END
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#pragma once
2+
3+
/// @file userver/storages/rocks/detail/db_impl.hpp
4+
/// @brief @copybrief storages::rocks::detail::DbImpl
5+
6+
#include <memory>
7+
#include <string>
8+
#include <optional>
9+
#include <string_view>
10+
#include <unordered_map>
11+
#include <userver/storages/rocks/column_family.hpp>
12+
#include <userver/engine/task/task_processor_fwd.hpp>
13+
14+
namespace rocksdb {
15+
class Options;
16+
class WriteOptions;
17+
class WriteBatch;
18+
class ReadOptions;
19+
class Iterator;
20+
class Snapshot;
21+
class DB;
22+
class ColumnFamilyHandle;
23+
} // namespace rocksdb
24+
25+
USERVER_NAMESPACE_BEGIN
26+
27+
namespace storages::rocks::detail {
28+
29+
class DbImpl final {
30+
public:
31+
DbImpl(const rocksdb::Options& options, const std::string& db, const std::vector<std::string>& column_families,
32+
engine::TaskProcessor& task_processor);
33+
~DbImpl();
34+
35+
[[nodiscard]] rocksdb::ColumnFamilyHandle* GetColumnFamily(const std::string& name) const;
36+
37+
void Put(const rocksdb::WriteOptions& options, std::string_view key, std::string_view value);
38+
void Put(const rocksdb::WriteOptions& options, rocksdb::ColumnFamilyHandle* column_family, std::string_view key,
39+
std::string_view value);
40+
41+
void Delete(const rocksdb::WriteOptions& options, std::string_view key);
42+
void Delete(const rocksdb::WriteOptions& options, rocksdb::ColumnFamilyHandle* column_family, std::string_view key);
43+
44+
void Write(const rocksdb::WriteOptions& options, rocksdb::WriteBatch& write_batch);
45+
46+
[[nodiscard]] std::optional<std::string> Get(const rocksdb::ReadOptions& options, std::string_view key) const;
47+
[[nodiscard]] std::optional<std::string> Get(const rocksdb::ReadOptions& options,
48+
rocksdb::ColumnFamilyHandle* column_family, std::string_view key) const;
49+
50+
[[nodiscard]] std::unique_ptr<rocksdb::Iterator> NewIterator(const rocksdb::ReadOptions& options) const;
51+
[[nodiscard]] std::unique_ptr<rocksdb::Iterator> NewIterator(const rocksdb::ReadOptions& options,
52+
rocksdb::ColumnFamilyHandle* column_family) const;
53+
54+
[[nodiscard]] const rocksdb::Snapshot* GetSnapshot() const;
55+
void ReleaseSnapshot(const rocksdb::Snapshot* snapshot) const;
56+
57+
[[nodiscard]] engine::TaskProcessor& GetTaskProcessor();
58+
59+
private:
60+
std::unique_ptr<rocksdb::DB> db_;
61+
engine::TaskProcessor& task_processor_;
62+
std::unordered_map<std::string, rocksdb::ColumnFamilyHandle*> column_family_handles_;
63+
};
64+
65+
} // namespace storages::rocks::detail
66+
67+
USERVER_NAMESPACE_END
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
/// @file userver/storages/rocks/detail/iterator_impl.hpp
4+
/// @brief @copybrief storages::rocks::detail::IteratorImpl
5+
6+
#include <memory>
7+
#include <string>
8+
#include <string_view>
9+
10+
namespace rocksdb {
11+
class Iterator;
12+
class Snapshot;
13+
} // namespace rocksdb
14+
15+
USERVER_NAMESPACE_BEGIN
16+
17+
namespace storages::rocks::detail {
18+
19+
class DbImpl;
20+
21+
class IteratorImpl {
22+
public:
23+
IteratorImpl(const std::shared_ptr<DbImpl>& db, const std::shared_ptr<const rocksdb::Snapshot>& snapshot,
24+
std::unique_ptr<rocksdb::Iterator> iterator) noexcept;
25+
virtual ~IteratorImpl();
26+
27+
IteratorImpl(IteratorImpl&&) noexcept;
28+
IteratorImpl& operator=(IteratorImpl&&) noexcept;
29+
30+
[[nodiscard]] bool Valid() const noexcept;
31+
void SeekToFirst();
32+
void SeekToLast();
33+
void Seek(std::string_view slice);
34+
void SeekForPrev(std::string_view slice);
35+
void Next();
36+
void Prev();
37+
38+
[[nodiscard]] std::string Key() const;
39+
[[nodiscard]] std::string Value() const;
40+
41+
private:
42+
std::shared_ptr<DbImpl> db_impl_;
43+
std::shared_ptr<const rocksdb::Snapshot> snapshot_;
44+
std::unique_ptr<rocksdb::Iterator> iterator_;
45+
};
46+
47+
} // namespace storages::rocks::detail
48+
49+
USERVER_NAMESPACE_END
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
/// @file userver/storages/rocks/detail/snapshot_impl.hpp
4+
/// @brief @copybrief storages::rocks::detail::SnapshotImpl
5+
6+
#include <memory>
7+
#include <string>
8+
#include <optional>
9+
#include <string_view>
10+
#include <userver/storages/rocks/column_family.hpp>
11+
#include <userver/storages/rocks/detail/iterator_impl.hpp>
12+
13+
namespace rocksdb {
14+
class Snapshot;
15+
class ReadOptions;
16+
class ColumnFamilyHandle;
17+
} // namespace rocksdb
18+
19+
USERVER_NAMESPACE_BEGIN
20+
21+
namespace storages::rocks::detail {
22+
23+
class DbImpl;
24+
25+
class SnapshotImpl final {
26+
public:
27+
SnapshotImpl(const std::shared_ptr<DbImpl>& db, const rocksdb::Snapshot* snapshot);
28+
29+
[[nodiscard]] std::optional<std::string> Get(rocksdb::ReadOptions& options, std::string_view key) const;
30+
[[nodiscard]] std::optional<std::string> Get(rocksdb::ReadOptions& options,
31+
rocksdb::ColumnFamilyHandle* column_family, std::string_view key) const;
32+
33+
[[nodiscard]] IteratorImpl NewIterator(rocksdb::ReadOptions& options) const;
34+
[[nodiscard]] IteratorImpl NewIterator(rocksdb::ReadOptions& options,
35+
rocksdb::ColumnFamilyHandle* column_family) const;
36+
37+
private:
38+
std::shared_ptr<detail::DbImpl> db_impl_;
39+
std::shared_ptr<const rocksdb::Snapshot> snapshot_;
40+
};
41+
42+
} // namespace storages::rocks::detail
43+
44+
USERVER_NAMESPACE_END

0 commit comments

Comments
 (0)