// ================================================================================================= // This file is part of the CLBlast project. The project is licensed under Apache Version 2.0. This // project loosely follows the Google C++ styleguide and uses a tab-size of two spaces and a max- // width of 100 characters per line. // // Author(s): // Cedric Nugteren // // This file implements the caching functionality of compiled binaries and programs. // // ================================================================================================= #include #include #include #include "database/database.hpp" #include "cache.hpp" namespace clblast { // ================================================================================================= template template Value Cache::Get(const U &key, bool *in_cache) const { std::lock_guard lock(cache_mutex_); #if __cplusplus >= 201402L // generalized std::map::find() of C++14 auto it = cache_.find(key); #else // O(n) lookup in a vector auto it = std::find_if(cache_.begin(), cache_.end(), [&] (const std::pair &pair) { return pair.first == key; }); #endif if (it == cache_.end()) { if (in_cache) { *in_cache = false; } return Value(); } if (in_cache) { *in_cache = true; } return it->second; } template void Cache::Store(Key &&key, Value &&value) { std::lock_guard lock(cache_mutex_); #if __cplusplus >= 201402L // emplace() into a map auto r = cache_.emplace(std::move(key), std::move(value)); if (!r.second) { throw LogicError("Cache::Store: object already in cache"); } #else // emplace_back() into a vector cache_.emplace_back(std::move(key), std::move(value)); #endif } template void Cache::Remove(const Key &key) { std::lock_guard lock(cache_mutex_); #if __cplusplus >= 201402L cache_.erase(key); #else auto it = cache_.begin(); while (it != cache_.end()) { if ((*it).first == key) { it = cache_.erase(it); } else ++it; } #endif } template template void Cache::RemoveBySubset(const Key &key) { std::lock_guard lock(cache_mutex_); auto it = cache_.begin(); while (it != cache_.end()) { const auto current_key = (*it).first; if ((std::get(key) == std::get(current_key)) && (std::get(key) == std::get(current_key))) { it = cache_.erase(it); } else ++it; } } template void Cache::Invalidate() { std::lock_guard lock(cache_mutex_); cache_.clear(); } template Cache &Cache::Instance() { return instance_; } template Cache Cache::instance_; // ================================================================================================= template class Cache; template std::string BinaryCache::Get(const BinaryKeyRef &, bool *) const; // ================================================================================================= template class Cache>; template std::shared_ptr ProgramCache::Get(const ProgramKeyRef &, bool *) const; template void ProgramCache::RemoveBySubset<1, 2>(const ProgramKey &); // precision and routine name // ================================================================================================= template class Cache; template Database DatabaseCache::Get(const DatabaseKeyRef &, bool *) const; // ================================================================================================= } // namespace clblast