From 0de46cca47e48bd74c4cbf0a9b025f001549426d Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Tue, 6 Aug 2019 22:22:35 +0100
Subject: [PATCH] ENH: Cache has an lru option

---
 fsl/utils/cache.py | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/fsl/utils/cache.py b/fsl/utils/cache.py
index 5a89817d9..e8de25aa1 100644
--- a/fsl/utils/cache.py
+++ b/fsl/utils/cache.py
@@ -42,14 +42,20 @@ class Cache(object):
          raised.
     """
 
-    def __init__(self, maxsize=100):
+    def __init__(self, maxsize=100, lru=False):
         """Create a ``Cache``.
 
         :arg maxsize: Maximum number of items allowed in the ``Cache`` before
                       it starts dropping old items
+
+        :arg lru:     (least recently used) If ``False`` (the default), items
+                      are dropped according to their insertion time. Otherwise,
+                      items are dropped according to their most recent access
+                      time.
         """
         self.__cache   = collections.OrderedDict()
         self.__maxsize = maxsize
+        self.__lru     = lru
 
 
     def put(self, key, value, expiry=0):
@@ -94,14 +100,26 @@ class Cache(object):
         else:
             entry = self.__cache[key]
 
+        # Check to see if the entry
+        # has expired
+        now = time.time()
+
         if entry.expiry > 0:
-            if time.time() - entry.storetime > entry.expiry:
+            if now - entry.storetime > entry.expiry:
 
                 self.__cache.pop(key)
 
                 if defaultSpecified: return default
                 else:                raise Expired(key)
 
+        # If we are an lru cache, update
+        # this entry's expiry, and update
+        # its order in the cache dict
+        if self.__lru:
+            entry.storetime = now
+            self.__cache.pop(key)
+            self.__cache[key] = entry
+
         return entry.value
 
 
@@ -134,7 +152,7 @@ class Cache(object):
                     - ``True`` if a default argument was specified, ``False``
                       otherwise.
 
-                    - The specifeid default value, or ``None`` if it wasn't
+                    - The specified default value, or ``None`` if it wasn't
                       specified.
         """
 
-- 
GitLab