~aleteoryx/muditaos

00fde83a0a595847c500608054fbc375d93ca5ac — RobertPiet 4 years ago 0c09880
[EGD-5808] Introduce cache for Settings

Settings Cache introduced
M module-services/service-db/CMakeLists.txt => module-services/service-db/CMakeLists.txt +1 -0
@@ 19,6 19,7 @@ set(SOURCES
    messages/QueryMessage.cpp
    agents/settings/SettingsAgent.cpp
    agents/settings/Settings.cpp
    agents/settings/SettingsCache.cpp
    agents/file_indexer/FileIndexerAgent.cpp
)


M module-services/service-db/agents/settings/Settings.cpp => module-services/service-db/agents/settings/Settings.cpp +16 -1
@@ 3,6 3,7 @@

#include <service-db/Settings.hpp>
#include <service-db/SettingsMessages.hpp>
#include <service-db/SettingsCache.hpp>

#include <Service/Common.hpp>
#include <Service/Message.hpp>


@@ 14,10 15,14 @@

namespace settings
{
    Settings::Settings(sys::Service *app, const std::string &dbAgentName) : dbAgentName(dbAgentName)
    Settings::Settings(sys::Service *app, const std::string &dbAgentName, SettingsCache *cache)
        : dbAgentName(dbAgentName), cache(cache)
    {
        this->app = std::shared_ptr<sys::Service>(app, [](sys::Service *) {}); /// with deleter that doesn't delete.
        this->app->bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);
        if (nullptr == cache) {
            this->cache = SettingsCache::getInstance();
        }
        registerHandlers();
    }



@@ 187,6 192,16 @@ namespace settings
        path.scope    = scope;
        auto msg      = std::make_shared<settings::Messages::SetVariable>(path, variableValue);
        sendMsg(std::move(msg));
        cache->setValue(path, variableValue);
    }

    std::string Settings::getValue(const std::string &variableName, SettingsScope scope)
    {
        EntryPath path;
        path.variable = variableName;
        path.service  = app->GetName();
        path.scope    = scope;
        return cache->getValue(path);
    }

    void Settings::getAllProfiles(OnAllProfilesRetrievedCallback cb)

M module-services/service-db/agents/settings/SettingsAgent.cpp => module-services/service-db/agents/settings/SettingsAgent.cpp +19 -1
@@ 7,6 7,7 @@
#include <Database/Database.hpp>
#include <Service/Service.hpp>
#include <purefs/filesystem_paths.hpp>
#include <service-db/SettingsCache.hpp>

namespace settings::DbPaths
{


@@ 14,13 15,30 @@ namespace settings::DbPaths
    constexpr auto phone_profile = "system/phone_profile";
}; // namespace settings::DbPaths

SettingsAgent::SettingsAgent(sys::Service *parentService) : DatabaseAgent(parentService)
SettingsAgent::SettingsAgent(sys::Service *parentService, settings::SettingsCache *cache)
    : DatabaseAgent(parentService), cache(cache)
{
    if (nullptr == cache) {
        this->cache = settings::SettingsCache::getInstance();
    }
    database = std::make_unique<Database>(getDbFilePath().c_str());
}

void SettingsAgent::initDb()
{
    // first approach -> take care about big amount of variables
    auto allVars = database->query(settings::Statements::getAllValues);
    if (nullptr == allVars || 0 == allVars->getRowCount()) {
        return;
    }

    do {
        auto path  = (*allVars)[0].getString();
        auto value = (*allVars)[0].getString();
        settings::EntryPath variablePath;
        variablePath.parse(path);
        cache->setValue(variablePath, value);
    } while (allVars->nextRow());
}

void SettingsAgent::deinitDb()

M module-services/service-db/agents/settings/SettingsAgent.hpp => module-services/service-db/agents/settings/SettingsAgent.hpp +3 -2
@@ 14,6 14,7 @@
namespace settings
{
    struct EntryPath;
    class SettingsCache;
} // namespace settings
namespace sys
{


@@ 23,7 24,7 @@ namespace sys
class SettingsAgent : public DatabaseAgent
{
  public:
    SettingsAgent(sys::Service *parentService);
    SettingsAgent(sys::Service *parentService, settings::SettingsCache *cache = nullptr);
    ~SettingsAgent() = default;

    void initDb() override;


@@ 33,7 34,7 @@ class SettingsAgent : public DatabaseAgent
    auto getDbFilePath() -> const std::string override;

  private:
    // using MapOfRecipentsToBeNotified = std::map<std::string, std::set<std::string>>;
    settings::SettingsCache *cache;
    using MapOfRecipentsToBeNotified = std::map<std::string, std::set<settings::EntryPath>>;
    MapOfRecipentsToBeNotified variableChangeRecipents;
    using SetOfRecipents = std::set<std::string>;

A module-services/service-db/agents/settings/SettingsCache.cpp => module-services/service-db/agents/settings/SettingsCache.cpp +29 -0
@@ 0,0 1,29 @@
#include <service-db/SettingsCache.hpp>
#include <mutex.hpp>

namespace settings
{

    SettingsCache *SettingsCache::getInstance()
    {
        static SettingsCache instance;
        return &instance;
    }

    const std::string &SettingsCache::getValue(const EntryPath &path) const
    {
        static const std::string empty = "";
        cpp_freertos::LockGuard lock(settingsMutex);
        auto pathIt = settingsMap.find(path);
        if (settingsMap.end() != pathIt) {
            return pathIt->second;
        }
        return empty;
    }

    void SettingsCache::setValue(const EntryPath &path, const std::string &value)
    {
        cpp_freertos::LockGuard lock(settingsMutex);
        settingsMap[path] = value;
    }
} // namespace settings

M module-services/service-db/agents/settings/Settings_queries.hpp => module-services/service-db/agents/settings/Settings_queries.hpp +5 -0
@@ 14,6 14,11 @@ namespace settings::Statements
                         COLLATE NOCASE;
                         )sql";

    constexpr auto getAllValues = R"sql(
                                        SELECT path, value
                                        FROM settings_tab;
                                        )sql";

    constexpr auto checkPathExists = R"sql(
                        SELECT COUNT(value) AS PATH_EXISTS FROM  settings_tab AS ST
                        WHERE ST.path = '%q'

M module-services/service-db/service-db/Settings.hpp => module-services/service-db/service-db/Settings.hpp +5 -1
@@ 18,6 18,7 @@

namespace settings
{
    class SettingsCache;
    class Settings
    {
      public:


@@ 30,7 31,7 @@ namespace settings
        using OnAllProfilesRetrievedCallback = std::function<void(const ListOfProfiles &)>;
        using OnAllModesRetrievedCallback    = std::function<void(const ListOfModes &)>;

        Settings(sys::Service *app, const std::string &dbAgentName = service::name::db);
        Settings(sys::Service *app, const std::string &dbAgentName = service::name::db, SettingsCache *cache = nullptr);
        virtual ~Settings();

        void setValue(const std::string &variableName,


@@ 45,6 46,7 @@ namespace settings
        void unregisterValueChange(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal);
        /// unregisters all registered variables (both global and local)
        void unregisterValueChange();
        std::string getValue(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal);

        void getAllProfiles(OnAllProfilesRetrievedCallback cb);
        void setCurrentProfile(const std::string &profile);


@@ 66,6 68,8 @@ namespace settings
        std::string phoneMode;
        std::string profile;

        SettingsCache *cache;

        using ValueCb = std::map<EntryPath, std::pair<ValueChangedCallback, ValueChangedCallbackWithName>>;
        ValueCb cbValues;
        ModeChangedCallback cbMode;

A module-services/service-db/service-db/SettingsCache.hpp => module-services/service-db/service-db/SettingsCache.hpp +17 -0
@@ 0,0 1,17 @@
#include <mutex.hpp>
#include "SettingsMessages.hpp"

namespace settings
{
    class SettingsCache
    {
      public:
        const std::string &getValue(const EntryPath &path) const;
        void setValue(const EntryPath &path, const std::string &value);
        static SettingsCache *getInstance();

      private:
        std::map<EntryPath, std::string> settingsMap;
        mutable cpp_freertos::MutexStandard settingsMutex;
    };
} // namespace settings

M module-services/service-db/service-db/SettingsMessages.hpp => module-services/service-db/service-db/SettingsMessages.hpp +17 -0
@@ 12,6 12,7 @@
#include <set>
#include <utility>
#include <variant>
#include <module-utils/Utils.hpp>

namespace settings
{


@@ 31,6 32,22 @@ namespace settings
            return mode + sep + service + sep + profile + sep + variable;
        }

        void parse(const std::string &dbPath)
        {
            auto parts = utils::split(dbPath, "\\");
            if (1 == parts.size()) {
                variable = dbPath;
                scope    = SettingsScope::Global;
            }
            else {
                mode     = parts[0];
                service  = parts[1];
                profile  = parts[2];
                variable = parts[3];
                scope    = SettingsScope::AppLocal;
            }
        }

        bool operator<(const EntryPath &other) const
        {
            if (mode < other.mode)