|
@@ -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:
|