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