Migrated recommendation stuff
This commit is contained in:
@@ -4,7 +4,7 @@ add_library(lmsrecommendation SHARED
|
||||
impl/features/FeaturesEngineCache.cpp
|
||||
impl/features/FeaturesEngine.cpp
|
||||
impl/features/FeaturesDefs.cpp
|
||||
impl/Engine.cpp
|
||||
impl/RecommendationService.cpp
|
||||
)
|
||||
|
||||
target_include_directories(lmsrecommendation INTERFACE
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "recommendation/IEngine.hpp"
|
||||
#include "IEngine.hpp"
|
||||
|
||||
namespace Database
|
||||
{
|
||||
|
||||
+1
-14
@@ -24,6 +24,7 @@
|
||||
#include <string_view>
|
||||
#include "database/Types.hpp"
|
||||
#include "utils/EnumSet.hpp"
|
||||
#include "services/recommendation/Types.hpp"
|
||||
|
||||
namespace Database
|
||||
{
|
||||
@@ -37,23 +38,9 @@ namespace Recommendation
|
||||
public:
|
||||
virtual ~IEngine() = default;
|
||||
|
||||
struct Progress
|
||||
{
|
||||
std::size_t totalElems {};
|
||||
std::size_t processedElems {};
|
||||
};
|
||||
using ProgressCallback = std::function<void(const Progress&)>;
|
||||
virtual void load(bool forceReload, const ProgressCallback& progressCallback = {}) = 0;
|
||||
virtual void cancelLoad() = 0; // wait for cancel done
|
||||
virtual void requestCancelLoad() = 0;
|
||||
|
||||
template <typename IdType>
|
||||
using ResultContainer = std::vector<IdType>;
|
||||
|
||||
using ArtistContainer = ResultContainer<Database::ArtistId>;
|
||||
using ReleaseContainer = ResultContainer<Database::ReleaseId>;
|
||||
using TrackContainer = ResultContainer<Database::TrackId>;
|
||||
|
||||
virtual TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const = 0;
|
||||
virtual TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const = 0;
|
||||
virtual ReleaseContainer getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const = 0;
|
||||
+18
-18
@@ -17,7 +17,7 @@
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Engine.hpp"
|
||||
#include "RecommendationService.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@@ -47,19 +47,19 @@ namespace Recommendation
|
||||
throw LmsException {"Internal error"};
|
||||
}
|
||||
|
||||
std::unique_ptr<IEngine>
|
||||
createEngine(Database::Db& db)
|
||||
std::unique_ptr<IRecommendationService>
|
||||
createRecommendationService(Database::Db& db)
|
||||
{
|
||||
return std::make_unique<Engine>(db);
|
||||
return std::make_unique<RecommendationService>(db);
|
||||
}
|
||||
|
||||
Engine::Engine(Database::Db& db)
|
||||
RecommendationService::RecommendationService(Database::Db& db)
|
||||
: _db {db}
|
||||
{
|
||||
}
|
||||
|
||||
Engine::TrackContainer
|
||||
Engine::getSimilarTracksFromTrackList(Database::TrackListId trackListId, std::size_t maxCount) const
|
||||
TrackContainer
|
||||
RecommendationService::getSimilarTracksFromTrackList(Database::TrackListId trackListId, std::size_t maxCount) const
|
||||
{
|
||||
TrackContainer res;
|
||||
|
||||
@@ -78,8 +78,8 @@ namespace Recommendation
|
||||
return res;
|
||||
}
|
||||
|
||||
Engine::TrackContainer
|
||||
Engine::getSimilarTracks(const std::vector<Database::TrackId>& trackIds, std::size_t maxCount) const
|
||||
TrackContainer
|
||||
RecommendationService::getSimilarTracks(const std::vector<Database::TrackId>& trackIds, std::size_t maxCount) const
|
||||
{
|
||||
TrackContainer res;
|
||||
|
||||
@@ -102,8 +102,8 @@ namespace Recommendation
|
||||
return res;
|
||||
}
|
||||
|
||||
Engine::ReleaseContainer
|
||||
Engine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
||||
ReleaseContainer
|
||||
RecommendationService::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
||||
{
|
||||
ReleaseContainer res;
|
||||
|
||||
@@ -128,8 +128,8 @@ namespace Recommendation
|
||||
return res;
|
||||
}
|
||||
|
||||
Engine::ArtistContainer
|
||||
Engine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> linkTypes, std::size_t maxCount) const
|
||||
ArtistContainer
|
||||
RecommendationService::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> linkTypes, std::size_t maxCount) const
|
||||
{
|
||||
ArtistContainer res;
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace Recommendation
|
||||
}
|
||||
|
||||
void
|
||||
Engine::load(bool forceReload, const ProgressCallback& progressCallback)
|
||||
RecommendationService::load(bool forceReload, const ProgressCallback& progressCallback)
|
||||
{
|
||||
using namespace Database;
|
||||
|
||||
@@ -208,18 +208,18 @@ namespace Recommendation
|
||||
}
|
||||
|
||||
void
|
||||
Engine::loadPendingEngine(EngineType engineType, std::unique_ptr<IEngine> engine, bool forceReload, const ProgressCallback& progressCallback)
|
||||
RecommendationService::loadPendingEngine(EngineType engineType, std::unique_ptr<IEngine> engine, bool forceReload, const ProgressCallback& progressCallback)
|
||||
{
|
||||
if (!_loadCancelled)
|
||||
{
|
||||
LMS_LOG(RECOMMENDATION, INFO) << "Initializing engine '" << engineTypeToString(engineType) << "'...";
|
||||
|
||||
auto progress {[&](const IEngine::Progress& progress)
|
||||
auto progress {[&](const Progress& progress)
|
||||
{
|
||||
progressCallback(progress);
|
||||
}};
|
||||
|
||||
engine->load(forceReload, progressCallback ? progress : IEngine::ProgressCallback {});
|
||||
engine->load(forceReload, progressCallback ? progress : ProgressCallback {});
|
||||
|
||||
{
|
||||
std::scoped_lock lock {_controlMutex};
|
||||
@@ -236,7 +236,7 @@ namespace Recommendation
|
||||
}
|
||||
|
||||
void
|
||||
Engine::cancelLoad()
|
||||
RecommendationService::cancelLoad()
|
||||
{
|
||||
LMS_LOG(RECOMMENDATION, DEBUG) << "Cancelling loading...";
|
||||
|
||||
+9
-9
@@ -25,7 +25,8 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "recommendation/IEngine.hpp"
|
||||
#include "services/recommendation/IRecommendationService.hpp"
|
||||
#include "IEngine.hpp"
|
||||
|
||||
namespace Database
|
||||
{
|
||||
@@ -40,21 +41,20 @@ namespace Recommendation
|
||||
Features,
|
||||
};
|
||||
|
||||
class Engine : public IEngine
|
||||
class RecommendationService : public IRecommendationService
|
||||
{
|
||||
public:
|
||||
Engine(Database::Db& db);
|
||||
~Engine() = default;
|
||||
RecommendationService(Database::Db& db);
|
||||
~RecommendationService() = default;
|
||||
|
||||
Engine(const Engine&) = delete;
|
||||
Engine(Engine&&) = delete;
|
||||
Engine& operator=(const Engine&) = delete;
|
||||
Engine& operator=(Engine&&) = delete;
|
||||
RecommendationService(const RecommendationService&) = delete;
|
||||
RecommendationService(RecommendationService&&) = delete;
|
||||
RecommendationService& operator=(const RecommendationService&) = delete;
|
||||
RecommendationService& operator=(RecommendationService&&) = delete;
|
||||
|
||||
private:
|
||||
void load(bool forceReload, const ProgressCallback& progressCallback) override;
|
||||
void cancelLoad() override;
|
||||
void requestCancelLoad() override {};
|
||||
|
||||
TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const override;
|
||||
TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const override;
|
||||
@@ -34,7 +34,7 @@ std::unique_ptr<IEngine> createClustersEngine(Database::Db& db)
|
||||
return std::make_unique<ClusterEngine>(db);
|
||||
}
|
||||
|
||||
IEngine::TrackContainer
|
||||
TrackContainer
|
||||
ClusterEngine::getSimilarTracks(const std::vector<Database::TrackId>& trackIds, std::size_t maxCount) const
|
||||
{
|
||||
Database::Session& dbSession {_db.getTLSSession()};
|
||||
@@ -52,7 +52,7 @@ ClusterEngine::getSimilarTracks(const std::vector<Database::TrackId>& trackIds,
|
||||
return res;
|
||||
}
|
||||
|
||||
IEngine::ResultContainer<Database::TrackId>
|
||||
TrackContainer
|
||||
ClusterEngine::getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const
|
||||
{
|
||||
Database::Session& dbSession {_db.getTLSSession()};
|
||||
@@ -74,7 +74,7 @@ ClusterEngine::getSimilarTracksFromTrackList(Database::TrackListId tracklistId,
|
||||
return res;
|
||||
}
|
||||
|
||||
IEngine::ResultContainer<Database::ReleaseId>
|
||||
ReleaseContainer
|
||||
ClusterEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
||||
{
|
||||
Database::Session& dbSession {_db.getTLSSession()};
|
||||
@@ -95,7 +95,7 @@ ClusterEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t max
|
||||
return res;
|
||||
}
|
||||
|
||||
IEngine::ResultContainer<Database::ArtistId>
|
||||
ArtistContainer
|
||||
ClusterEngine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> artistLinkTypes, std::size_t maxCount) const
|
||||
{
|
||||
Database::Session& dbSession {_db.getTLSSession()};
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "recommendation/IEngine.hpp"
|
||||
#include "IEngine.hpp"
|
||||
|
||||
namespace Recommendation
|
||||
{
|
||||
@@ -37,7 +37,6 @@ namespace Recommendation
|
||||
private:
|
||||
void load(bool, const ProgressCallback&) override {}
|
||||
void requestCancelLoad() override {}
|
||||
void cancelLoad() {}
|
||||
|
||||
TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const override;
|
||||
TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const override;
|
||||
|
||||
@@ -248,7 +248,7 @@ FeaturesEngine::loadFromCache(FeaturesEngineCache cache)
|
||||
load(std::move(cache._network), cache._trackPositions);
|
||||
}
|
||||
|
||||
IEngine::TrackContainer
|
||||
TrackContainer
|
||||
FeaturesEngine::getSimilarTracksFromTrackList(Database::TrackListId trackListId, std::size_t maxCount) const
|
||||
{
|
||||
const TrackContainer trackIds {[&]
|
||||
@@ -269,7 +269,7 @@ FeaturesEngine::getSimilarTracksFromTrackList(Database::TrackListId trackListId,
|
||||
return getSimilarTracks(trackIds, maxCount);
|
||||
}
|
||||
|
||||
IEngine::TrackContainer
|
||||
TrackContainer
|
||||
FeaturesEngine::getSimilarTracks(const std::vector<Database::TrackId>& tracksIds, std::size_t maxCount) const
|
||||
{
|
||||
auto similarTrackIds {getSimilarObjects(tracksIds, _trackMatrix, _trackPositions, maxCount)};
|
||||
@@ -290,7 +290,7 @@ FeaturesEngine::getSimilarTracks(const std::vector<Database::TrackId>& tracksIds
|
||||
return similarTrackIds;
|
||||
}
|
||||
|
||||
IEngine::ReleaseContainer
|
||||
ReleaseContainer
|
||||
FeaturesEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const
|
||||
{
|
||||
auto similarReleaseIds {getSimilarObjects({releaseId}, _releaseMatrix, _releasePositions, maxCount)};
|
||||
@@ -312,12 +312,12 @@ FeaturesEngine::getSimilarReleases(Database::ReleaseId releaseId, std::size_t ma
|
||||
return similarReleaseIds;
|
||||
}
|
||||
|
||||
std::vector<Database::ArtistId>
|
||||
ArtistContainer
|
||||
FeaturesEngine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> linkTypes, std::size_t maxCount) const
|
||||
{
|
||||
auto getSimilarArtistIdsForLinkType {[&] (Database::TrackArtistLinkType linkType)
|
||||
{
|
||||
std::vector<Database::ArtistId> similarArtistIds;
|
||||
ArtistContainer similarArtistIds;
|
||||
|
||||
const auto itArtists {_artistMatrix.find(linkType)};
|
||||
if (itArtists == std::cend(_artistMatrix))
|
||||
@@ -336,7 +336,7 @@ FeaturesEngine::getSimilarArtists(Database::ArtistId artistId, EnumSet<Database:
|
||||
similarArtistIds.insert(std::begin(similarArtistIdsForLinkType), std::end(similarArtistIdsForLinkType));
|
||||
}
|
||||
|
||||
std::vector<Database::ArtistId> res(std::cbegin(similarArtistIds), std::cend(similarArtistIds));
|
||||
ArtistContainer res(std::cbegin(similarArtistIds), std::cend(similarArtistIds));
|
||||
|
||||
Database::Session& session {_db.getTLSSession()};
|
||||
{
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "recommendation/IEngine.hpp"
|
||||
#include "som/DataNormalizer.hpp"
|
||||
#include "som/Network.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
#include "IEngine.hpp"
|
||||
#include "FeaturesEngineCache.hpp"
|
||||
#include "FeaturesDefs.hpp"
|
||||
|
||||
@@ -62,7 +62,6 @@ class FeaturesEngine : public IEngine
|
||||
private:
|
||||
void load(bool forceReload, const ProgressCallback& progressCallback) override;
|
||||
void requestCancelLoad() override;
|
||||
void cancelLoad() override {}
|
||||
|
||||
TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const override;
|
||||
TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const override;
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include "utils/EnumSet.hpp"
|
||||
#include "services/recommendation/Types.hpp"
|
||||
|
||||
namespace Database
|
||||
{
|
||||
class Db;
|
||||
}
|
||||
|
||||
namespace Recommendation
|
||||
{
|
||||
class IRecommendationService
|
||||
{
|
||||
public:
|
||||
virtual ~IRecommendationService() = default;
|
||||
|
||||
virtual void load(bool forceReload, const ProgressCallback& progressCallback = {}) = 0;
|
||||
virtual void cancelLoad() = 0; // wait for cancel done
|
||||
|
||||
virtual TrackContainer getSimilarTracksFromTrackList(Database::TrackListId tracklistId, std::size_t maxCount) const = 0;
|
||||
virtual TrackContainer getSimilarTracks(const std::vector<Database::TrackId>& tracksId, std::size_t maxCount) const = 0;
|
||||
virtual ReleaseContainer getSimilarReleases(Database::ReleaseId releaseId, std::size_t maxCount) const = 0;
|
||||
virtual ArtistContainer getSimilarArtists(Database::ArtistId artistId, EnumSet<Database::TrackArtistLinkType> linkTypes, std::size_t maxCount) const = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<IRecommendationService> createRecommendationService(Database::Db& db);
|
||||
|
||||
} // ns Recommendation
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include "database/Types.hpp"
|
||||
|
||||
namespace Recommendation
|
||||
{
|
||||
struct Progress
|
||||
{
|
||||
std::size_t totalElems {};
|
||||
std::size_t processedElems {};
|
||||
};
|
||||
using ProgressCallback = std::function<void(const Progress&)>;
|
||||
|
||||
template <typename IdType>
|
||||
using ResultContainer = std::vector<IdType>;
|
||||
|
||||
using ArtistContainer = ResultContainer<Database::ArtistId>;
|
||||
using ReleaseContainer = ResultContainer<Database::ReleaseId>;
|
||||
using TrackContainer = ResultContainer<Database::TrackId>;
|
||||
|
||||
} // namespace Recommendation
|
||||
Reference in New Issue
Block a user