mirror of
https://github.com/quizhizhe/LiteLoaderBDS-1.16.40.git
synced 2025-06-06 12:03:39 +00:00
128 lines
3.8 KiB
C++
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();
|
|
} |