[geary/mjog/lru-crash-3-34] Replace use of Gee.TreeSet in Util.Cache.Lru



commit faaf3ae77ad55bc236a34d38b150d9b055441cb4
Author: Michael Gratton <mike vee net>
Date:   Wed Nov 20 12:28:37 2019 +1100

    Replace use of Gee.TreeSet in Util.Cache.Lru
    
    We're getting crashes (#398, #609) in Gee.TreeSet for the LRU cache when
    removing values to update the last used time for an existing cache.
    Since Gee isn't currently being activaly maintained, replace use of
    that class with something else.

 src/client/util/util-cache.vala | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)
---
diff --git a/src/client/util/util-cache.vala b/src/client/util/util-cache.vala
index ffc0a41b..44097d89 100644
--- a/src/client/util/util-cache.vala
+++ b/src/client/util/util-cache.vala
@@ -47,8 +47,8 @@ public class Util.Cache.Lru<T> : Geary.BaseObject {
 
     private Gee.Map<string,CacheEntry<T>> cache =
         new Gee.HashMap<string,CacheEntry<T>>();
-    private Gee.SortedSet<CacheEntry<T>> ordering =
-        new Gee.TreeSet<CacheEntry<T>>(CacheEntry.lru_compare);
+    private GLib.Sequence<CacheEntry<T>> ordering =
+        new GLib.Sequence<CacheEntry<T>>();
 
 
     /**
@@ -76,13 +76,15 @@ public class Util.Cache.Lru<T> : Geary.BaseObject {
         int64 now = GLib.get_monotonic_time();
         CacheEntry<T> entry = new CacheEntry<T>(key, value, now);
         this.cache.set(key, entry);
-        this.ordering.add(entry);
+        this.ordering.append(entry);
 
         // Prune if needed
         if (this.cache.size > this.max_size) {
-            CacheEntry oldest = this.ordering.first();
-            this.cache.unset(oldest.key);
-            this.ordering.remove(oldest);
+            var oldest = this.ordering.get_begin_iter();
+            if (oldest != null) {
+                this.cache.unset(oldest.get().key);
+                oldest.remove();
+            }
         }
     }
 
@@ -101,9 +103,12 @@ public class Util.Cache.Lru<T> : Geary.BaseObject {
             // Need to remove the entry from the ordering before
             // updating the last used time since doing so changes the
             // ordering
-            this.ordering.remove(entry);
+            var to_remove = this.ordering.lookup(entry, CacheEntry.lru_compare);
+            if (to_remove != null) {
+                to_remove.remove();
+            }
             entry.last_used = now;
-            this.ordering.add(entry);
+            this.ordering.append(entry);
         }
         return value;
     }
@@ -114,7 +119,10 @@ public class Util.Cache.Lru<T> : Geary.BaseObject {
         T value = null;
         this.cache.unset(key, out entry);
         if (entry != null) {
-            this.ordering.remove(entry);
+            var to_remove = this.ordering.lookup(entry, CacheEntry.lru_compare);
+            if (to_remove != null) {
+                to_remove.remove();
+            }
             value = entry.value;
         }
         return value;
@@ -123,7 +131,12 @@ public class Util.Cache.Lru<T> : Geary.BaseObject {
     /** Evicts all entries in the cache. */
     public void clear() {
         this.cache.clear();
-        this.ordering.clear();
+
+        var first = this.ordering.get_begin_iter();
+        if (first != null) {
+            var last = this.ordering.get_end_iter();
+            first.remove_range(last);
+        }
     }
 
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]