From b02b5b055f96843579fd054e4eafe36607058a50 Mon Sep 17 00:00:00 2001 From: vng Date: Thu, 18 Oct 2012 02:18:23 +0300 Subject: [PATCH] Add storage::CountryInfoGetter::ClearCaches. --- base/cache.hpp | 35 ++++++++++++++++++++++++----------- storage/country_info.cpp | 19 +++++++++++++++++++ storage/country_info.hpp | 3 +++ 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/base/cache.hpp b/base/cache.hpp index 7787236cda..b792fd0333 100644 --- a/base/cache.hpp +++ b/base/cache.hpp @@ -21,14 +21,12 @@ namespace my STATIC_ASSERT((is_same::value || is_same::value)); - CHECK_GREATER ( logCacheSize, 0, () ); - CHECK_GREATER ( m_HashMask, 0, () ); - CHECK_LESS(logCacheSize, 32, ()); + // We always use cache with static constant. So debug assert is enough here. + ASSERT_GREATER ( logCacheSize, 0, () ); + ASSERT_GREATER ( m_HashMask, 0, () ); + ASSERT_LESS(logCacheSize, 32, ()); - uint32_t const cacheSize = 1 << logCacheSize; - // Initialize m_Cache such, that (Hash(m_Cache[i].m_Key) & m_HashMask) != i. - for (uint32_t i = 0; i < cacheSize; ++i) - for (m_Cache[i].m_Key = 0; (Hash(m_Cache[i].m_Key) & m_HashMask) == i; ++m_Cache[i].m_Key) ; + Reset(); } ~Cache() @@ -47,7 +45,7 @@ namespace my // TODO: Return pair instead? ValueT & Find(KeyT const & key, bool & found) { - Data & data = m_Cache[Hash(key) & m_HashMask]; + Data & data = m_Cache[Index(key)]; if (data.m_Key == key) { found = true; @@ -60,10 +58,10 @@ namespace my return data.m_Value; } - bool HasKey(KeyT const & key) + bool HasKey(KeyT const & key) const { - Data & data = m_Cache[Hash(key) & m_HashMask]; - return data.m_Key == key; + Data const & data = m_Cache[Index(key)]; + return (data.m_Key == key); } template @@ -73,7 +71,22 @@ namespace my f(m_Cache[i].m_Value); } + void Reset() + { + // Initialize m_Cache such, that Index(m_Cache[i].m_Key) != i. + for (uint32_t i = 0; i <= m_HashMask; ++i) + { + KeyT & key = m_Cache[i].m_Key; + for (key = 0; Index(key) == i; ++key) ; + } + } + private: + inline size_t Index(KeyT const & key) const + { + return static_cast(Hash(key) & m_HashMask); + } + inline static uint32_t Hash(uint32_t x) { x = (x ^ 61) ^ (x >> 16); diff --git a/storage/country_info.cpp b/storage/country_info.cpp index 2ca2f6eae2..219c7517f3 100644 --- a/storage/country_info.cpp +++ b/storage/country_info.cpp @@ -227,4 +227,23 @@ namespace storage return false; } + +namespace +{ + class DoFreeCacheMemory + { + public: + void operator() (vector & v) const + { + vector emptyV; + emptyV.swap(v); + } + }; +} + + void CountryInfoGetter::ClearCaches() const + { + m_cache.ForEachValue(DoFreeCacheMemory()); + m_cache.Reset(); + } } diff --git a/storage/country_info.hpp b/storage/country_info.hpp index 3cbedcabb0..0297fcfc1b 100644 --- a/storage/country_info.hpp +++ b/storage/country_info.hpp @@ -76,5 +76,8 @@ namespace storage void GetMatchedRegions(string const & enName, IDSet & regions) const; bool IsBelongToRegion(m2::PointD const & pt, IDSet const & regions) const; //@} + + /// m_cache is mutable. + void ClearCaches() const; }; }