Spaces:
Running
Running
github-actions[bot]
commited on
Commit
·
3556342
1
Parent(s):
b0efb60
Auto-sync from demo at Mon Jan 26 06:10:19 UTC 2026
Browse files- graphgen/bases/base_partitioner.py +0 -21
- graphgen/bases/base_storage.py +4 -0
- graphgen/common/init_storage.py +6 -0
- graphgen/models/partitioner/bfs_partitioner.py +3 -4
- graphgen/models/partitioner/dfs_partitioner.py +3 -4
- graphgen/models/partitioner/ece_partitioner.py +1 -2
- graphgen/models/storage/graph/kuzu_storage.py +8 -0
- graphgen/models/storage/graph/networkx_storage.py +12 -0
graphgen/bases/base_partitioner.py
CHANGED
|
@@ -51,24 +51,3 @@ class BasePartitioner(ABC):
|
|
| 51 |
if edge_data:
|
| 52 |
edges_data.append((u, v, edge_data))
|
| 53 |
return nodes_data, edges_data
|
| 54 |
-
|
| 55 |
-
@staticmethod
|
| 56 |
-
def _build_adjacency_list(
|
| 57 |
-
nodes: List[tuple[str, dict]], edges: List[tuple[str, str, dict]]
|
| 58 |
-
) -> tuple[dict[str, List[str]], set[tuple[str, str]]]:
|
| 59 |
-
"""
|
| 60 |
-
Build adjacency list and edge set from nodes and edges.
|
| 61 |
-
:param nodes
|
| 62 |
-
:param edges
|
| 63 |
-
:return: adjacency list, edge set
|
| 64 |
-
"""
|
| 65 |
-
adj: dict[str, List[str]] = {n[0]: [] for n in nodes}
|
| 66 |
-
edge_set: set[tuple[str, str]] = set()
|
| 67 |
-
for u, v, _ in edges:
|
| 68 |
-
if u == v:
|
| 69 |
-
continue
|
| 70 |
-
adj[u].append(v)
|
| 71 |
-
adj[v].append(u)
|
| 72 |
-
edge_set.add((u, v))
|
| 73 |
-
edge_set.add((v, u))
|
| 74 |
-
return adj, edge_set
|
|
|
|
| 51 |
if edge_data:
|
| 52 |
edges_data.append((u, v, edge_data))
|
| 53 |
return nodes_data, edges_data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
graphgen/bases/base_storage.py
CHANGED
|
@@ -126,6 +126,10 @@ class BaseGraphStorage(StorageNameSpace, ABC):
|
|
| 126 |
def delete_node(self, node_id: str):
|
| 127 |
raise NotImplementedError
|
| 128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
@abstractmethod
|
| 130 |
def reload(self):
|
| 131 |
raise NotImplementedError
|
|
|
|
| 126 |
def delete_node(self, node_id: str):
|
| 127 |
raise NotImplementedError
|
| 128 |
|
| 129 |
+
@abstractmethod
|
| 130 |
+
def get_neighbors(self, node_id: str) -> List[str]:
|
| 131 |
+
raise NotImplementedError
|
| 132 |
+
|
| 133 |
@abstractmethod
|
| 134 |
def reload(self):
|
| 135 |
raise NotImplementedError
|
graphgen/common/init_storage.py
CHANGED
|
@@ -129,6 +129,9 @@ class GraphStorageActor:
|
|
| 129 |
def delete_node(self, node_id: str):
|
| 130 |
return self.graph.delete_node(node_id)
|
| 131 |
|
|
|
|
|
|
|
|
|
|
| 132 |
def reload(self):
|
| 133 |
return self.graph.reload()
|
| 134 |
|
|
@@ -245,6 +248,9 @@ class RemoteGraphStorageProxy(BaseGraphStorage):
|
|
| 245 |
def delete_node(self, node_id: str):
|
| 246 |
return ray.get(self.actor.delete_node.remote(node_id))
|
| 247 |
|
|
|
|
|
|
|
|
|
|
| 248 |
def reload(self):
|
| 249 |
return ray.get(self.actor.reload.remote())
|
| 250 |
|
|
|
|
| 129 |
def delete_node(self, node_id: str):
|
| 130 |
return self.graph.delete_node(node_id)
|
| 131 |
|
| 132 |
+
def get_neighbors(self, node_id: str) -> List[str]:
|
| 133 |
+
return self.graph.get_neighbors(node_id)
|
| 134 |
+
|
| 135 |
def reload(self):
|
| 136 |
return self.graph.reload()
|
| 137 |
|
|
|
|
| 248 |
def delete_node(self, node_id: str):
|
| 249 |
return ray.get(self.actor.delete_node.remote(node_id))
|
| 250 |
|
| 251 |
+
def get_neighbors(self, node_id: str) -> List[str]:
|
| 252 |
+
return ray.get(self.actor.get_neighbors.remote(node_id))
|
| 253 |
+
|
| 254 |
def reload(self):
|
| 255 |
return ray.get(self.actor.reload.remote())
|
| 256 |
|
graphgen/models/partitioner/bfs_partitioner.py
CHANGED
|
@@ -26,8 +26,6 @@ class BFSPartitioner(BasePartitioner):
|
|
| 26 |
nodes = g.get_all_nodes()
|
| 27 |
edges = g.get_all_edges()
|
| 28 |
|
| 29 |
-
adj, _ = self._build_adjacency_list(nodes, edges)
|
| 30 |
-
|
| 31 |
used_n: set[str] = set()
|
| 32 |
used_e: set[frozenset[str]] = set()
|
| 33 |
|
|
@@ -55,7 +53,7 @@ class BFSPartitioner(BasePartitioner):
|
|
| 55 |
used_n.add(it)
|
| 56 |
comm_n.append(it)
|
| 57 |
cnt += 1
|
| 58 |
-
for nei in
|
| 59 |
e_key = frozenset((it, nei))
|
| 60 |
if e_key not in used_e:
|
| 61 |
queue.append((EDGE_UNIT, e_key))
|
|
@@ -63,7 +61,8 @@ class BFSPartitioner(BasePartitioner):
|
|
| 63 |
if it in used_e:
|
| 64 |
continue
|
| 65 |
used_e.add(it)
|
| 66 |
-
|
|
|
|
| 67 |
cnt += 1
|
| 68 |
# push nodes that are not visited
|
| 69 |
for n in it:
|
|
|
|
| 26 |
nodes = g.get_all_nodes()
|
| 27 |
edges = g.get_all_edges()
|
| 28 |
|
|
|
|
|
|
|
| 29 |
used_n: set[str] = set()
|
| 30 |
used_e: set[frozenset[str]] = set()
|
| 31 |
|
|
|
|
| 53 |
used_n.add(it)
|
| 54 |
comm_n.append(it)
|
| 55 |
cnt += 1
|
| 56 |
+
for nei in g.get_neighbors(it):
|
| 57 |
e_key = frozenset((it, nei))
|
| 58 |
if e_key not in used_e:
|
| 59 |
queue.append((EDGE_UNIT, e_key))
|
|
|
|
| 61 |
if it in used_e:
|
| 62 |
continue
|
| 63 |
used_e.add(it)
|
| 64 |
+
u, v = sorted(it)
|
| 65 |
+
comm_e.append((u, v))
|
| 66 |
cnt += 1
|
| 67 |
# push nodes that are not visited
|
| 68 |
for n in it:
|
graphgen/models/partitioner/dfs_partitioner.py
CHANGED
|
@@ -26,8 +26,6 @@ class DFSPartitioner(BasePartitioner):
|
|
| 26 |
nodes = g.get_all_nodes()
|
| 27 |
edges = g.get_all_edges()
|
| 28 |
|
| 29 |
-
adj, _ = self._build_adjacency_list(nodes, edges)
|
| 30 |
-
|
| 31 |
used_n: set[str] = set()
|
| 32 |
used_e: set[frozenset[str]] = set()
|
| 33 |
|
|
@@ -55,7 +53,7 @@ class DFSPartitioner(BasePartitioner):
|
|
| 55 |
used_n.add(it)
|
| 56 |
comm_n.append(it)
|
| 57 |
cnt += 1
|
| 58 |
-
for nei in
|
| 59 |
e_key = frozenset((it, nei))
|
| 60 |
if e_key not in used_e:
|
| 61 |
stack.append((EDGE_UNIT, e_key))
|
|
@@ -64,7 +62,8 @@ class DFSPartitioner(BasePartitioner):
|
|
| 64 |
if it in used_e:
|
| 65 |
continue
|
| 66 |
used_e.add(it)
|
| 67 |
-
|
|
|
|
| 68 |
cnt += 1
|
| 69 |
# push neighboring nodes
|
| 70 |
for n in it:
|
|
|
|
| 26 |
nodes = g.get_all_nodes()
|
| 27 |
edges = g.get_all_edges()
|
| 28 |
|
|
|
|
|
|
|
| 29 |
used_n: set[str] = set()
|
| 30 |
used_e: set[frozenset[str]] = set()
|
| 31 |
|
|
|
|
| 53 |
used_n.add(it)
|
| 54 |
comm_n.append(it)
|
| 55 |
cnt += 1
|
| 56 |
+
for nei in g.get_neighbors(it):
|
| 57 |
e_key = frozenset((it, nei))
|
| 58 |
if e_key not in used_e:
|
| 59 |
stack.append((EDGE_UNIT, e_key))
|
|
|
|
| 62 |
if it in used_e:
|
| 63 |
continue
|
| 64 |
used_e.add(it)
|
| 65 |
+
u, v = sorted(it)
|
| 66 |
+
comm_e.append((u, v))
|
| 67 |
cnt += 1
|
| 68 |
# push neighboring nodes
|
| 69 |
for n in it:
|
graphgen/models/partitioner/ece_partitioner.py
CHANGED
|
@@ -65,7 +65,6 @@ class ECEPartitioner(BFSPartitioner):
|
|
| 65 |
nodes: List[Tuple[str, dict]] = g.get_all_nodes()
|
| 66 |
edges: List[Tuple[str, str, dict]] = g.get_all_edges()
|
| 67 |
|
| 68 |
-
adj, _ = self._build_adjacency_list(nodes, edges)
|
| 69 |
node_dict = dict(nodes)
|
| 70 |
edge_dict = {frozenset((u, v)): d for u, v, d in edges}
|
| 71 |
|
|
@@ -118,7 +117,7 @@ class ECEPartitioner(BFSPartitioner):
|
|
| 118 |
|
| 119 |
neighbors: List[Tuple[str, Any, dict]] = []
|
| 120 |
if cur_type == NODE_UNIT:
|
| 121 |
-
for nb_id in
|
| 122 |
e_key = frozenset((cur_id, nb_id))
|
| 123 |
if e_key not in used_e and e_key not in community_edges:
|
| 124 |
neighbors.append((EDGE_UNIT, e_key, edge_dict[e_key]))
|
|
|
|
| 65 |
nodes: List[Tuple[str, dict]] = g.get_all_nodes()
|
| 66 |
edges: List[Tuple[str, str, dict]] = g.get_all_edges()
|
| 67 |
|
|
|
|
| 68 |
node_dict = dict(nodes)
|
| 69 |
edge_dict = {frozenset((u, v)): d for u, v, d in edges}
|
| 70 |
|
|
|
|
| 117 |
|
| 118 |
neighbors: List[Tuple[str, Any, dict]] = []
|
| 119 |
if cur_type == NODE_UNIT:
|
| 120 |
+
for nb_id in g.get_neighbors(cur_id):
|
| 121 |
e_key = frozenset((cur_id, nb_id))
|
| 122 |
if e_key not in used_e and e_key not in community_edges:
|
| 123 |
neighbors.append((EDGE_UNIT, e_key, edge_dict[e_key]))
|
graphgen/models/storage/graph/kuzu_storage.py
CHANGED
|
@@ -373,6 +373,14 @@ class KuzuStorage(BaseGraphStorage):
|
|
| 373 |
self._conn.execute(query, {"id": node_id})
|
| 374 |
print(f"Node {node_id} deleted from KuzuDB.")
|
| 375 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 376 |
def clear(self):
|
| 377 |
"""Clear all data but keep schema (or drop tables)."""
|
| 378 |
self._conn.execute("MATCH (n) DETACH DELETE n")
|
|
|
|
| 373 |
self._conn.execute(query, {"id": node_id})
|
| 374 |
print(f"Node {node_id} deleted from KuzuDB.")
|
| 375 |
|
| 376 |
+
def get_neighbors(self, node_id: str) -> List[str]:
|
| 377 |
+
query = """
|
| 378 |
+
MATCH (a:Entity {id: $id})-[:Relation]-(b:Entity)
|
| 379 |
+
RETURN DISTINCT b.id
|
| 380 |
+
"""
|
| 381 |
+
result = self._conn.execute(query, {"id": node_id})
|
| 382 |
+
return [row[0] for row in result if row]
|
| 383 |
+
|
| 384 |
def clear(self):
|
| 385 |
"""Clear all data but keep schema (or drop tables)."""
|
| 386 |
self._conn.execute("MATCH (n) DETACH DELETE n")
|
graphgen/models/storage/graph/networkx_storage.py
CHANGED
|
@@ -188,6 +188,18 @@ class NetworkXStorage(BaseGraphStorage):
|
|
| 188 |
else:
|
| 189 |
print(f"Node {node_id} not found in the graph for deletion.")
|
| 190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
def clear(self):
|
| 192 |
"""
|
| 193 |
Clear the graph by removing all nodes and edges.
|
|
|
|
| 188 |
else:
|
| 189 |
print(f"Node {node_id} not found in the graph for deletion.")
|
| 190 |
|
| 191 |
+
def get_neighbors(self, node_id: str) -> List[str]:
|
| 192 |
+
"""
|
| 193 |
+
Get the neighbors of a node based on the specified node_id.
|
| 194 |
+
|
| 195 |
+
:param node_id: The node_id to get neighbors for
|
| 196 |
+
:return: List of neighbor node IDs
|
| 197 |
+
"""
|
| 198 |
+
if self._graph.has_node(node_id):
|
| 199 |
+
return list(self._graph.neighbors(node_id))
|
| 200 |
+
print(f"Node {node_id} not found in the graph.")
|
| 201 |
+
return []
|
| 202 |
+
|
| 203 |
def clear(self):
|
| 204 |
"""
|
| 205 |
Clear the graph by removing all nodes and edges.
|