Skip to content

Commit 1e94e27

Browse files
committed
feat rocks: rework RocksDB bindings
- Replace storages::rocks::Client with storages::rocks::Db and a shared detail::DbImpl backend - Use std::optional for Get methods instead of empty strings when NotFound - Add RAII wrappers for RocksDB snapshots and iterators (storages::rocks::Snapshot, storages::rocks::Iterator) - Add storages::rocks::WriteBatch for atomic multi-key updates - Ensure graceful DB shutdown: sync WAL and wait for compaction/close on the dedicated Rocks task processor - Introduce components::Rocks component exposing GetDb() - Make Rocks DB path and max_background_jobs configurable via component options (db_path, max_background_jobs) - 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 1e94e27

24 files changed

Lines changed: 930 additions & 224 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: 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: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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/iterator.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+
/**
25+
* @brief Client for working with RocksDB storage.
26+
*/
27+
class Db final {
28+
public:
29+
/**
30+
* @brief Constructor of the Db class.
31+
*/
32+
Db(const std::string& db_path, int max_background_jobs, engine::TaskProcessor& task_processor);
33+
34+
/**
35+
* @brief Puts a record into the database.
36+
*/
37+
void Put(std::string_view key, std::string_view value);
38+
39+
/**
40+
* @brief Apply the specified updates to the database.
41+
*/
42+
void Write(WriteBatch& write_batch);
43+
44+
/**
45+
* @brief Deletes a record from the database by key.
46+
*/
47+
void Delete(std::string_view key);
48+
49+
/**
50+
* @brief Retrieves the value of a record from the database by key.
51+
*/
52+
[[nodiscard]] std::optional<std::string> Get(std::string_view key) const;
53+
54+
/**
55+
* @brief Return a newly created Snapshot instance.
56+
*/
57+
[[nodiscard]] Snapshot GetSnapshot() const;
58+
59+
/**
60+
* @brief Return a newly created Iterator instance.
61+
*/
62+
template <IteratorDirection Direction = IteratorDirection::kForward>
63+
[[nodiscard]] Iterator<Direction> NewIterator() const;
64+
65+
private:
66+
std::shared_ptr<detail::DbImpl> db_impl_;
67+
};
68+
69+
} // namespace storages::rocks
70+
71+
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: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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 <userver/engine/task/task_processor_fwd.hpp>
11+
12+
namespace rocksdb {
13+
class Options;
14+
class WriteOptions;
15+
class WriteBatch;
16+
class ReadOptions;
17+
class Iterator;
18+
class Snapshot;
19+
class DB;
20+
} // namespace rocksdb
21+
22+
USERVER_NAMESPACE_BEGIN
23+
24+
namespace storages::rocks::detail {
25+
26+
/**
27+
* @brief Database implementation for working with RocksDB storage.
28+
*/
29+
class DbImpl final {
30+
public:
31+
DbImpl(const rocksdb::Options& options, const std::string& db, engine::TaskProcessor& task_processor);
32+
~DbImpl();
33+
34+
void Put(const rocksdb::WriteOptions& options, std::string_view key, std::string_view value);
35+
void Write(const rocksdb::WriteOptions& options, rocksdb::WriteBatch& write_batch);
36+
void Delete(const rocksdb::WriteOptions& options, std::string_view key);
37+
38+
[[nodiscard]] const rocksdb::Snapshot* GetSnapshot() const;
39+
[[nodiscard]] std::optional<std::string> Get(const rocksdb::ReadOptions& options, std::string_view key) const;
40+
[[nodiscard]] std::unique_ptr<rocksdb::Iterator> NewIterator(const rocksdb::ReadOptions& options) const;
41+
42+
void ReleaseSnapshot(const rocksdb::Snapshot* snapshot) const;
43+
44+
[[nodiscard]] engine::TaskProcessor& GetTaskProcessor();
45+
46+
private:
47+
std::unique_ptr<rocksdb::DB> db_;
48+
engine::TaskProcessor& task_processor_;
49+
};
50+
51+
} // namespace storages::rocks::detail
52+
53+
USERVER_NAMESPACE_END
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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 final {
22+
public:
23+
IteratorImpl(const std::shared_ptr<DbImpl>& db, std::unique_ptr<rocksdb::Iterator> iterator) noexcept;
24+
IteratorImpl(const std::shared_ptr<DbImpl>& db, std::unique_ptr<rocksdb::Iterator> iterator,
25+
const std::shared_ptr<const rocksdb::Snapshot>& snapshot) noexcept;
26+
~IteratorImpl();
27+
28+
IteratorImpl(IteratorImpl&& other) noexcept;
29+
IteratorImpl& operator=(IteratorImpl&&) noexcept;
30+
31+
[[nodiscard]] bool Valid() const noexcept;
32+
void SeekToFirst();
33+
void SeekToLast();
34+
void Seek(std::string_view slice);
35+
void SeekForPrev(std::string_view slice);
36+
void Next();
37+
void Prev();
38+
39+
[[nodiscard]] std::string Key() const;
40+
[[nodiscard]] std::string Value() const;
41+
42+
private:
43+
std::shared_ptr<DbImpl> db_impl_;
44+
std::unique_ptr<rocksdb::Iterator> iterator_;
45+
// It only contains a pointer if instance relates to a Snapshot (may not).
46+
std::shared_ptr<const rocksdb::Snapshot> snapshot_;
47+
};
48+
49+
} // namespace storages::rocks::detail
50+
51+
USERVER_NAMESPACE_END
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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/detail/iterator_impl.hpp>
11+
12+
namespace rocksdb {
13+
class Snapshot;
14+
} // namespace rocksdb
15+
16+
USERVER_NAMESPACE_BEGIN
17+
18+
namespace storages::rocks::detail {
19+
20+
class DbImpl;
21+
22+
class SnapshotImpl final {
23+
public:
24+
SnapshotImpl() noexcept;
25+
SnapshotImpl(const std::shared_ptr<DbImpl>& db, const rocksdb::Snapshot* snapshot);
26+
27+
[[nodiscard]] std::optional<std::string> Get(std::string_view key) const;
28+
[[nodiscard]] IteratorImpl NewIterator() const;
29+
30+
private:
31+
std::shared_ptr<detail::DbImpl> db_impl_;
32+
std::shared_ptr<const rocksdb::Snapshot> snapshot_;
33+
};
34+
35+
} // namespace storages::rocks::detail
36+
37+
USERVER_NAMESPACE_END

0 commit comments

Comments
 (0)