LiteLoaderBDS-1.16.40/LiteLoader/Kernel/KVDBAPI.cpp
2022-09-21 19:47:03 +08:00

128 lines
3.8 KiB
C++

#include <Global.h>
#include <KVDBAPI.h>
#include <LoggerAPI.h>
#include <Utils/FileHelper.h>
#include <I18nAPI.h>
Logger levelDBLogger("LevelDB");
std::unique_ptr<KVDB> KVDB::create(const std::string& path, bool read_cache, int cache_sz, int Bfilter_bit) {
CreateDirs(path);
auto db = std::make_unique<KVDB>();
db->_init(path.c_str(), true, read_cache, cache_sz, Bfilter_bit);
return db;
}
std::unique_ptr<KVDB> KVDB::open(const std::string& path, bool create, bool read_cache, int cache_sz, int Bfilter_bit) {
CreateDirs(path);
auto db = std::make_unique<KVDB>();
db->_init(path.c_str(), create, read_cache, cache_sz, Bfilter_bit);
return db;
}
void KVDB::_init(const char* path, bool create, bool read_cache, int cache_sz, int Bfilter_bit) {
rdopt = leveldb::ReadOptions();
wropt = leveldb::WriteOptions();
options = leveldb::Options();
rdopt.fill_cache = read_cache;
rdopt.verify_checksums = false;
wropt.sync = false;
if (cache_sz) {
options.block_cache = leveldb::NewLRUCache(cache_sz);
}
options.reuse_logs = true; // WARN:EXPERIMENTAL
if (Bfilter_bit)
options.filter_policy = leveldb::NewBloomFilterPolicy(Bfilter_bit);
options.create_if_missing = create;
dbpath = path;
status = leveldb::DB::Open(options, path, &db);
if (!status.ok()) {
levelDBLogger.error("Fail to load KVDB <{}>", path);
auto output = error(status);
output.erase(std::remove(output.begin(), output.end(), '\n'), output.end());
levelDBLogger.error("{}", TextEncoding::toUTF8(output));
}
}
KVDB::~KVDB() {
if (options.filter_policy)
delete options.filter_policy;
delete db;
}
bool KVDB::get(std::string_view key, std::string& val) {
auto s = db->Get(rdopt, leveldb::Slice(key.data(), key.size()), &val);
if (!s.ok()) {
if (s.IsNotFound())
return false;
levelDBLogger.error("get %s %s\n", dbpath.c_str(), s.ToString().c_str());
}
return true;
}
std::optional<std::string> KVDB::get(std::string_view key) {
std::string result;
auto s = db->Get(rdopt, leveldb::Slice(key.data(), key.size()), &result);
if (!s.ok()) {
return std::nullopt;
}
return result;
}
bool KVDB::set(std::string_view key, std::string_view val) {
auto s = db->Put(wropt, leveldb::Slice(key.data(), key.size()),
leveldb::Slice(val.data(), val.size()));
if (!s.ok()) {
levelDBLogger.error("put %s %s\n", dbpath.c_str(), s.ToString().c_str());
}
return true;
}
bool KVDB::del(std::string_view key) {
auto s = db->Delete(wropt, leveldb::Slice(key.data(), key.size()));
if (!s.ok()) {
levelDBLogger.error("del %s %s\n", dbpath.c_str(), s.ToString().c_str());
}
return true;
}
void KVDB::iter(std::function<bool(std::string_view key)> const& fn) {
leveldb::Iterator* it = db->NewIterator(rdopt);
for (it->SeekToFirst(); it->Valid(); it->Next()) {
auto k = it->key();
if (!fn({k.data(), k.size()}))
break;
}
delete it;
}
void KVDB::iter(std::function<bool(std::string_view key, std::string_view val)> const& fn) {
leveldb::Iterator* it = db->NewIterator(rdopt);
for (it->SeekToFirst(); it->Valid(); it->Next()) {
auto k = it->key();
auto v = it->value();
if (!fn({k.data(), k.size()}, {v.data(), v.size()}))
break;
}
delete it;
}
std::vector<std::string> KVDB::getAllKeys() {
std::vector<std::string> keyList;
iter([&keyList](const std::string_view& key) {
keyList.push_back(std::string(key));
return true;
});
return keyList;
}
bool KVDB::isValid() {
return status.ok();
}
KVDB::operator bool() {
return isValid();
}
LIAPI std::string KVDB::error(leveldb::Status status) {
return status.ToString();
}