From 1fc5fb437bba620bad623eace1263caf1854d115 Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Mon, 17 Aug 2015 10:48:12 -0400 Subject: [PATCH] TreeModel path cache: clear path cache when data changes... * Allow to disable by setting interface.treemodel-cache-size to 0 * Protection if mode/view gets different --- gramps/gui/views/treemodels/basemodel.py | 15 +++++++++++--- gramps/gui/views/treemodels/lru.py | 7 ++++++- gramps/gui/views/treemodels/treebasemodel.py | 21 ++++++++++++++------ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/gramps/gui/views/treemodels/basemodel.py b/gramps/gui/views/treemodels/basemodel.py index 7bf17e844..598178206 100644 --- a/gramps/gui/views/treemodels/basemodel.py +++ b/gramps/gui/views/treemodels/basemodel.py @@ -63,7 +63,9 @@ class BaseModel(object): or a name (special value used by view). """ if handle in self.lru_data and col in self.lru_data[handle]: + #print("hit", handle, col) return (True, self.lru_data[handle][col]) + #print("MISS", handle, col) return (False, None) def set_cached_value(self, handle, col, data): @@ -71,9 +73,10 @@ class BaseModel(object): Set the data associated with handle + col. """ if not self._in_build: - if handle not in self.lru_data: - self.lru_data[handle] = {} - self.lru_data[handle][col] = data + if self.lru_data.count > 0: + if handle not in self.lru_data: + self.lru_data[handle] = {} + self.lru_data[handle][col] = data ## Cached Path's for TreeView: def get_cached_path(self, handle): @@ -90,3 +93,9 @@ class BaseModel(object): """ if not self._in_build: self.lru_path[handle] = path + + def clear_path_cache(self): + """ + Clear path cache for all. + """ + self.lru_path.clear() diff --git a/gramps/gui/views/treemodels/lru.py b/gramps/gui/views/treemodels/lru.py index 95a84c2d9..1c93c212e 100644 --- a/gramps/gui/views/treemodels/lru.py +++ b/gramps/gui/views/treemodels/lru.py @@ -39,7 +39,10 @@ class LRU(object): Implementation of a length-limited O(1) LRU cache """ def __init__(self, count): - self.count = max(count, 2) + """ + Set count to 0 or 1 to disable. + """ + self.count = count self.data = {} self.first = None self.last = None @@ -60,6 +63,8 @@ class LRU(object): """ Set the item in the LRU, removing an old entry if needed """ + if self.count <= 1: # Disabled + return if obj in self.data: del self[obj] nobj = Node(self.last, (obj, val)) diff --git a/gramps/gui/views/treemodels/treebasemodel.py b/gramps/gui/views/treemodels/treebasemodel.py index 6b3f1590c..68e5ad2d6 100644 --- a/gramps/gui/views/treemodels/treebasemodel.py +++ b/gramps/gui/views/treemodels/treebasemodel.py @@ -409,6 +409,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel): """ Clear the data map. """ + self.clear_cache() self.tree.clear() self.handle2node.clear() self.stamp += 1 @@ -618,6 +619,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel): add_parent Bool, if True, check if parent is present, if not add the parent as a top group with no handle """ + self.clear_path_cache() if add_parent and not (parent in self.tree): #add parent to self.tree as a node with no handle, as the first #group level @@ -668,6 +670,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel): """ Remove a node from the map. """ + self.clear_path_cache() if node.children: del self.handle2node[node.handle] node.set_handle(None) @@ -694,6 +697,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel): rows_reordered, so to propagate the change to the view, you need to reattach the model to the view. """ + self.clear_path_cache() self.__reverse = not self.__reverse top_node = self.tree[None] self._reverse_level(top_node) @@ -729,16 +733,17 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel): def add_row(self, handle, data): """ - Add a row to the model. In general this will add more then one node by + Add a row to the model. In general this will add more than one node by using the add_node method. """ - raise NotImplementedError + self.clear_path_cache() def add_row_by_handle(self, handle): """ Add a row to the model. """ assert isinstance(handle, str) + self.clear_path_cache() if self._get_node(handle) is not None: return # row already exists cput = time.clock() @@ -763,11 +768,11 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel): """ assert isinstance(handle, str) cput = time.clock() + self.clear_cache(handle) node = self._get_node(handle) if node is None: return # row not currently displayed - self.clear_cache(handle) parent = self.nodemap.node(node.parent) self.remove_node(node) @@ -793,6 +798,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel): Update a row in the model. """ assert isinstance(handle, str) + self.clear_cache(handle) if self._get_node(handle) is None: return # row not currently displayed @@ -956,9 +962,12 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel): pathlist = path.get_indices() for index in pathlist: _index = (-index - 1) if self.__reverse else index - if len(node.children[_index]) > 0: - node = self.nodemap.node(node.children[_index][1]) - else: + try: + if len(node.children[_index]) > 0: + node = self.nodemap.node(node.children[_index][1]) + else: + return False, Gtk.TreeIter() + except IndexError: return False, Gtk.TreeIter() return True, self._get_iter(node)