From 394bcd83ba4e77814621fe0cf0c820e006164f09 Mon Sep 17 00:00:00 2001 From: keqingmoe Date: Tue, 31 Dec 2024 01:00:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=AF=94=E8=BE=83=E5=99=A8=E4=BB=A5=E6=94=AF=E6=8C=81=E6=95=B0?= =?UTF-8?q?=E5=AD=97=E6=8E=92=E5=BA=8F=EF=BC=8C=E4=BC=98=E5=8C=96=E9=97=AE?= =?UTF-8?q?=E9=A2=98ID=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/db/problems.cpp | 59 ++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/src/db/problems.cpp b/src/db/problems.cpp index e19bd41..10cc64d 100644 --- a/src/db/problems.cpp +++ b/src/db/problems.cpp @@ -2,17 +2,43 @@ #include +#include #include #include #include -#include + +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())); }