Optimize Model insertions (blist + bisect)

This commit is contained in:
miruka 2020-02-12 07:43:03 -04:00
parent 7020706ff1
commit f922204644
3 changed files with 18 additions and 13 deletions

View File

@ -9,5 +9,6 @@ lxml >= 4.4.2, < 5
mistune >= 0.8.4, < 0.9
dataclasses >= 0.6, < 0.7; python_version < "3.7"
pyfastcopy >= 1.0.3, < 2; python_version < "3.8"
blist >= 1.3.6, < 2
git+http://github.com/mirukan/matrix-nio#egg=matrix-nio[e2e]

View File

@ -1,8 +1,11 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
from threading import Lock
from bisect import bisect
from threading import RLock
from typing import TYPE_CHECKING, Any, Dict, Iterator, List, MutableMapping
from blist import blist
from ..pyotherside_events import (
ModelCleared, ModelItemDeleted, ModelItemInserted,
)
@ -34,8 +37,8 @@ class Model(MutableMapping):
def __init__(self, sync_id: SyncId) -> None:
self.sync_id: SyncId = sync_id
self._data: Dict[Any, "ModelItem"] = {}
self._sorted_data: List["ModelItem"] = []
self._write_lock: Lock = Lock()
self._sorted_data: List["ModelItem"] = blist()
self._write_lock: RLock = RLock()
def __repr__(self) -> str:
@ -85,10 +88,10 @@ class Model(MutableMapping):
new.parent_model = self
self._data[key] = new
self._sorted_data.append(new)
self._sorted_data.sort()
index = bisect(self._sorted_data, new)
self._sorted_data.insert(index, new)
ModelItemInserted(self.sync_id, self._sorted_data.index(new), new)
ModelItemInserted(self.sync_id, index, new)
def __delitem__(self, key) -> None:

View File

@ -35,15 +35,16 @@ class ModelItem:
if getattr(self, name) == value:
return
super().__setattr__(name, value)
with self.parent_model._write_lock:
super().__setattr__(name, value)
old_index = self.parent_model._sorted_data.index(self)
self.parent_model._sorted_data.sort()
new_index = self.parent_model._sorted_data.index(self)
old_index = self.parent_model._sorted_data.index(self)
self.parent_model._sorted_data.sort()
new_index = self.parent_model._sorted_data.index(self)
ModelItemFieldChanged(
self.parent_model.sync_id, old_index, new_index, name, value,
)
ModelItemFieldChanged(
self.parent_model.sync_id, old_index, new_index, name, value,
)
def __delattr__(self, name: str) -> None: