[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - include/o3tl

Tomaž Vajngerl (via logerrit) logerrit at kemper.freedesktop.org
Thu May 23 11:28:49 UTC 2019


 include/o3tl/lru_map.hxx |   45 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 8 deletions(-)

New commits:
commit bf57afed15faa88a139dbd99ebf362647eb183b4
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Thu May 23 17:38:53 2019 +0900
Commit:     Tor Lillqvist <tml at collabora.com>
CommitDate: Thu May 23 13:28:02 2019 +0200

    bring lru_map to the latest (needed by widget draw cache)
    
    lru_map in master has been fixed in various (unrelated) commits.
    This brings it to the same state as it is in master as this is
    needed for the widget draw images and draw command cache. Without
    this the cache never hits and this will impact performance.
    
    Change-Id: If02eff899aa782df68d16a8b6995a59d822f5643
    Reviewed-on: https://gerrit.libreoffice.org/72822
    Reviewed-by: Tor Lillqvist <tml at collabora.com>
    Tested-by: Tor Lillqvist <tml at collabora.com>

diff --git a/include/o3tl/lru_map.hxx b/include/o3tl/lru_map.hxx
index 53b5d5c8d004..aeb27378d96a 100644
--- a/include/o3tl/lru_map.hxx
+++ b/include/o3tl/lru_map.hxx
@@ -30,16 +30,18 @@ namespace o3tl
  * for most of the operations with a combination unordered map and linked list.
  *
  **/
-template<typename Key, typename Value, class KeyHash = std::hash<Key>>
+template<typename Key, typename Value, class KeyHash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
 class lru_map final
 {
-private:
+public:
     typedef typename std::pair<Key, Value> key_value_pair_t;
+
+private:
     typedef std::list<key_value_pair_t> list_t;
     typedef typename list_t::iterator list_iterator_t;
     typedef typename list_t::const_iterator list_const_iterator_t;
 
-    typedef std::unordered_map<Key, list_iterator_t, KeyHash> map_t;
+    typedef std::unordered_map<Key, list_iterator_t, KeyHash, KeyEqual> map_t;
     typedef typename map_t::iterator map_iterator_t;
     typedef typename map_t::const_iterator map_const_iterator_t;
 
@@ -57,12 +59,14 @@ private:
             mLruList.pop_back();
         }
     }
+
 public:
     typedef list_iterator_t iterator;
     typedef list_const_iterator_t const_iterator;
 
+    // a size of 0 effectively disables the LRU cleanup code
     lru_map(size_t nMaxSize)
-        : mMaxSize(nMaxSize)
+        : mMaxSize(nMaxSize ? nMaxSize : std::min(mLruMap.max_size(), mLruList.max_size()))
     {}
 
     void insert(key_value_pair_t& rPair)
@@ -74,7 +78,8 @@ public:
             // add to front of the list
             mLruList.push_front(rPair);
             // add the list position (iterator) to the map
-            mLruMap[rPair.first] = mLruList.begin();
+            auto it = mLruList.begin();
+            mLruMap[it->first] = it;
             checkLRU();
         }
         else // already exists -> replace value
@@ -95,7 +100,8 @@ public:
             // add to front of the list
             mLruList.push_front(std::move(rPair));
             // add the list position (iterator) to the map
-            mLruMap[rPair.first] = mLruList.begin();
+            auto it = mLruList.begin();
+            mLruMap[it->first] = it;
             checkLRU();
         }
         else // already exists -> replace value
@@ -123,14 +129,37 @@ public:
         }
     }
 
+    // reverse-iterates the list removing all items matching the predicate
+    template<class UnaryPredicate>
+    void remove_if(UnaryPredicate pred)
+    {
+        auto it = mLruList.rbegin();
+        while (it != mLruList.rend())
+        {
+            if (pred(*it))
+            {
+                mLruMap.erase(it->first);
+                it = decltype(it){ mLruList.erase(std::next(it).base()) };
+            }
+            else
+                ++it;
+        }
+    }
+
+    const list_const_iterator_t begin() const
+    {
+        return mLruList.cbegin();
+    }
+
     const list_const_iterator_t end() const
     {
-        return mLruList.end();
+        return mLruList.cend();
     }
 
     size_t size() const
     {
-        return mLruList.size();
+        assert(mLruMap.size() == mLruList.size());
+        return mLruMap.size();
     }
 
     void clear()


More information about the Libreoffice-commits mailing list