diff options
| author | cooljqln <cooljqln@noreply.codeberg.org> | 2025-01-24 00:40:48 +0000 |
|---|---|---|
| committer | cooljqln <cooljqln@noreply.codeberg.org> | 2025-01-24 00:40:48 +0000 |
| commit | 580712acd11d5afdacd51c2e8d29313efc93d520 (patch) | |
| tree | b53e5f14926e03ff5c5399b3be95c827a255c83b /src/tangara/database/records.cpp | |
| parent | eeead037478ec9015cac6383ff32af6e179a952d (diff) | |
| download | tangara-fw-580712acd11d5afdacd51c2e8d29313efc93d520.tar.gz | |
Resolve some issues with dangling index records (#193)
- The tag parser's cache is now cleared between indexing runs, preventing stale data from being used
- Multi-value tag fields (genres, all artists) are now properly ingested in the tag value cache
- Cleaning up removed index records now properly handles the case where only a subset of the records for multi-value tags need to be deleted.
- Synthesizing missing tag values is now done in the tag parser instead of TrackTags, which resolves some issues with multi-value tag callbacks from libtags not being handled properly
These fixes seem to address all the issues with stale index records we were able to repro (including the issues in https://codeberg.org/cool-tech-zone/tangara-fw/issues/191), but if you've got any more cases with consistent repros then lmk!
Co-authored-by: ailurux <ailuruxx@gmail.com>
Reviewed-on: https://codeberg.org/cool-tech-zone/tangara-fw/pulls/193
Diffstat (limited to 'src/tangara/database/records.cpp')
| -rw-r--r-- | src/tangara/database/records.cpp | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/src/tangara/database/records.cpp b/src/tangara/database/records.cpp index addcc13d..852eb131 100644 --- a/src/tangara/database/records.cpp +++ b/src/tangara/database/records.cpp @@ -181,11 +181,13 @@ auto EncodeAllIndexesPrefix() -> std::string { auto EncodeIndexPrefix(const IndexKey::Header& header) -> std::string { std::ostringstream out; out << makePrefix(kIndexPrefix); - cppbor::Array val{ - cppbor::Uint{header.id}, - cppbor::Uint{header.depth}, - cppbor::Uint{header.components_hash}, - }; + + cppbor::Array components{}; + for (auto hash : header.components_hash) { + components.add(cppbor::Uint{hash}); + } + + cppbor::Array val{cppbor::Uint{header.id}, std::move(components)}; out << val.toString() << kFieldSeparator; return out.str(); } @@ -210,8 +212,8 @@ auto EncodeIndexKey(const IndexKey& key) -> std::string { out << EncodeIndexPrefix(key.header); // The component should already be UTF-8 encoded, so just write it. - if (key.item) { - out << *key.item << kFieldSeparator; + if (!key.item.empty()) { + out << key.item << kFieldSeparator; } if (key.track) { @@ -236,14 +238,16 @@ auto ParseIndexKey(const leveldb::Slice& slice) -> std::optional<IndexKey> { return {}; } auto as_array = key->asArray(); - if (as_array->size() != 3 || as_array->get(0)->type() != cppbor::UINT || - as_array->get(1)->type() != cppbor::UINT || - as_array->get(2)->type() != cppbor::UINT) { + if (as_array->size() != 2 || as_array->get(0)->type() != cppbor::UINT || + as_array->get(1)->type() != cppbor::ARRAY) { return {}; } result.header.id = as_array->get(0)->asUint()->unsignedValue(); - result.header.depth = as_array->get(1)->asUint()->unsignedValue(); - result.header.components_hash = as_array->get(2)->asUint()->unsignedValue(); + auto components_array = as_array->get(1)->asArray(); + for (int i = 0; i < components_array->size(); i++) { + result.header.components_hash.push_back( + components_array->get(i)->asUint()->unsignedValue()); + } size_t header_length = reinterpret_cast<const char*>(end_of_key) - key_data.data(); |
