summary refs log tree commit diff
path: root/src/Cache_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cache_p.h')
-rw-r--r--src/Cache_p.h54
1 files changed, 28 insertions, 26 deletions
diff --git a/src/Cache_p.h b/src/Cache_p.h

index 9f19b724..69e99fa0 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h
@@ -310,9 +310,12 @@ public: static int compare_state_key(const MDB_val *a, const MDB_val *b) { auto get_skey = [](const MDB_val *v) { - return nlohmann::json::parse( - std::string_view(static_cast<const char *>(v->mv_data), v->mv_size)) - .value("key", ""); + auto temp = std::string_view(static_cast<const char *>(v->mv_data), v->mv_size); + // allow only passing the state key, in which case no null char will be in it and we + // return the whole string because rfind returns npos. + // We search from the back, because state keys could include nullbytes, event ids can + // not. + return temp.substr(0, temp.rfind('\0')); }; return get_skey(a).compare(get_skey(b)); @@ -438,22 +441,13 @@ private: else if (e.state_key.empty()) statesdb.del(txn, to_string(e.type)); else - stateskeydb.del(txn, - to_string(e.type), - nlohmann::json::object({ - {"key", e.state_key}, - {"id", e.event_id}, - }) - .dump()); + stateskeydb.del( + txn, to_string(e.type), e.state_key + '\0' + e.event_id); } else if (e.state_key.empty()) { statesdb.put(txn, to_string(e.type), nlohmann::json(e).dump()); } else { - auto data = nlohmann::json::object({ - {"key", e.state_key}, - {"id", e.event_id}, - }) - .dump(); - auto key = to_string(e.type); + auto data = e.state_key + '\0' + e.event_id; + auto key = to_string(e.type); // Work around https://bugs.openldap.org/show_bug.cgi?id=8447 stateskeydb.del(txn, key, data); @@ -485,9 +479,10 @@ private: return std::nullopt; } } else { - auto db = getStatesKeyDb(txn, room_id); - std::string d = nlohmann::json::object({{"key", state_key}}).dump(); - std::string_view data = d; + auto db = getStatesKeyDb(txn, room_id); + // we can search using state key, since the compare functions defaults to the whole + // string, when there is no nullbyte + std::string_view data = state_key; std::string_view typeStrV = typeStr; auto cursor = lmdb::cursor::open(txn, db); @@ -496,9 +491,14 @@ private: try { auto eventsDb = getEventsDb(txn, room_id); - if (!eventsDb.get( - txn, nlohmann::json::parse(data)["id"].get<std::string>(), value)) + auto eventid = data; + if (auto sep = data.rfind('\0'); sep != std::string_view::npos) { + if (!eventsDb.get(txn, eventid.substr(sep + 1), value)) + return std::nullopt; + } else { return std::nullopt; + } + } catch (std::exception &) { return std::nullopt; } @@ -537,10 +537,12 @@ private: first = false; try { - if (eventsDb.get( - txn, nlohmann::json::parse(data)["id"].get<std::string>(), value)) - events.push_back( - nlohmann::json::parse(value).get<mtx::events::StateEvent<T>>()); + auto eventid = data; + if (auto sep = data.rfind('\0'); sep != std::string_view::npos) { + if (eventsDb.get(txn, eventid.substr(sep + 1), value)) + events.push_back( + nlohmann::json::parse(value).get<mtx::events::StateEvent<T>>()); + } } catch (std::exception &e) { nhlog::db()->warn("Failed to parse state event: {}", e.what()); } @@ -636,7 +638,7 @@ private: lmdb::dbi getStatesKeyDb(lmdb::txn &txn, const std::string &room_id) { auto db = lmdb::dbi::open( - txn, std::string(room_id + "/state_by_key").c_str(), MDB_CREATE | MDB_DUPSORT); + txn, std::string(room_id + "/states_key").c_str(), MDB_CREATE | MDB_DUPSORT); lmdb::dbi_set_dupsort(txn, db, compare_state_key); return db; }