[hdf-compass] 76/295: Add tile-based LRU cache to Array viewer

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Sun May 8 10:35:28 UTC 2016


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch debian/master
in repository hdf-compass.

commit 797d48dca3490b98243a34e220cf88e10a2c2f99
Author: Andrew Collette <andrew.collette at gmail.com>
Date:   Thu May 7 22:59:38 2015 -0600

    Add tile-based LRU cache to Array viewer
---
 compass_viewer/array/__init__.py | 66 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 63 insertions(+), 3 deletions(-)

diff --git a/compass_viewer/array/__init__.py b/compass_viewer/array/__init__.py
index f37af2c..bfd52dd 100644
--- a/compass_viewer/array/__init__.py
+++ b/compass_viewer/array/__init__.py
@@ -263,6 +263,65 @@ class ArrayGrid(wx.grid.Grid):
         self.SetSelectionMode(selmode)
 
 
+class LRUTileCache(object):
+
+    """
+        Simple tile-based LRU cache which goes between the Grid and
+        the Array object.  Caches tiles along the last 1 or 2 dimensions
+        of a dataset.
+        
+        Access is via __getitem__.  Because this class exists specifically
+        to support point-based callbacks for the Grid, arguments may
+        only be indices, not slices.
+    """
+    
+    TILESIZE = 100  # Tiles will have shape (100,) or (100, 100)
+    MAXTILES = 50   # Max number of tiles to retain in the cache
+    
+    def __init__(self, arr):
+        """ *arr* is anything implementing compass_model.Array """
+        import collections
+        self.cache = collections.OrderedDict()
+        self.arr = arr
+        
+    def __getitem__(self, args):
+        """ Restricted to an index or tuple of indices. """
+        
+        if not isinstance(args, tuple):
+            args = (args,)
+            
+        # Split off the last 1 or 2 dimensions
+        coarse_position, fine_position = args[0:-2], args[-2:]
+        
+        def clip(x):
+            """ Round down to nearest TILESIZE; takes e.g. 181 -> 100 """
+            return (x//self.TILESIZE)*self.TILESIZE
+            
+        # Tuple with index of tile corner
+        tile_key = coarse_position + tuple(clip(x) for x in fine_position)
+        
+        # Slice which will be applied to dataset to retrieve tile
+        tile_slice = coarse_position + tuple(slice(clip(x), clip(x)+self.TILESIZE) for x in fine_position)
+        
+        # Index applied to tile to retrieve the desired data point
+        tile_data_index = tuple(x%self.TILESIZE for x in fine_position)
+        
+        # Case 1: Add tile to cache, ejecting oldest tile if needed
+        if not tile_key in self.cache:
+        
+            if len(self.cache) >= self.MAXTILES:
+                self.cache.popitem(last=False)
+                
+            tile = self.arr[tile_slice]
+            self.cache[tile_key] = tile
+
+        # Case 2: Mark the tile as recently accessed            
+        else:
+            tile = self.cache.pop(tile_key)
+            self.cache[tile_key] = tile
+            
+        return tile[tile_data_index]
+        
 
 class ArrayTable(wx.grid.PyGridTableBase):
 
@@ -288,7 +347,8 @@ class ArrayTable(wx.grid.PyGridTableBase):
         self.rank = len(node.shape)
         self.names = node.dtype.names
 
-
+        self.cache = LRUTileCache(self.node)
+        
     def GetNumberRows(self):
         """ Callback for number of rows displayed by the grid control """
         if self.rank == 0:
@@ -322,7 +382,7 @@ class ArrayTable(wx.grid.PyGridTableBase):
 
         # 1D case
         if self.rank == 1:
-            data = self.node[row]
+            data = self.cache[row]
             if self.names is None:
                 return data
             return data[self.names[col]]
@@ -333,7 +393,7 @@ class ArrayTable(wx.grid.PyGridTableBase):
         else:
             args = self.slicer.indices + (row,)
 
-        data = self.node[args]
+        data = self.cache[args]
         if self.names is None:
             return data
         return data[self.names[col]]

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/hdf-compass.git



More information about the debian-science-commits mailing list