Skip to content
Snippets Groups Projects
Commit 8522e9ab authored by Vincent Texier's avatar Vincent Texier
Browse files

Improve graph efficiency by storing only pubkey of connected nodes

parent 9f708292
No related branches found
No related tags found
No related merge requests found
...@@ -7,7 +7,6 @@ from cutecoin.gui.views.wot import NODE_STATUS_HIGHLIGHTED, NODE_STATUS_OUT, ARC ...@@ -7,7 +7,6 @@ from cutecoin.gui.views.wot import NODE_STATUS_HIGHLIGHTED, NODE_STATUS_OUT, ARC
class Graph(dict): class Graph(dict):
def __init__(self, community): def __init__(self, community):
""" """
Init Graph instance Init Graph instance
...@@ -39,8 +38,8 @@ class Graph(dict): ...@@ -39,8 +38,8 @@ class Graph(dict):
if to_person.pubkey not in graph_tmp.keys(): if to_person.pubkey not in graph_tmp.keys():
# recursively feed graph searching for account node... # recursively feed graph searching for account node...
graph_tmp.explore_to_find_member(to_person, graph_tmp[from_person.pubkey]['nodes'], list()) graph_tmp.explore_to_find_member(to_person, graph_tmp[from_person.pubkey]['connected'], list())
if len(graph_tmp[from_person.pubkey]['nodes']) > 0: if len(graph_tmp[from_person.pubkey]['connected']) > 0:
# calculate path of nodes between person and to_person # calculate path of nodes between person and to_person
path = graph_tmp.find_shortest_path(graph_tmp[from_person.pubkey], graph_tmp[to_person.pubkey]) path = graph_tmp.find_shortest_path(graph_tmp[from_person.pubkey], graph_tmp[to_person.pubkey])
...@@ -51,20 +50,24 @@ class Graph(dict): ...@@ -51,20 +50,24 @@ class Graph(dict):
return path return path
def explore_to_find_member(self, person, nodes=None, done=None): def explore_to_find_member(self, person, connected=None, done=None):
""" """
Scan graph recursively to find person Scan graph recursively to find person
:param Person person: Person instance to find :param Person person: Person instance to find
:param list nodes: Optional, default=None, List of nodes around the person :param list connected: Optional, default=None, Pubkey list of the connected nodes
around the current scanned node
:param list done: Optional, default=None, List of node already scanned :param list done: Optional, default=None, List of node already scanned
:return: :return:
""" """
# functions keywords args are persistent... Need to reset it with None trick # functions keywords args are persistent... Need to reset it with None trick
nodes = nodes or (list() and (nodes is None)) connected = connected or (list() and (connected is None))
done = done or (list() and (done is None)) done = done or (list() and (done is None))
logging.debug("search %s in " % person.name) logging.debug("search %s in " % person.name)
logging.debug([node['text'] for node in nodes]) logging.debug([self[pubkey]['text'] for pubkey in connected])
for node in tuple(nodes): # for each pubkey connected...
for pubkey in tuple(connected):
# capture node connected
node = self[pubkey]
if node['id'] in tuple(done): if node['id'] in tuple(done):
continue continue
person_selected = Person(node['text'], node['id']) person_selected = Person(node['text'], node['id'])
...@@ -80,27 +83,29 @@ class Graph(dict): ...@@ -80,27 +83,29 @@ class Graph(dict):
done.append(node['id']) done.append(node['id'])
if len(done) >= len(self): if len(done) >= len(self):
return True return True
result = self.explore_to_find_member(person, self[person_selected.pubkey]['nodes'], done) result = self.explore_to_find_member(person, self[person_selected.pubkey]['connected'], done)
if not result: if not result:
return False return False
return True return True
def find_shortest_path(self, start, end, path=list()): def find_shortest_path(self, start, end, path=None):
""" """
Find recursively the shortest path between two nodes Find recursively the shortest path between two nodes
:param dict start: :param dict start: Start node
:param dict end: :param dict end: End node
:param list path: :param list path: Optional, default=None, List of nodes
:return: :return:
""" """
path = path or (list() and (path is None))
path = path + [start] path = path + [start]
if start['id'] == end['id']: if start['id'] == end['id']:
return path return path
if start['id'] not in self.keys(): if start['id'] not in self.keys():
return None return None
shortest = None shortest = None
for node in tuple(self[start['id']]['nodes']): for pubkey in tuple(self[start['id']]['connected']):
node = self[pubkey]
if node not in path: if node not in path:
newpath = self.find_shortest_path(node, end, path) newpath = self.find_shortest_path(node, end, path)
if newpath: if newpath:
...@@ -134,7 +139,7 @@ class Graph(dict): ...@@ -134,7 +139,7 @@ class Graph(dict):
'text': certifier['uid'], 'text': certifier['uid'],
'tooltip': certifier['pubkey'], 'tooltip': certifier['pubkey'],
'status': node_status, 'status': node_status,
'nodes': [self[person.pubkey]] 'connected': [person.pubkey]
} }
# keep only the latest certification # keep only the latest certification
...@@ -157,9 +162,9 @@ class Graph(dict): ...@@ -157,9 +162,9 @@ class Graph(dict):
# add arc to certifier # add arc to certifier
self[certifier['pubkey']]['arcs'].append(arc) self[certifier['pubkey']]['arcs'].append(arc)
# if certifier node not in person nodes # if certifier node not in person nodes
if self[certifier['pubkey']] not in tuple(self[person.pubkey]['nodes']): if certifier['pubkey'] not in tuple(self[person.pubkey]['connected']):
# add certifier node to person node # add certifier node to person node
self[person.pubkey]['nodes'].append(self[certifier['pubkey']]) self[person.pubkey]['connected'].append(certifier['pubkey'])
def add_certified_list(self, certified_list, person, person_account): def add_certified_list(self, certified_list, person, person_account):
""" """
...@@ -186,7 +191,7 @@ class Graph(dict): ...@@ -186,7 +191,7 @@ class Graph(dict):
'text': certified['uid'], 'text': certified['uid'],
'tooltip': certified['pubkey'], 'tooltip': certified['pubkey'],
'status': node_status, 'status': node_status,
'nodes': [self[person.pubkey]] 'connected': [person.pubkey]
} }
# display validity status # display validity status
if (time.time() - certified['cert_time']['medianTime']) > self.ARC_STATUS_STRONG_time: if (time.time() - certified['cert_time']['medianTime']) > self.ARC_STATUS_STRONG_time:
...@@ -219,27 +224,28 @@ class Graph(dict): ...@@ -219,27 +224,28 @@ class Graph(dict):
# add arc in graph # add arc in graph
self[person.pubkey]['arcs'].append(arc) self[person.pubkey]['arcs'].append(arc)
# if certified node not in person nodes # if certified node not in person nodes
if self[certified['pubkey']] not in tuple(self[person.pubkey]['nodes']): if certified['pubkey'] not in tuple(self[person.pubkey]['connected']):
# add certified node to person node # add certified node to person node
self[person.pubkey]['nodes'].append(self[certified['pubkey']]) self[person.pubkey]['connected'].append(certified['pubkey'])
def add_person(self, person, status=0, arcs=None, nodes=None): def add_person(self, person, status=None, arcs=None, connected=None):
""" """
Add person as a new node in graph Add person as a new node in graph
:param Person person: Person instance :param Person person: Person instance
:param int status: Node status (see cutecoin.gui.views.wot) :param int status: Optional, default=None, Node status (see cutecoin.gui.views.wot)
:param list arcs: List of arcs (certified by person) :param list arcs: Optional, default=None, List of arcs (certified by person)
:param list nodes: List of nodes around person :param list connected: Optional, default=None, Public key list of the connected nodes around the person
:return: :return:
""" """
# functions keywords args are persistent... Need to reset it with None trick # functions keywords args are persistent... Need to reset it with None trick
status = status or (0 and (status is None))
arcs = arcs or (list() and (arcs is None)) arcs = arcs or (list() and (arcs is None))
nodes = nodes or (list() and (nodes is None)) connected = connected or (list() and (connected is None))
self[person.pubkey] = { self[person.pubkey] = {
'id': person.pubkey, 'id': person.pubkey,
'arcs': arcs, 'arcs': arcs,
'text': person.name, 'text': person.name,
'tooltip': person.pubkey, 'tooltip': person.pubkey,
'status': status, 'status': status,
'nodes': nodes 'connected': connected
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment