Bläddra i källkod

Node dictionaries are also cached now

Yentl Van Tendeloo 8 år sedan
förälder
incheckning
8c035f3fe8
1 ändrade filer med 34 tillägg och 6 borttagningar
  1. 34 6
      state/modelverse_state/main.py

+ 34 - 6
state/modelverse_state/main.py

@@ -34,6 +34,7 @@ class ModelverseState(object):
         self.to_delete = set()
 
         self.cache = {}
+        self.cache_node = {}
 
         if bootfile is not None:
             self.root = self.parse(bootfile)
@@ -174,6 +175,7 @@ class ModelverseState(object):
         e = self.create_edge(source, destination)[0]
         self.create_edge(e, n)
         self.cache.setdefault(source, {})[data] = e
+        self.cache_node.setdefault(source, {})[n] = e
         return (None, status.SUCCESS)
 
     def read_value(self, node):
@@ -297,19 +299,31 @@ class ModelverseState(object):
             return (None, status.FAIL_RDICTE_NOT_FOUND)
 
     def read_dict_node(self, node, value_node):
+        try:
+            first = self.cache_node[node][value_node]
+            # Got hit, so validate
+            if (self.edges[first][0] == node) and \
+                (len(self.outgoing[first]) == 1) and \
+                (self.edges[list(self.outgoing[first])[0]][1] == value_node):
+                return (self.edges[first][1], status.SUCCESS)
+            # Hit but invalid now
+            del self.cache_node[node][value_node]
+        except KeyError:
+            # Didn't exist
+            pass
+
         e, s = self.read_dict_node_edge(node, value_node)
+
         if s != status.SUCCESS:
             return (None, {status.FAIL_RDICTNE_UNKNOWN: status.FAIL_RDICTN_UNKNOWN,
                            status.FAIL_RDICTNE_UNCERTAIN: status.FAIL_RDICTN_UNCERTAIN,
                            status.FAIL_RDICTNE_AMBIGUOUS: status.FAIL_RDICTN_AMBIGUOUS,
                            status.FAIL_RDICTNE_OOB: status.FAIL_RDICTN_OOB,
                            status.FAIL_RDICTNE_NOT_FOUND: status.FAIL_RDICTN_NOT_FOUND}[s])
+        self.cache_node.setdefault(node, {})[value_node] = e
         return (self.edges[e][1], status.SUCCESS)
 
     def read_dict_node_edge(self, node, value_node):
-        if node not in self.nodes and node not in self.edges:
-            return (None, status.FAIL_RDICTNE_UNKNOWN)
-
         # Get all outgoing links
         found = None
         if node in self.outgoing:
@@ -325,8 +339,11 @@ class ModelverseState(object):
                                 print("Duplicate key on node: %s (%s <-> %s)!" % (value_node, found, e1))
                                 return (None, status.FAIL_RDICTNE_AMBIGUOUS)
                             found = e1
+
         if found is not None:
             return (found, status.SUCCESS)
+        elif node not in self.nodes and node not in self.edges:
+            return (None, status.FAIL_RDICTNE_UNKNOWN)
         else:
             return (None, status.FAIL_RDICTNE_NOT_FOUND)
 
@@ -365,9 +382,6 @@ class ModelverseState(object):
 
         self.nodes.remove(node)
 
-        if node in self.cache:
-            del self.cache[node]
-
         if node in self.values:
             del self.values[node]
 
@@ -451,6 +465,20 @@ class ModelverseState(object):
                 if elem in self.incoming:
                     visit_list.extend(self.incoming[elem])
 
+        dset = set()
+        for key in self.cache:
+            if key not in self.nodes and key not in self.edges:
+                dset.add(key)
+        for key in dset:
+            del self.cache[key]
+
+        dset = set()
+        for key in self.cache_node:
+            if key not in self.nodes and key not in self.edges:
+                dset.add(key)
+        for key in dset:
+            del self.cache_node[key]
+
         # All remaining elements are to be purged
         if len(values) > 0:
             while values: