Generate stable track external IDs by hashing various file and metadata

fields. Playlists can now survive track table rebuilds.
This commit is contained in:
casey langen 2017-05-18 10:24:16 -07:00
parent f8e201cb80
commit f57881c88e
2 changed files with 17 additions and 9 deletions

View File

@ -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");
}

View File

@ -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 */