Commit 02a7bb02 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Album: Cache album artist.

This allows us to fetch the album artist at most once when parsing an
album, instead of one time for each track
parent 2f1e6e27
......@@ -232,10 +232,13 @@ ArtistPtr Album::albumArtist() const
{
if ( m_artistId == 0 )
return nullptr;
return Artist::fetch( m_ml, m_artistId );
auto lock = m_albumArtist.lock();
if ( m_albumArtist.isCached() == false )
m_albumArtist = Artist::fetch( m_ml, m_artistId );
return m_albumArtist.get();
}
bool Album::setAlbumArtist( Artist* artist )
bool Album::setAlbumArtist( std::shared_ptr<Artist> artist )
{
if ( m_artistId == artist->id() )
return true;
......@@ -247,10 +250,12 @@ bool Album::setAlbumArtist( Artist* artist )
return false;
if ( m_artistId != 0 )
{
auto previousArtist = Artist::fetch( m_ml, m_artistId );
previousArtist->updateNbAlbum( -1 );
if ( m_albumArtist.isCached() == false )
albumArtist();
m_albumArtist.get()->updateNbAlbum( -1 );
}
m_artistId = artist->id();
m_albumArtist = artist;
artist->updateNbAlbum( 1 );
static const std::string ftsReq = "UPDATE " + policy::AlbumTable::Name + "Fts SET "
" artist = ? WHERE rowid = ?";
......
......@@ -89,7 +89,7 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
unsigned int nbTracks() const override;
virtual ArtistPtr albumArtist() const override;
bool setAlbumArtist( Artist* artist );
bool setAlbumArtist( std::shared_ptr<Artist> artist );
virtual std::vector<ArtistPtr> artists(bool desc) const override;
bool addArtist( std::shared_ptr<Artist> artist );
bool removeArtist( Artist* artist );
......@@ -122,6 +122,7 @@ class Album : public IAlbum, public DatabaseHelpers<Album, policy::AlbumTable>
bool m_isPresent;
mutable Cache<std::vector<MediaPtr>> m_tracks;
mutable Cache<std::shared_ptr<Artist>> m_albumArtist;
friend struct policy::AlbumTable;
};
......
......@@ -394,7 +394,7 @@ bool MetadataParser::link( Media& media, std::shared_ptr<Album> album,
// We don't know if the artist was tagged as artist or albumartist, however, we simply add it
// as the albumartist until proven we were wrong (ie. until one of the next tracks
// has a different artist)
album->setAlbumArtist( albumArtist.get() );
album->setAlbumArtist( albumArtist );
// Always add the album artist as an artist
album->addArtist( albumArtist );
if ( artist != nullptr )
......@@ -406,7 +406,7 @@ bool MetadataParser::link( Media& media, std::shared_ptr<Album> album,
{
// We have more than a single artist on this album, fallback to various artists
auto variousArtists = Artist::fetch( m_ml, medialibrary::VariousArtistID );
album->setAlbumArtist( variousArtists.get() );
album->setAlbumArtist( variousArtists );
// Add those two artists as "featuring".
album->addArtist( albumArtist );
}
......
......@@ -242,7 +242,7 @@ TEST_F( Albums, AlbumArtist )
auto album = ml->createAlbum( "test" );
ASSERT_EQ( album->albumArtist(), nullptr );
auto artist = ml->createArtist( "artist" );
album->setAlbumArtist( artist.get() );
album->setAlbumArtist( artist );
ASSERT_NE( album->albumArtist(), nullptr );
Reload();
......@@ -266,7 +266,7 @@ TEST_F( Albums, SearchByArtist )
{
auto a = ml->createAlbum( "sea otters" );
auto artist = ml->createArtist( "pangolins" );
a->setAlbumArtist( artist.get() );
a->setAlbumArtist( artist );
auto albums = ml->searchAlbums( "pangol" );
ASSERT_EQ( 1u, albums.size() );
......@@ -276,7 +276,7 @@ TEST_F( Albums, SearchNoDuplicate )
{
auto a = ml->createAlbum( "sea otters" );
auto artist = ml->createArtist( "otters" );
a->setAlbumArtist( artist.get() );
a->setAlbumArtist( artist );
auto albums = ml->searchAlbums( "otters" );
ASSERT_EQ( 1u, albums.size() );
......@@ -310,7 +310,7 @@ TEST_F( Albums, SearchAfterArtistUpdate )
auto a = ml->createAlbum( "sea otters" );
auto artist = ml->createArtist( "pangolin of fire" );
auto artist2 = ml->createArtist( "pangolin of ice" );
a->setAlbumArtist( artist.get() );
a->setAlbumArtist( artist );
auto albums = ml->searchAlbums( "fire" );
ASSERT_EQ( 1u, albums.size() );
......@@ -318,7 +318,7 @@ TEST_F( Albums, SearchAfterArtistUpdate )
albums = ml->searchAlbums( "ice" );
ASSERT_EQ( 0u, albums.size() );
a->setAlbumArtist( artist2.get() );
a->setAlbumArtist( artist2 );
albums = ml->searchAlbums( "fire" );
ASSERT_EQ( 0u, albums.size() );
......
......@@ -98,8 +98,8 @@ TEST_F( Artists, Albums )
ASSERT_NE( album1, nullptr );
ASSERT_NE( album2, nullptr );
album1->setAlbumArtist( artist.get() );
album2->setAlbumArtist( artist.get() );
album1->setAlbumArtist( artist );
album2->setAlbumArtist( artist );
auto albums = artist->albums( medialibrary::SortingCriteria::Default, false );
ASSERT_EQ( albums.size(), 2u );
......@@ -144,7 +144,7 @@ TEST_F( Artists, GetAll )
auto a = ml->createArtist( std::to_string( i ) );
auto alb = ml->createAlbum( std::to_string( i ) );
ASSERT_NE( nullptr, alb );
alb->setAlbumArtist( a.get() );
alb->setAlbumArtist( a );
ASSERT_NE( a, nullptr );
}
artists = ml->artists( medialibrary::SortingCriteria::Default, false );
......@@ -251,9 +251,9 @@ TEST_F( Artists, SortAlbum )
auto album3 = ml->createAlbum( "album3" );
album3->setReleaseYear( 2000, false );
album1->setAlbumArtist( artist.get() );
album2->setAlbumArtist( artist.get() );
album3->setAlbumArtist( artist.get() );
album1->setAlbumArtist( artist );
album2->setAlbumArtist( artist );
album3->setAlbumArtist( artist );
// Default order is by descending year, discriminated by lexical order
auto albums = artist->albums( medialibrary::SortingCriteria::Default, false );
......@@ -286,10 +286,10 @@ TEST_F( Artists, Sort )
// Keep in mind that artists are only listed when they are marked as album artist at least once
auto a1 = ml->createArtist( "A" );
auto alb1 = ml->createAlbum( "albumA" );
alb1->setAlbumArtist( a1.get() );
alb1->setAlbumArtist( a1 );
auto a2 = ml->createArtist( "B" );
auto alb2 = ml->createAlbum( "albumB" );
alb2->setAlbumArtist( a2.get() );
alb2->setAlbumArtist( a2 );
auto artists = ml->artists( medialibrary::SortingCriteria::Alpha, false );
ASSERT_EQ( 2u, artists.size() );
......
......@@ -257,7 +257,7 @@ TEST_F( DeviceFs, RemoveAlbum )
auto media = ml->media( mock::FileSystemFactory::Root + "audio.mp3" );
album->addTrack( std::static_pointer_cast<Media>( media ), 1, 1 );
auto artist = ml->createArtist( "artist" );
album->setAlbumArtist( artist.get() );
album->setAlbumArtist( artist );
}
// And an album that will disappear, along with its artist
{
......@@ -267,7 +267,7 @@ TEST_F( DeviceFs, RemoveAlbum )
album->addTrack( std::static_pointer_cast<Media>( media ), 1, 1 );
album->addTrack( std::static_pointer_cast<Media>( media ), 2, 1 );
auto artist = ml->createArtist( "artist 2" );
album->setAlbumArtist( artist.get() );
album->setAlbumArtist( artist );
}
auto albums = ml->albums( medialibrary::SortingCriteria::Default, false );
......@@ -302,7 +302,7 @@ TEST_F( DeviceFs, PartialAlbumRemoval )
album->addTrack( std::static_pointer_cast<Media>( media ), 1, 1 );
album->addTrack( std::static_pointer_cast<Media>( media2 ), 2, 1 );
auto newArtist = ml->createArtist( "artist" );
album->setAlbumArtist( newArtist.get() );
album->setAlbumArtist( newArtist );
newArtist->addMedia( static_cast<Media&>( *media ) );
newArtist->addMedia( static_cast<Media&>( *media2 ) );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment