添加自定义比较器以支持数字排序,优化问题ID获取逻辑
This commit is contained in:
parent
dea868fc2a
commit
394bcd83ba
@ -2,17 +2,43 @@
|
|||||||
|
|
||||||
#include <print>
|
#include <print>
|
||||||
|
|
||||||
|
#include <leveldb/comparator.h>
|
||||||
#include <leveldb/db.h>
|
#include <leveldb/db.h>
|
||||||
#include <leveldb/write_batch.h>
|
#include <leveldb/write_batch.h>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <string>
|
|
||||||
|
class NumericComparator : public leveldb::Comparator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const override
|
||||||
|
{
|
||||||
|
auto x = std::stoi(a.ToString()), y = std::stoi(b.ToString());
|
||||||
|
|
||||||
|
if (x < y) {
|
||||||
|
return -1;
|
||||||
|
} else if (x > y) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Name() const override
|
||||||
|
{
|
||||||
|
return "NumericComparator";
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindShortestSeparator(std::string* start, const leveldb::Slice& limit) const override {}
|
||||||
|
void FindShortSuccessor(std::string* key) const override {}
|
||||||
|
};
|
||||||
|
|
||||||
using leveldb_ptr = leveldb::DB*;
|
using leveldb_ptr = leveldb::DB*;
|
||||||
|
|
||||||
auto problems_db = leveldb_ptr{nullptr};
|
auto problems_db = leveldb_ptr{nullptr};
|
||||||
auto max_problem_id = 0;
|
auto max_problem_id = 0;
|
||||||
|
|
||||||
|
auto comparator = NumericComparator{};
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -20,6 +46,8 @@ extern "C"
|
|||||||
{
|
{
|
||||||
auto opts = leveldb::Options{};
|
auto opts = leveldb::Options{};
|
||||||
|
|
||||||
|
opts.comparator = &comparator;
|
||||||
|
|
||||||
opts.create_if_missing = true;
|
opts.create_if_missing = true;
|
||||||
|
|
||||||
auto status = leveldb::DB::Open(opts, "db/problems", &problems_db);
|
auto status = leveldb::DB::Open(opts, "db/problems", &problems_db);
|
||||||
@ -29,22 +57,20 @@ extern "C"
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto value = std::string{};
|
auto it = problems_db->NewIterator(leveldb::ReadOptions());
|
||||||
status = problems_db->Get(leveldb::ReadOptions{}, "@", &value);
|
for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
||||||
if (status.ok()) {
|
auto id = std::stoi(it->key().ToString());
|
||||||
auto json = nlohmann::json::parse(value);
|
if (id > max_problem_id) max_problem_id = id;
|
||||||
json["max_problem_id"].get_to(max_problem_id);
|
}
|
||||||
} else if (status.IsNotFound()) {
|
|
||||||
auto json = nlohmann::json{
|
if (!it->status().ok()) {
|
||||||
{"max_problem_id", 0}
|
std::println(stderr, "Failed to get max problem id: {}", it->status().ToString());
|
||||||
};
|
delete it;
|
||||||
status = problems_db->Put(leveldb::WriteOptions{}, "@", json.dump());
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
std::println(stderr, "Failed to get max problem id: {}", status.ToString());
|
|
||||||
delete problems_db;
|
delete problems_db;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete it;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,10 +84,6 @@ extern "C"
|
|||||||
auto batch = leveldb::WriteBatch{};
|
auto batch = leveldb::WriteBatch{};
|
||||||
++max_problem_id;
|
++max_problem_id;
|
||||||
auto json = nlohmann::json{
|
auto json = nlohmann::json{
|
||||||
{"max_problem_id", max_problem_id}
|
|
||||||
};
|
|
||||||
batch.Put("@", json.dump());
|
|
||||||
json = nlohmann::json{
|
|
||||||
{"content", problem },
|
{"content", problem },
|
||||||
{"answer", answer },
|
{"answer", answer },
|
||||||
{"error", check_error}
|
{"error", check_error}
|
||||||
@ -178,7 +200,6 @@ extern "C"
|
|||||||
|
|
||||||
auto it = problems_db->NewIterator(leveldb::ReadOptions());
|
auto it = problems_db->NewIterator(leveldb::ReadOptions());
|
||||||
for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
||||||
if (!it->key().compare("@")) continue;
|
|
||||||
problems.emplace_back(std::stoi(it->key().ToString()));
|
problems.emplace_back(std::stoi(it->key().ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user