// // Copyright (c) ZeroC, Inc. All rights reserved. // #ifndef ICE_GRID_CACHE_H #define ICE_GRID_CACHE_H #include #include #include namespace IceGrid { class SynchronizationCallback { public: virtual void synchronized() = 0; virtual void synchronized(std::exception_ptr) = 0; }; template class Cache { using ValueType = std::shared_ptr; using ValueMap = std::map; public: Cache() : _entriesHint(_entries.end()) { } virtual ~Cache() = default; bool has(const Key& key) const { std::lock_guard lock(_mutex); return getImpl(key) != nullptr; } void remove(const Key& key) { std::lock_guard lock(_mutex); removeImpl(key); } void setTraceLevels(const std::shared_ptr& traceLevels) { _traceLevels = traceLevels; } const std::shared_ptr& getTraceLevels() const { return _traceLevels; } protected: virtual ValueType getImpl(const Key& key) const { auto p = const_cast(_entries).end(); if(_entriesHint != p) { if(_entriesHint->first == key) { p = _entriesHint; } } if(p == const_cast(_entries).end()) { p = const_cast(_entries).find(key); } if(p != const_cast(_entries).end()) { const_cast(_entriesHint) = p; return p->second; } else { return nullptr; } } virtual ValueType addImpl(const Key& key, const ValueType& entry) { _entriesHint = _entries.insert(_entriesHint, { key, entry }); return entry; } virtual void removeImpl(const Key& key) { auto p = _entries.end(); if(_entriesHint != _entries.end()) { if(_entriesHint->first == key) { p = _entriesHint; } } if(p == _entries.end()) { p = _entries.find(key); } assert(p != _entries.end()); if(p->second->canRemove()) { _entries.erase(p); _entriesHint = _entries.end(); } else { _entriesHint = p; } } std::shared_ptr _traceLevels; ValueMap _entries; typename ValueMap::iterator _entriesHint; mutable std::mutex _mutex; std::condition_variable _condVar; }; template class CacheByString : public Cache { public: std::vector getAll(const std::string& expr) { std::lock_guard lock(Cache::_mutex); return getMatchingKeys>>(Cache::_entries, expr); } }; }; #endif