Module gundb.backends.graph
The Graph module manages a graph of nodes and applies put requests on these nodes in dfs order.
A node represents a soul in the sent graph.
Source code
"""
The Graph module manages a graph of nodes and applies put requests on these nodes in dfs order.
A node represents a soul in the sent graph.
"""
from .resolvers import *
import json
from ..consts import *
class PutRequest:
"""
PutRequst contains data about a pull request that is dispatched later using dispatch method.
Args:
soul (str) : The soul to which the change is applied.
key (str) : The key of the property in the soul object.
value (str) : The new value associated with the key
state (dict): The state.
graph (dict): The updated graph sent by gundb.
"""
def __init__(self, soul, key, value, state, graph):
self.soul = soul
self.key = key
self.value = value
self.state = state
self.graph = graph
def dispatch(self, func):
"""
Calls the sent function with self attributes as arguments.
"""
func(self.soul, self.key, self.value, self.state, self.graph)
def node_added(self, node_resolver):
"""
Returns the node object that is added as a result of this put request.
Args:
node_resolver (dict): A mapping between souls and node objects.
"""
assert(isinstance(self.value, dict) and '#' in self.value)
return node_resolver[self.value['#']]
def node_removed(self, node_resolver):
"""
Returns the node object that is deleted as a result of this put request.
Args:
node_resolver (dict): A mapping between souls and node objects.
"""
if self.key in self.graph[self.soul] and is_reference(self.graph[self.soul][self.key]):
return node_resolver[self.graph[self.soul][self.key]['#']]
else:
return None
class Node:
"""
Node object represents a soul in the graph.
Attributes:
soul (str) : The soul that the node represents.
requests (list[PutRequests]) : Requests that modifies some key belonging to the soul object directly.
children (list[Node]) : Nodes that are referenced in some key belonging to the soul object directly.
"""
def __init__(self, soul):
self.soul = soul
self.requests = []
self.children = []
def apply_to_subtree(self, func, node_resolver):
"""
Dispatches the put requests in this node and the subtree of this node.
Args:
func (function) : The function that handles a put request.
node_resolver (dict) : Maps between the souls and the nodes.
"""
for e in self.requests:
e.dispatch(func)
self.apply_to_children(func, node_resolver)
def apply_to_children(self, func, node_resolver):
"""
Dispatches the put requests in the subtree (not including self).
Args:
func (function) : The function that handles a put request.
node_resolver (dict) : Maps between the souls and the nodes.
"""
for child in self.children:
child.apply_to_subtree(func, node_resolver)
def add_put_request(self, req):
"""
Appends a put requests to the node.
Args:
req (PutRequest): The request to be added.
"""
self.requests.append(req)
def extract_children(self, soul_obj, node_resolver):
"""
Extracts the children of the soul_obj and stores them in self.children.
Args:
soul_obj (dict): The object associated with soul in the graph (graph[soul]).
node_resolber (dict): Mapping between souls and nodes.
"""
for k, v in soul_obj.items():
if k != '_' and is_reference(v):
self.children.append(node_resolver[v['#']])
class Graph:
"""
Graph object keeps track of all nodes in the graph and applies the put requests in dfs order starting from root object.
The main objective is not to apply put requests except for souls referenced in the graph.
Attributes:
graph (dict): The graph sent by GUN.
nodes (dict): Mapping between souls and nodes.
"""
def __init__(self, graph):
self.graph = graph
self.nodes = {}
self.initialize_nodes()
def process_ref_diffs(self, diffs, func):
"""
Applies diffs in dfs order starting from root objects.
"""
for soul, node in diffs.items():
for k, v in node.items():
if k != METADATA:
self.nodes[soul].add_put_request(PutRequest(soul, k, v, diffs[soul][METADATA][STATE][k], self.graph))
for soul, node in diffs.items():
if is_root_soul(soul):
self.nodes[soul].apply_to_subtree(func, self.nodes)
def initialize_nodes(self):
"""
Initializee the nodes from the graph and build the relations between them.
"""
for k, v in self.graph.items():
self.nodes[k] = Node(k)
for k, v in self.graph.items():
self.nodes[k].extract_children(v, self.nodes)
Classes
class Graph (graph)
-
Graph object keeps track of all nodes in the graph and applies the put requests in dfs order starting from root object.
The main objective is not to apply put requests except for souls referenced in the graph.
Attributes
graph
:dict
- The graph sent by GUN.
nodes
:dict
- Mapping between souls and nodes.
Source code
class Graph: """ Graph object keeps track of all nodes in the graph and applies the put requests in dfs order starting from root object. The main objective is not to apply put requests except for souls referenced in the graph. Attributes: graph (dict): The graph sent by GUN. nodes (dict): Mapping between souls and nodes. """ def __init__(self, graph): self.graph = graph self.nodes = {} self.initialize_nodes() def process_ref_diffs(self, diffs, func): """ Applies diffs in dfs order starting from root objects. """ for soul, node in diffs.items(): for k, v in node.items(): if k != METADATA: self.nodes[soul].add_put_request(PutRequest(soul, k, v, diffs[soul][METADATA][STATE][k], self.graph)) for soul, node in diffs.items(): if is_root_soul(soul): self.nodes[soul].apply_to_subtree(func, self.nodes) def initialize_nodes(self): """ Initializee the nodes from the graph and build the relations between them. """ for k, v in self.graph.items(): self.nodes[k] = Node(k) for k, v in self.graph.items(): self.nodes[k].extract_children(v, self.nodes)
Methods
def initialize_nodes(self)
-
Initializee the nodes from the graph and build the relations between them.
Source code
def initialize_nodes(self): """ Initializee the nodes from the graph and build the relations between them. """ for k, v in self.graph.items(): self.nodes[k] = Node(k) for k, v in self.graph.items(): self.nodes[k].extract_children(v, self.nodes)
def process_ref_diffs(self, diffs, func)
-
Applies diffs in dfs order starting from root objects.
Source code
def process_ref_diffs(self, diffs, func): """ Applies diffs in dfs order starting from root objects. """ for soul, node in diffs.items(): for k, v in node.items(): if k != METADATA: self.nodes[soul].add_put_request(PutRequest(soul, k, v, diffs[soul][METADATA][STATE][k], self.graph)) for soul, node in diffs.items(): if is_root_soul(soul): self.nodes[soul].apply_to_subtree(func, self.nodes)
class Node (soul)
-
Node object represents a soul in the graph.
Attributes
soul (str) : The soul that the node represents. requests (list[PutRequests]) : Requests that modifies some key belonging to the soul object directly. children (list[Node]) : Nodes that are referenced in some key belonging to the soul object directly.
Source code
class Node: """ Node object represents a soul in the graph. Attributes: soul (str) : The soul that the node represents. requests (list[PutRequests]) : Requests that modifies some key belonging to the soul object directly. children (list[Node]) : Nodes that are referenced in some key belonging to the soul object directly. """ def __init__(self, soul): self.soul = soul self.requests = [] self.children = [] def apply_to_subtree(self, func, node_resolver): """ Dispatches the put requests in this node and the subtree of this node. Args: func (function) : The function that handles a put request. node_resolver (dict) : Maps between the souls and the nodes. """ for e in self.requests: e.dispatch(func) self.apply_to_children(func, node_resolver) def apply_to_children(self, func, node_resolver): """ Dispatches the put requests in the subtree (not including self). Args: func (function) : The function that handles a put request. node_resolver (dict) : Maps between the souls and the nodes. """ for child in self.children: child.apply_to_subtree(func, node_resolver) def add_put_request(self, req): """ Appends a put requests to the node. Args: req (PutRequest): The request to be added. """ self.requests.append(req) def extract_children(self, soul_obj, node_resolver): """ Extracts the children of the soul_obj and stores them in self.children. Args: soul_obj (dict): The object associated with soul in the graph (graph[soul]). node_resolber (dict): Mapping between souls and nodes. """ for k, v in soul_obj.items(): if k != '_' and is_reference(v): self.children.append(node_resolver[v['#']])
Methods
def add_put_request(self, req)
-
Appends a put requests to the node.
Args
req
:PutRequest
- The request to be added.
Source code
def add_put_request(self, req): """ Appends a put requests to the node. Args: req (PutRequest): The request to be added. """ self.requests.append(req)
def apply_to_children(self, func, node_resolver)
-
Dispatches the put requests in the subtree (not including self).
Args
func (function) : The function that handles a put request. node_resolver (dict) : Maps between the souls and the nodes.
Source code
def apply_to_children(self, func, node_resolver): """ Dispatches the put requests in the subtree (not including self). Args: func (function) : The function that handles a put request. node_resolver (dict) : Maps between the souls and the nodes. """ for child in self.children: child.apply_to_subtree(func, node_resolver)
def apply_to_subtree(self, func, node_resolver)
-
Dispatches the put requests in this node and the subtree of this node.
Args
func (function) : The function that handles a put request. node_resolver (dict) : Maps between the souls and the nodes.
Source code
def apply_to_subtree(self, func, node_resolver): """ Dispatches the put requests in this node and the subtree of this node. Args: func (function) : The function that handles a put request. node_resolver (dict) : Maps between the souls and the nodes. """ for e in self.requests: e.dispatch(func) self.apply_to_children(func, node_resolver)
def extract_children(self, soul_obj, node_resolver)
-
Extracts the children of the soul_obj and stores them in self.children.
Args
- soul_obj (dict): The object associated with soul in the graph (graph[soul]).
node_resolber
:dict
- Mapping between souls and nodes.
Source code
def extract_children(self, soul_obj, node_resolver): """ Extracts the children of the soul_obj and stores them in self.children. Args: soul_obj (dict): The object associated with soul in the graph (graph[soul]). node_resolber (dict): Mapping between souls and nodes. """ for k, v in soul_obj.items(): if k != '_' and is_reference(v): self.children.append(node_resolver[v['#']])
class PutRequest (soul, key, value, state, graph)
-
PutRequst contains data about a pull request that is dispatched later using dispatch method.
Args
- soul (str) : The soul to which the change is applied.
- key (str) : The key of the property in the soul object.
- value (str) : The new value associated with the key
state
:dict
- The state.
graph
:dict
- The updated graph sent by gundb.
Source code
class PutRequest: """ PutRequst contains data about a pull request that is dispatched later using dispatch method. Args: soul (str) : The soul to which the change is applied. key (str) : The key of the property in the soul object. value (str) : The new value associated with the key state (dict): The state. graph (dict): The updated graph sent by gundb. """ def __init__(self, soul, key, value, state, graph): self.soul = soul self.key = key self.value = value self.state = state self.graph = graph def dispatch(self, func): """ Calls the sent function with self attributes as arguments. """ func(self.soul, self.key, self.value, self.state, self.graph) def node_added(self, node_resolver): """ Returns the node object that is added as a result of this put request. Args: node_resolver (dict): A mapping between souls and node objects. """ assert(isinstance(self.value, dict) and '#' in self.value) return node_resolver[self.value['#']] def node_removed(self, node_resolver): """ Returns the node object that is deleted as a result of this put request. Args: node_resolver (dict): A mapping between souls and node objects. """ if self.key in self.graph[self.soul] and is_reference(self.graph[self.soul][self.key]): return node_resolver[self.graph[self.soul][self.key]['#']] else: return None
Methods
def dispatch(self, func)
-
Calls the sent function with self attributes as arguments.
Source code
def dispatch(self, func): """ Calls the sent function with self attributes as arguments. """ func(self.soul, self.key, self.value, self.state, self.graph)
def node_added(self, node_resolver)
-
Returns the node object that is added as a result of this put request.
Args
node_resolver
:dict
- A mapping between souls and node objects.
Source code
def node_added(self, node_resolver): """ Returns the node object that is added as a result of this put request. Args: node_resolver (dict): A mapping between souls and node objects. """ assert(isinstance(self.value, dict) and '#' in self.value) return node_resolver[self.value['#']]
def node_removed(self, node_resolver)
-
Returns the node object that is deleted as a result of this put request.
Args
node_resolver
:dict
- A mapping between souls and node objects.
Source code
def node_removed(self, node_resolver): """ Returns the node object that is deleted as a result of this put request. Args: node_resolver (dict): A mapping between souls and node objects. """ if self.key in self.graph[self.soul] and is_reference(self.graph[self.soul][self.key]): return node_resolver[self.graph[self.soul][self.key]['#']] else: return None