You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
6.2 KiB
C
199 lines
6.2 KiB
C
2 years ago
|
//
|
||
|
// Created by Ziyang Hu on 2022/4/13.
|
||
|
//
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <memory>
|
||
|
#include "rust/cxx.h"
|
||
|
|
||
|
#include "rocksdb/db.h"
|
||
|
#include "rocksdb/slice.h"
|
||
|
#include "rocksdb/options.h"
|
||
|
#include "rocksdb/utilities/transaction.h"
|
||
|
#include "rocksdb/utilities/transaction_db.h"
|
||
|
|
||
|
struct Status;
|
||
|
|
||
2 years ago
|
namespace RDB = ROCKSDB_NAMESPACE;
|
||
2 years ago
|
|
||
2 years ago
|
typedef RDB::Status::Code StatusCode;
|
||
|
typedef RDB::Status::SubCode StatusSubCode;
|
||
|
typedef RDB::Status::Severity StatusSeverity;
|
||
2 years ago
|
|
||
2 years ago
|
std::unique_ptr <RDB::DB> new_db();
|
||
2 years ago
|
|
||
|
struct ReadOptionsBridge {
|
||
|
mutable RDB::ReadOptions inner;
|
||
|
};
|
||
|
|
||
|
struct WriteOptionsBridge {
|
||
|
mutable RDB::WriteOptions inner;
|
||
|
|
||
|
public:
|
||
|
inline void set_disable_wal(bool v) const {
|
||
|
inner.disableWAL = v;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
typedef rust::Fn<std::int8_t(rust::Slice<const std::uint8_t>, rust::Slice<const std::uint8_t>)> RustComparatorFn;
|
||
|
|
||
2 years ago
|
class RustComparator : public RDB::Comparator {
|
||
2 years ago
|
public:
|
||
2 years ago
|
inline int Compare(const rocksdb::Slice &a, const rocksdb::Slice &b) const {
|
||
2 years ago
|
auto ra = rust::Slice(reinterpret_cast<const std::uint8_t *>(a.data()), a.size());
|
||
|
auto rb = rust::Slice(reinterpret_cast<const std::uint8_t *>(b.data()), b.size());
|
||
|
return int(rust_compare(ra, rb));
|
||
|
}
|
||
|
|
||
2 years ago
|
const char *Name() const {
|
||
2 years ago
|
return "RustComparator";
|
||
|
}
|
||
2 years ago
|
|
||
|
void FindShortestSeparator(std::string *, const rocksdb::Slice &) const {}
|
||
|
|
||
|
void FindShortSuccessor(std::string *) const {}
|
||
2 years ago
|
|
||
|
void set_fn(RustComparatorFn f) const {
|
||
|
rust_compare = f;
|
||
|
}
|
||
|
|
||
|
void set_name(rust::Str name_) const {
|
||
|
name = std::string(name_);
|
||
|
}
|
||
|
|
||
|
mutable std::string name;
|
||
|
mutable RustComparatorFn rust_compare;
|
||
|
};
|
||
|
|
||
|
struct OptionsBridge {
|
||
|
mutable RDB::Options inner;
|
||
|
mutable RustComparator cmp_obj;
|
||
2 years ago
|
|
||
|
public:
|
||
|
inline void prepare_for_bulk_load() const {
|
||
|
inner.PrepareForBulkLoad();
|
||
|
}
|
||
|
|
||
|
inline void increase_parallelism() const {
|
||
|
inner.IncreaseParallelism();
|
||
|
}
|
||
|
|
||
|
inline void optimize_level_style_compaction() const {
|
||
|
inner.OptimizeLevelStyleCompaction();
|
||
|
};
|
||
|
|
||
|
inline void set_create_if_missing(bool v) const {
|
||
|
inner.create_if_missing = v;
|
||
|
}
|
||
2 years ago
|
|
||
|
inline void set_comparator(rust::Str name, RustComparatorFn f) const {
|
||
|
cmp_obj = RustComparator();
|
||
|
cmp_obj.set_name(name);
|
||
|
cmp_obj.set_fn(f);
|
||
|
inner.comparator = &cmp_obj;
|
||
|
}
|
||
2 years ago
|
};
|
||
|
|
||
2 years ago
|
inline std::unique_ptr <ReadOptionsBridge> new_read_options() {
|
||
2 years ago
|
return std::unique_ptr<ReadOptionsBridge>(new ReadOptionsBridge);
|
||
|
}
|
||
|
|
||
2 years ago
|
inline std::unique_ptr <WriteOptionsBridge> new_write_options() {
|
||
2 years ago
|
return std::unique_ptr<WriteOptionsBridge>(new WriteOptionsBridge);
|
||
|
}
|
||
|
|
||
2 years ago
|
inline std::unique_ptr <OptionsBridge> new_options() {
|
||
2 years ago
|
return std::unique_ptr<OptionsBridge>(new OptionsBridge);
|
||
2 years ago
|
}
|
||
|
|
||
|
|
||
2 years ago
|
struct PinnableSliceBridge {
|
||
|
RDB::PinnableSlice inner;
|
||
2 years ago
|
|
||
|
inline rust::Slice<const std::uint8_t> as_bytes() const {
|
||
|
return rust::Slice(reinterpret_cast<const std::uint8_t *>(inner.data()), inner.size());
|
||
|
}
|
||
|
};
|
||
|
|
||
2 years ago
|
void write_status_impl(Status &status, StatusCode code, StatusSubCode subcode, StatusSeverity severity);
|
||
2 years ago
|
|
||
2 years ago
|
inline void write_status(RDB::Status &&rstatus, Status &status) {
|
||
|
if (rstatus.code() != StatusCode::kOk || rstatus.subcode() != StatusSubCode::kNoSpace ||
|
||
|
rstatus.severity() != StatusSeverity::kNoError) {
|
||
|
write_status_impl(status, rstatus.code(), rstatus.subcode(), rstatus.severity());
|
||
2 years ago
|
}
|
||
2 years ago
|
}
|
||
2 years ago
|
|
||
2 years ago
|
struct DBBridge {
|
||
2 years ago
|
mutable std::unique_ptr <RDB::DB> inner;
|
||
2 years ago
|
|
||
|
DBBridge(RDB::DB *inner_) : inner(inner_) {}
|
||
|
|
||
|
inline void put(
|
||
|
const WriteOptionsBridge &options,
|
||
|
rust::Slice<const uint8_t> key,
|
||
|
rust::Slice<const uint8_t> val,
|
||
|
Status &status
|
||
|
) const {
|
||
|
write_status(
|
||
|
inner->Put(options.inner,
|
||
|
RDB::Slice(reinterpret_cast<const char *>(key.data()), key.size()),
|
||
|
RDB::Slice(reinterpret_cast<const char *>(val.data()), val.size())),
|
||
|
status
|
||
|
);
|
||
|
}
|
||
2 years ago
|
|
||
2 years ago
|
inline std::unique_ptr <PinnableSliceBridge> get(
|
||
2 years ago
|
const ReadOptionsBridge &options,
|
||
|
rust::Slice<const uint8_t> key,
|
||
|
Status &status
|
||
|
) const {
|
||
|
auto pinnable_val = std::make_unique<PinnableSliceBridge>();
|
||
|
write_status(
|
||
|
inner->Get(options.inner,
|
||
|
inner->DefaultColumnFamily(),
|
||
|
RDB::Slice(reinterpret_cast<const char *>(key.data()), key.size()),
|
||
|
&pinnable_val->inner),
|
||
|
status
|
||
|
);
|
||
2 years ago
|
return pinnable_val;
|
||
|
}
|
||
|
};
|
||
|
|
||
2 years ago
|
inline std::unique_ptr <std::vector<std::string>> list_column_families(const OptionsBridge &options,
|
||
|
const rust::Slice<const uint8_t> path) {
|
||
|
auto column_families = std::make_unique < std::vector < std::string >> ();
|
||
2 years ago
|
RDB::DB::ListColumnFamilies(options.inner,
|
||
|
std::string(reinterpret_cast<const char *>(path.data()), path.size()),
|
||
2 years ago
|
&*column_families);
|
||
2 years ago
|
return column_families;
|
||
|
}
|
||
|
|
||
2 years ago
|
inline std::unique_ptr <DBBridge> open_db(const OptionsBridge &options, const rust::Slice<const uint8_t> path, Status &status) {
|
||
|
auto old_column_families = std::vector<std::string>();
|
||
|
RDB::DB::ListColumnFamilies(options.inner,
|
||
|
std::string(reinterpret_cast<const char *>(path.data()), path.size()),
|
||
|
&old_column_families);
|
||
|
if (old_column_families.empty()) {
|
||
|
old_column_families.push_back(RDB::kDefaultColumnFamilyName);
|
||
|
}
|
||
|
|
||
|
std::vector <RDB::ColumnFamilyDescriptor> column_families;
|
||
|
|
||
|
for (auto el: old_column_families) {
|
||
|
column_families.push_back(RDB::ColumnFamilyDescriptor(
|
||
|
el, options.inner));
|
||
|
}
|
||
|
|
||
|
std::vector < RDB::ColumnFamilyHandle * > handles;
|
||
|
|
||
2 years ago
|
RDB::DB *db_ptr;
|
||
|
RDB::Status s = RDB::DB::Open(options.inner,
|
||
|
std::string(reinterpret_cast<const char *>(path.data()), path.size()),
|
||
2 years ago
|
column_families,
|
||
|
&handles,
|
||
2 years ago
|
&db_ptr);
|
||
2 years ago
|
write_status(std::move(s), status);
|
||
2 years ago
|
return std::unique_ptr<DBBridge>(new DBBridge(db_ptr));
|
||
2 years ago
|
}
|