From df22bed0724b3a0d04c9fefd0f5bb130945a6b4e Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 12 Jul 2023 10:36:06 +1000 Subject: [PATCH] Include title in indexes to avoid a per-record disk read GOTTA GO FAST --- src/app_console/app_console.cpp | 2 +- src/database/database.cpp | 26 +++++++++----------------- src/database/include/database.hpp | 7 ++++--- src/database/index.cpp | 9 +++++++-- src/ui/screen_track_browser.cpp | 7 ------- src/ui/ui_fsm.cpp | 2 +- 6 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/app_console/app_console.cpp b/src/app_console/app_console.cpp index 2b5b84f7..a3f04bf9 100644 --- a/src/app_console/app_console.cpp +++ b/src/app_console/app_console.cpp @@ -259,7 +259,7 @@ int CmdDbIndex(int argc, char** argv) { for (database::IndexRecord r : res->values()) { std::cout << r.text().value_or(""); if (r.track()) { - std::cout << "\t(id:" << r.track()->data().id() << ")"; + std::cout << "\t(id:" << *r.track() << ")"; } std::cout << std::endl; } diff --git a/src/database/database.cpp b/src/database/database.cpp index 0d1c43e2..d0011abe 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -600,20 +600,12 @@ auto Database::ParseRecord(const leveldb::Slice& key, return {}; } - // If there was a track id included for this key, then this is a leaf record. - // Fetch the actual track data instead of relying on the information in the - // key. - std::optional track; - if (data->track) { - std::optional track_data = dbGetTrackData(*data->track); - TrackTags track_tags; - if (track_data && - tag_parser_->ReadAndParseTags(track_data->filepath(), &track_tags)) { - track.emplace(*track_data, track_tags); - } + std::optional title; + if (!val.empty()) { + title = val.ToString(); } - return IndexRecord(*data, track); + return IndexRecord(*data, title, data->track); } template <> @@ -663,17 +655,17 @@ auto Database::ParseRecord(const leveldb::Slice& key, return stream.str(); } -IndexRecord::IndexRecord(const IndexKey& key, std::optional track) - : key_(key), track_(track) {} +IndexRecord::IndexRecord(const IndexKey& key, std::optional title, std::optional track) + : key_(key), override_text_(title), track_(track) {} auto IndexRecord::text() const -> std::optional { - if (track_) { - return track_->TitleOrFilename(); + if (override_text_) { + return override_text_; } return key_.item; } -auto IndexRecord::track() const -> std::optional { +auto IndexRecord::track() const -> std::optional { return track_; } diff --git a/src/database/include/database.hpp b/src/database/include/database.hpp index 7ffc15b0..f7e44299 100644 --- a/src/database/include/database.hpp +++ b/src/database/include/database.hpp @@ -70,16 +70,17 @@ class Result { class IndexRecord { public: - explicit IndexRecord(const IndexKey&, std::optional); + explicit IndexRecord(const IndexKey&, std::optional, std::optional); auto text() const -> std::optional; - auto track() const -> std::optional; + auto track() const -> std::optional; auto Expand(std::size_t) const -> std::optional>; private: IndexKey key_; - std::optional track_; + std::optional override_text_; + std::optional track_; }; class Database { diff --git a/src/database/index.cpp b/src/database/index.cpp index a828578d..84d00bcd 100644 --- a/src/database/index.cpp +++ b/src/database/index.cpp @@ -52,15 +52,20 @@ auto Index(const IndexInfo& info, const Track& t, leveldb::WriteBatch* batch) key.item = {}; } - // If this is the last component, then we should also fill in the track id. + // If this is the last component, then we should also fill in the track id + // and title. + std::optional title; if (i == info.components.size() - 1) { key.track = t.data().id(); + if (info.components.at(i) != Tag::kTitle) { + title = t.TitleOrFilename(); + } } else { key.track = {}; } auto encoded = EncodeIndexKey(key); - batch->Put(encoded.slice, leveldb::Slice{}); + batch->Put(encoded.slice, title.value_or("")); // If there are more components after this, then we need to finish by // narrowing the header with the current title. diff --git a/src/ui/screen_track_browser.cpp b/src/ui/screen_track_browser.cpp index bf8a550c..d1fd921c 100644 --- a/src/ui/screen_track_browser.cpp +++ b/src/ui/screen_track_browser.cpp @@ -110,7 +110,6 @@ auto TrackBrowser::Tick() -> void { } if (loading_page_->wait_for(std::chrono::seconds(0)) == std::future_status::ready) { - ESP_LOGI(kTag, "load finished. adding to page."); auto result = loading_page_->get(); AddResults(loading_pos_.value_or(END), result); @@ -125,12 +124,10 @@ auto TrackBrowser::OnItemSelected(lv_event_t* ev) -> void { return; } if (index < kPageBuffer) { - ESP_LOGI(kTag, "fetch page at start"); FetchNewPage(START); return; } if (index > GetNumRecords() - kPageBuffer) { - ESP_LOGI(kTag, "fetch page at end"); FetchNewPage(END); return; } @@ -254,7 +251,6 @@ auto TrackBrowser::DropPage(Position pos) -> void { auto TrackBrowser::FetchNewPage(Position pos) -> void { if (loading_page_) { - ESP_LOGI(kTag, "already loading; giving up"); return; } @@ -268,7 +264,6 @@ auto TrackBrowser::FetchNewPage(Position pos) -> void { break; } if (!cont) { - ESP_LOGI(kTag, "out of pages; giving up"); return; } @@ -282,11 +277,9 @@ auto TrackBrowser::FetchNewPage(Position pos) -> void { if (current_pages_.size() >= kMaxPages) { switch (pos) { case START: - ESP_LOGI(kTag, "dropping end page"); DropPage(END); break; case END: - ESP_LOGI(kTag, "dropping start page"); DropPage(START); break; } diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp index b57f97f1..d2d0ad59 100644 --- a/src/ui/ui_fsm.cpp +++ b/src/ui/ui_fsm.cpp @@ -120,7 +120,7 @@ void Browse::react(const internal::RecordSelected& ev) { ESP_LOGI(kTag, "selected track '%s'", ev.record.text()->c_str()); // TODO(jacqueline): We should also send some kind of playlist info here. sQueue->Clear(); - sQueue->AddLast(ev.record.track()->data().id()); + sQueue->AddLast(*ev.record.track()); transit(); } else { ESP_LOGI(kTag, "selected record '%s'", ev.record.text()->c_str());