添加自定义比较器以支持数字排序,优化问题ID获取逻辑

This commit is contained in:
keqingmoe 2024-12-31 01:00:47 +08:00
parent dea868fc2a
commit 394bcd83ba

View File

@ -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()));
} }