diff --git a/src/core/library/Indexer.cpp b/src/core/library/Indexer.cpp index 39d761f7c..382c7663b 100644 --- a/src/core/library/Indexer.cpp +++ b/src/core/library/Indexer.cpp @@ -607,9 +607,8 @@ void Indexer::SyncCleanup() { this->dbConnection.Execute("DELETE FROM meta_values WHERE id NOT IN (SELECT DISTINCT(meta_value_id) FROM track_meta)"); this->dbConnection.Execute("DELETE FROM meta_keys WHERE id NOT IN (SELECT DISTINCT(meta_key_id) FROM meta_values)"); - /* orphaned playlist tracks (local tracks only. let tracks from external - sources continue to exist */ - this->dbConnection.Execute("DELETE FROM playlist_tracks WHERE source_id=0 AND track_external_id NOT IN (SELECT DISTINCT external_id FROM tracks WHERE source_id == 0)"); + /* NOTE: we used to remove orphaned local library tracks here, but we don't anymore because + the indexer generates stable external ids by hashing various file and metadata fields */ /* orphaned playlist tracks from source plugins that do not have stable ids need to be cleaned up. */ @@ -629,7 +628,6 @@ void Indexer::SyncCleanup() { } } - /* optimize and shrink */ this->dbConnection.Execute("VACUUM"); } diff --git a/src/core/library/track/IndexerTrack.cpp b/src/core/library/track/IndexerTrack.cpp index 31d9888c8..0388a8b07 100644 --- a/src/core/library/track/IndexerTrack.cpp +++ b/src/core/library/track/IndexerTrack.cpp @@ -43,9 +43,6 @@ #include <core/io/DataStreamFactory.h> #include <boost/lexical_cast.hpp> -#include <boost/uuid/uuid.hpp> -#include <boost/uuid/uuid_generators.hpp> -#include <boost/uuid/uuid_io.hpp> #include <unordered_map> using namespace musik::core; @@ -62,7 +59,6 @@ using namespace musik::core; static std::mutex trackWriteLock; static std::unordered_map<std::string, int64_t> metadataIdCache; -static auto uuids = boost::uuids::random_generator(); void IndexerTrack::ResetIdCache() { metadataIdCache.clear(); @@ -477,6 +473,20 @@ static size_t hash32(const char* str) { return h; } +static std::string createTrackExternalId(IndexerTrack& track) { + size_t hash1 = (size_t) hash32(track.GetValue("filename").c_str()); + + size_t hash2 = (size_t) hash32( + (track.GetValue("title") + + track.GetValue("album") + + track.GetValue("artist") + + track.GetValue("album_artist") + + track.GetValue("filesize") + + track.GetValue("duration")).c_str()); + + return std::string("local-") + std::to_string(hash1) + "-" + std::to_string(hash2); +} + int64_t IndexerTrack::SaveAlbum(db::Connection& dbConnection) { std::string album = this->GetValue("album"); std::string value = album + "-" + this->GetValue("album_artist"); @@ -619,7 +629,7 @@ bool IndexerTrack::Save(db::Connection &dbConnection, std::string libraryDirecto } if (this->GetValue("external_id") == "") { - this->SetValue("external_id", boost::uuids::to_string(uuids()).c_str()); + this->SetValue("external_id", createTrackExternalId(*this).c_str()); } /* remove existing relations -- we're going to update them with fresh data */