Skip to content

Commit f58b942

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 f58b942

24 files changed

Lines changed: 918 additions & 225 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: 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/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+
class Db final {
25+
public:
26+
Db(const std::string& db_path, int max_background_jobs, engine::TaskProcessor& task_processor);
27+
28+
void Put(std::string_view key, std::string_view value);
29+
void Write(WriteBatch& write_batch);
30+
void Delete(std::string_view key);
31+
32+
[[nodiscard]] std::optional<std::string> Get(std::string_view key) const;
33+
[[nodiscard]] Snapshot GetSnapshot() const;
34+
35+
template <IteratorDirection Direction = IteratorDirection::kForward>
36+
[[nodiscard]] Iterator<Direction> NewIterator() const;
37+
38+
private:
39+
std::shared_ptr<detail::DbImpl> db_impl_;
40+
};
41+
42+
} // namespace storages::rocks
43+
44+
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: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
class DbImpl final {
27+
public:
28+
DbImpl(const rocksdb::Options& options, const std::string& db, engine::TaskProcessor& task_processor);
29+
~DbImpl();
30+
31+
void Put(const rocksdb::WriteOptions& options, std::string_view key, std::string_view value);
32+
void Write(const rocksdb::WriteOptions& options, rocksdb::WriteBatch& write_batch);
33+
void Delete(const rocksdb::WriteOptions& options, std::string_view key);
34+
35+
[[nodiscard]] const rocksdb::Snapshot* GetSnapshot() const;
36+
[[nodiscard]] std::optional<std::string> Get(const rocksdb::ReadOptions& options, std::string_view key) const;
37+
[[nodiscard]] std::unique_ptr<rocksdb::Iterator> NewIterator(const rocksdb::ReadOptions& options) const;
38+
39+
void ReleaseSnapshot(const rocksdb::Snapshot* snapshot) const;
40+
41+
[[nodiscard]] engine::TaskProcessor& GetTaskProcessor();
42+
43+
private:
44+
std::unique_ptr<rocksdb::DB> db_;
45+
engine::TaskProcessor& task_processor_;
46+
};
47+
48+
} // namespace storages::rocks::detail
49+
50+
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, const std::shared_ptr<const rocksdb::Snapshot>& snapshot,
25+
std::unique_ptr<rocksdb::Iterator> iterator) noexcept;
26+
~IteratorImpl();
27+
28+
IteratorImpl(IteratorImpl&&) 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+
// It only contains a pointer if instance relates to a Snapshot (may not).
45+
std::shared_ptr<const rocksdb::Snapshot> snapshot_;
46+
std::unique_ptr<rocksdb::Iterator> iterator_;
47+
};
48+
49+
} // namespace storages::rocks::detail
50+
51+
USERVER_NAMESPACE_END
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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(const std::shared_ptr<DbImpl>& db, const rocksdb::Snapshot* snapshot);
25+
26+
[[nodiscard]] std::optional<std::string> Get(std::string_view key) const;
27+
[[nodiscard]] IteratorImpl NewIterator() const;
28+
29+
private:
30+
std::shared_ptr<detail::DbImpl> db_impl_;
31+
std::shared_ptr<const rocksdb::Snapshot> snapshot_;
32+
};
33+
34+
} // namespace storages::rocks::detail
35+
36+
USERVER_NAMESPACE_END

rocks/include/userver/storages/rocks/exception.hpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,23 @@
66
#include <stdexcept>
77
#include <string_view>
88

9+
namespace rocksdb {
10+
class Status;
11+
} // namespace rocksdb
12+
913
USERVER_NAMESPACE_BEGIN
1014

1115
namespace storages::rocks {
1216

13-
/// Generic rocks-related exception
14-
class Exception : public std::runtime_error {
15-
public:
16-
using std::runtime_error::runtime_error;
17-
};
17+
namespace detail {
1818

19-
/// Request execution failed
20-
class RequestFailedException : public Exception {
21-
public:
22-
RequestFailedException(std::string_view request_description, std::string_view status);
19+
void CheckStatus(const rocksdb::Status& status, std::string_view description);
20+
21+
} // namespace detail
2322

23+
class StatusNokException : public std::runtime_error {
24+
public:
25+
StatusNokException(std::string_view description, std::string_view status);
2426
std::string_view GetStatusString() const;
2527

2628
private:

0 commit comments

Comments
 (0)