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
This commit is contained in:
Doug Blank 2015-08-17 10:48:12 -04:00
parent 269a1ab6f5
commit 1fc5fb437b
3 changed files with 33 additions and 10 deletions

View File

@ -63,7 +63,9 @@ class BaseModel(object):
or a name (special value used by view). or a name (special value used by view).
""" """
if handle in self.lru_data and col in self.lru_data[handle]: if handle in self.lru_data and col in self.lru_data[handle]:
#print("hit", handle, col)
return (True, self.lru_data[handle][col]) return (True, self.lru_data[handle][col])
#print("MISS", handle, col)
return (False, None) return (False, None)
def set_cached_value(self, handle, col, data): def set_cached_value(self, handle, col, data):
@ -71,9 +73,10 @@ class BaseModel(object):
Set the data associated with handle + col. Set the data associated with handle + col.
""" """
if not self._in_build: if not self._in_build:
if handle not in self.lru_data: if self.lru_data.count > 0:
self.lru_data[handle] = {} if handle not in self.lru_data:
self.lru_data[handle][col] = data self.lru_data[handle] = {}
self.lru_data[handle][col] = data
## Cached Path's for TreeView: ## Cached Path's for TreeView:
def get_cached_path(self, handle): def get_cached_path(self, handle):
@ -90,3 +93,9 @@ class BaseModel(object):
""" """
if not self._in_build: if not self._in_build:
self.lru_path[handle] = path self.lru_path[handle] = path
def clear_path_cache(self):
"""
Clear path cache for all.
"""
self.lru_path.clear()

View File

@ -39,7 +39,10 @@ class LRU(object):
Implementation of a length-limited O(1) LRU cache Implementation of a length-limited O(1) LRU cache
""" """
def __init__(self, count): def __init__(self, count):
self.count = max(count, 2) """
Set count to 0 or 1 to disable.
"""
self.count = count
self.data = {} self.data = {}
self.first = None self.first = None
self.last = None self.last = None
@ -60,6 +63,8 @@ class LRU(object):
""" """
Set the item in the LRU, removing an old entry if needed Set the item in the LRU, removing an old entry if needed
""" """
if self.count <= 1: # Disabled
return
if obj in self.data: if obj in self.data:
del self[obj] del self[obj]
nobj = Node(self.last, (obj, val)) nobj = Node(self.last, (obj, val))

View File

@ -409,6 +409,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
""" """
Clear the data map. Clear the data map.
""" """
self.clear_cache()
self.tree.clear() self.tree.clear()
self.handle2node.clear() self.handle2node.clear()
self.stamp += 1 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 add_parent Bool, if True, check if parent is present, if not add the
parent as a top group with no handle parent as a top group with no handle
""" """
self.clear_path_cache()
if add_parent and not (parent in self.tree): if add_parent and not (parent in self.tree):
#add parent to self.tree as a node with no handle, as the first #add parent to self.tree as a node with no handle, as the first
#group level #group level
@ -668,6 +670,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
""" """
Remove a node from the map. Remove a node from the map.
""" """
self.clear_path_cache()
if node.children: if node.children:
del self.handle2node[node.handle] del self.handle2node[node.handle]
node.set_handle(None) 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 rows_reordered, so to propagate the change to the view, you need to
reattach the model to the view. reattach the model to the view.
""" """
self.clear_path_cache()
self.__reverse = not self.__reverse self.__reverse = not self.__reverse
top_node = self.tree[None] top_node = self.tree[None]
self._reverse_level(top_node) self._reverse_level(top_node)
@ -729,16 +733,17 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
def add_row(self, handle, data): 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. using the add_node method.
""" """
raise NotImplementedError self.clear_path_cache()
def add_row_by_handle(self, handle): def add_row_by_handle(self, handle):
""" """
Add a row to the model. Add a row to the model.
""" """
assert isinstance(handle, str) assert isinstance(handle, str)
self.clear_path_cache()
if self._get_node(handle) is not None: if self._get_node(handle) is not None:
return # row already exists return # row already exists
cput = time.clock() cput = time.clock()
@ -763,11 +768,11 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
""" """
assert isinstance(handle, str) assert isinstance(handle, str)
cput = time.clock() cput = time.clock()
self.clear_cache(handle)
node = self._get_node(handle) node = self._get_node(handle)
if node is None: if node is None:
return # row not currently displayed return # row not currently displayed
self.clear_cache(handle)
parent = self.nodemap.node(node.parent) parent = self.nodemap.node(node.parent)
self.remove_node(node) self.remove_node(node)
@ -793,6 +798,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
Update a row in the model. Update a row in the model.
""" """
assert isinstance(handle, str) assert isinstance(handle, str)
self.clear_cache(handle)
if self._get_node(handle) is None: if self._get_node(handle) is None:
return # row not currently displayed return # row not currently displayed
@ -956,9 +962,12 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
pathlist = path.get_indices() pathlist = path.get_indices()
for index in pathlist: for index in pathlist:
_index = (-index - 1) if self.__reverse else index _index = (-index - 1) if self.__reverse else index
if len(node.children[_index]) > 0: try:
node = self.nodemap.node(node.children[_index][1]) if len(node.children[_index]) > 0:
else: node = self.nodemap.node(node.children[_index][1])
else:
return False, Gtk.TreeIter()
except IndexError:
return False, Gtk.TreeIter() return False, Gtk.TreeIter()
return True, self._get_iter(node) return True, self._get_iter(node)