优化性能

This commit is contained in:
strepsiades
2026-04-01 18:13:18 +08:00
parent 9a3a34c58b
commit f93a6c5c68
8 changed files with 198 additions and 107 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ class BindingManager:
BindingManager 负责维护不同 DataCollection 间节点的绑定关系。
所有查询均在内存中进行,持久化仅作为备份。
"""
def __init__(self, persistence: PersistenceBackend, auto_persist: bool = True, scope: str = "global"):
def __init__(self, persistence: PersistenceBackend, auto_persist: bool = False, scope: str = "global"):
self.persistence = persistence
self.auto_persist = auto_persist
self.scope = scope
+29 -20
View File
@@ -36,6 +36,8 @@ class DataCollection:
self._nodes: Dict[str, SyncNode] = {} # 内存缓存
# data_id 全局唯一(按 collection 维度),用于 O(1) 反查 node_id
self._data_id_to_node_id: Dict[str, str] = {}
# node_id -> data_id 反向索引,用于 O(1) 维护 data_id 更新
self._node_id_to_data_id: Dict[str, str] = {}
# auto_persist=False 时,delete() 不会立即落库;这里记录删除集合,persist() 时统一写回
self._deleted_node_ids: set[str] = set()
@@ -51,6 +53,20 @@ class DataCollection:
"""设置 Collection 默认状态机 runtime。"""
self._sm_runtime = runtime
def _remove_data_id_index(self, node_id: str, data_id: Optional[str] = None) -> None:
target_data_id = data_id
if target_data_id is None:
target_data_id = self._node_id_to_data_id.pop(node_id, None)
else:
self._node_id_to_data_id.pop(node_id, None)
if target_data_id and self._data_id_to_node_id.get(target_data_id) == node_id:
self._data_id_to_node_id.pop(target_data_id, None)
def _set_data_id_index(self, node_id: str, data_id: str) -> None:
self._data_id_to_node_id[data_id] = node_id
self._node_id_to_data_id[node_id] = data_id
async def add(self, node: SyncNode):
# 检查 node_id 唯一性
if node.node_id in self._nodes:
@@ -65,7 +81,7 @@ class DataCollection:
raise ValueError(
f"Duplicate data_id detected: {node.data_id} already bound to node_id={existing_node_id}"
)
self._data_id_to_node_id[node.data_id] = node.node_id
self._set_data_id_index(node.node_id, node.data_id)
self._nodes[node.node_id] = node
self._deleted_node_ids.discard(node.node_id)
@@ -73,18 +89,9 @@ class DataCollection:
await self.persistence.save_node(self.collection_id, self.scope, node)
async def update(self, node: SyncNode):
old_node = self._nodes.get(node.node_id)
if old_node and old_node.data_id and old_node.data_id != "" and old_node.data_id != node.data_id:
# node_id 不变但 data_id 变更,清理旧索引
self._data_id_to_node_id.pop(old_node.data_id, None)
stale_data_ids = [
data_id
for data_id, existing_node_id in self._data_id_to_node_id.items()
if existing_node_id == node.node_id and data_id != node.data_id
]
for stale_data_id in stale_data_ids:
self._data_id_to_node_id.pop(stale_data_id, None)
old_data_id = self._node_id_to_data_id.get(node.node_id)
if old_data_id and old_data_id != node.data_id:
self._remove_data_id_index(node.node_id, old_data_id)
if node.data_id and node.data_id != "":
existing_node_id = self._data_id_to_node_id.get(node.data_id)
@@ -92,16 +99,16 @@ class DataCollection:
raise ValueError(
f"Duplicate data_id detected: {node.data_id} already bound to node_id={existing_node_id}"
)
self._data_id_to_node_id[node.data_id] = node.node_id
self._set_data_id_index(node.node_id, node.data_id)
else:
self._node_id_to_data_id.pop(node.node_id, None)
self._nodes[node.node_id] = node
self._deleted_node_ids.discard(node.node_id)
if self.persistence and self.auto_persist:
await self.persistence.save_node(self.collection_id, self.scope, node)
async def delete(self, node_id: str):
old_node = self._nodes.get(node_id)
if old_node and old_node.data_id and old_node.data_id != "":
self._data_id_to_node_id.pop(old_node.data_id, None)
self._remove_data_id_index(node_id)
if node_id in self._nodes:
del self._nodes[node_id]
@@ -379,6 +386,7 @@ class DataCollection:
self._nodes = {}
self._data_id_to_node_id = {}
self._node_id_to_data_id = {}
self._deleted_node_ids.clear()
node_dicts = await self.persistence.load_nodes(self.collection_id, self.scope)
@@ -498,7 +506,7 @@ class DataCollection:
raise ValueError(
f"Duplicate data_id detected while loading: {node.data_id} already bound to node_id={existing_node_id}"
)
self._data_id_to_node_id[node.data_id] = node.node_id
self._set_data_id_index(node.node_id, node.data_id)
node_types = {node.node_type for node in self._nodes.values()}
for node_type in node_types:
@@ -517,6 +525,7 @@ class DataCollection:
self._nodes = {}
self._data_id_to_node_id = {}
self._node_id_to_data_id = {}
self._deleted_node_ids.clear()
node_dicts = await self.persistence.load_nodes(
@@ -622,7 +631,7 @@ class DataCollection:
raise ValueError(
f"Duplicate data_id detected while loading: {node.data_id} already bound to node_id={existing_node_id}"
)
self._data_id_to_node_id[node.data_id] = node.node_id
self._set_data_id_index(node.node_id, node.data_id)
loaded_node_types = {node.node_type for node in self._nodes.values()}
for node_type in loaded_node_types:
@@ -647,7 +656,7 @@ class DataCollection:
raise ValueError(
f"Duplicate data_id detected: {node.data_id} already bound to node_id={existing_node_id}"
)
self._data_id_to_node_id[node.data_id] = node.node_id
self._set_data_id_index(node.node_id, node.data_id)
self._nodes[node.node_id] = node
self._deleted_node_ids.discard(node.node_id)