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