#pragma once #include "local_ads/event.hpp" #include "base/thread.hpp" #include #include #include #include #include #include #include #include namespace local_ads { using ServerSerializer = std::function(std::list const & events, std::string const & userId, std::string & contentType, std::string & contentEncoding)>; class Statistics final { public: struct PackedData { int64_t m_mercator = 0; uint32_t m_featureIndex = 0; uint32_t m_seconds = 0; uint16_t m_accuracy = 0; uint8_t m_eventType = 0; uint8_t m_zoomLevel = 0; }; Statistics() = default; ~Statistics(); void Startup(); void Teardown(); void SetUserId(std::string const & userId); void SetCustomServerSerializer(ServerSerializer && serializer); void RegisterEvent(Event && event); void RegisterEvents(std::list && events); std::list WriteEventsForTesting(std::list const & events, std::string & fileNameToRebuild); std::list ReadEventsForTesting(std::string const & fileName); void ProcessEventsForTesting(std::list const & events); void CleanupAfterTesting(); private: void ThreadRoutine(); bool RequestEvents(std::list & events, bool & needToSend); void IndexMetadata(); void ExtractMetadata(std::string const & fileName); void BalanceMemory(); std::list WriteEvents(std::list & events, std::string & fileNameToRebuild); std::list ReadEvents(std::string const & fileName) const; void ProcessEvents(std::list & events); void SendToServer(); std::vector SerializeForServer(std::list const & events) const; using MetadataKey = std::pair; struct Metadata { std::string m_fileName; Timestamp m_timestamp; Metadata() = default; Metadata(std::string const & fileName, Timestamp const & timestamp) : m_fileName(fileName), m_timestamp(timestamp) { } }; std::map m_metadataCache; std::chrono::steady_clock::time_point m_lastSending; bool m_isFirstSending = true; std::string m_userId; ServerSerializer m_serverSerializer; bool m_isRunning = false; std::list m_events; std::condition_variable m_condition; std::mutex m_mutex; threads::SimpleThread m_thread; }; } // namespace local_ads