From 2086ab09b8d89c27f524d82a68b9a2035ea02436 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Tue, 24 Oct 2023 16:29:46 +1100 Subject: Implement incremental updates of database indexes This makes rescanning the library *so* much faster. Yay! --- src/database/records.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/database/records.cpp') diff --git a/src/database/records.cpp b/src/database/records.cpp index 0619cd93..c9fafe08 100644 --- a/src/database/records.cpp +++ b/src/database/records.cpp @@ -48,6 +48,7 @@ static const char* kTag = "RECORDS"; static const char kDataPrefix = 'D'; static const char kHashPrefix = 'H'; +static const char kTagHashPrefix = 'T'; static const char kIndexPrefix = 'I'; static const char kFieldSeparator = '\0'; @@ -62,6 +63,11 @@ auto EncodeDataKey(const TrackId& id) -> std::string { } auto EncodeDataValue(const TrackData& track) -> std::string { + auto* tag_hashes = new cppbor::Map{}; // Free'd by Array's dtor. + for (const auto& entry : track.individual_tag_hashes) { + tag_hashes->add(cppbor::Uint{static_cast(entry.first)}, + cppbor::Uint{entry.second}); + } cppbor::Array val{ cppbor::Uint{track.id}, cppbor::Tstr{track.filepath}, @@ -69,6 +75,7 @@ auto EncodeDataValue(const TrackData& track) -> std::string { cppbor::Bool{track.is_tombstoned}, cppbor::Uint{track.modified_at.first}, cppbor::Uint{track.modified_at.second}, + tag_hashes, }; return val.toString(); } @@ -80,12 +87,13 @@ auto ParseDataValue(const leveldb::Slice& slice) -> std::shared_ptr { return nullptr; } auto vals = item->asArray(); - if (vals->size() != 6 || vals->get(0)->type() != cppbor::UINT || + if (vals->size() != 7 || vals->get(0)->type() != cppbor::UINT || vals->get(1)->type() != cppbor::TSTR || vals->get(2)->type() != cppbor::UINT || vals->get(3)->type() != cppbor::SIMPLE || vals->get(4)->type() != cppbor::UINT || - vals->get(5)->type() != cppbor::UINT) { + vals->get(5)->type() != cppbor::UINT || + vals->get(6)->type() != cppbor::MAP) { return {}; } auto res = std::make_shared(); @@ -96,6 +104,12 @@ auto ParseDataValue(const leveldb::Slice& slice) -> std::shared_ptr { res->modified_at = std::make_pair( vals->get(4)->asUint()->unsignedValue(), vals->get(5)->asUint()->unsignedValue()); + + auto tag_hashes = vals->get(6)->asMap(); + for (const auto& entry : *tag_hashes) { + auto tag = static_cast(entry.first->asUint()->unsignedValue()); + res->individual_tag_hashes[tag] = entry.second->asUint()->unsignedValue(); + } return res; } @@ -113,6 +127,12 @@ auto EncodeHashValue(TrackId id) -> std::string { return TrackIdToBytes(id); } +/* 'T/ 0xBEEF' */ +auto EncodeTagHashKey(const uint64_t& hash) -> std::string { + return std::string{kTagHashPrefix, kFieldSeparator} + + cppbor::Uint{hash}.toString(); +} + /* 'I/' */ auto EncodeAllIndexesPrefix() -> std::string { return {kIndexPrefix, kFieldSeparator}; -- cgit v1.2.3