[Draft] in-memory replica
This commit is contained in:
parent
9517f53473
commit
a6c3d1f029
@ -1,6 +1,7 @@
|
|||||||
"""Replica related things"""
|
"""Replica related things"""
|
||||||
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
from enum import Enum, auto
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from ..document import Document
|
from ..document import Document
|
||||||
@ -10,6 +11,11 @@ from ..query import Query
|
|||||||
from ..share import Share
|
from ..share import Share
|
||||||
|
|
||||||
|
|
||||||
|
class HistoryMode(Enum):
|
||||||
|
ALL = auto()
|
||||||
|
LATEST = auto()
|
||||||
|
|
||||||
|
|
||||||
class IngestEvent:
|
class IngestEvent:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -44,7 +50,12 @@ class Replica(ABC):
|
|||||||
"""Returns the maximum local index of all stored documents"""
|
"""Returns the maximum local index of all stored documents"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_docs_after_local_index(self) -> List[Document]:
|
def get_docs_after_local_index(
|
||||||
|
self,
|
||||||
|
history_mode: HistoryMode,
|
||||||
|
start_after: int,
|
||||||
|
limit: Optional[int] = None,
|
||||||
|
) -> List[Document]:
|
||||||
"""Get all documents after a specific local index"""
|
"""Get all documents after a specific local index"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
82
earthsnake/replica/memory.py
Normal file
82
earthsnake/replica/memory.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
from typing import Dict, List, Tuple
|
||||||
|
|
||||||
|
from ..document import Document
|
||||||
|
from ..exc import ReplicaIsClosedError
|
||||||
|
from ..identity import Identity
|
||||||
|
from ..query import HistoryMode, Query
|
||||||
|
from ..path import Path
|
||||||
|
from ..share import Share
|
||||||
|
from . import Replica
|
||||||
|
|
||||||
|
|
||||||
|
class InMemoryReplica(Replica):
|
||||||
|
def __init__(self, share: Share, **driver_kwargs):
|
||||||
|
self.share = share
|
||||||
|
self._is_closed = False
|
||||||
|
self._max_local_index = -1
|
||||||
|
# Local Index <=> Document pairs
|
||||||
|
self._documents: List[Tuple[int, Document]] = {}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_closed(self):
|
||||||
|
return self._is_closed
|
||||||
|
|
||||||
|
def close(self, erase: bool = False):
|
||||||
|
if erase:
|
||||||
|
self._local_index = -1
|
||||||
|
self._documents = []
|
||||||
|
|
||||||
|
self._is_closed = True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_local_index(self) -> int:
|
||||||
|
return self._max_local_index
|
||||||
|
|
||||||
|
def _get_all_docs(self) -> List[Document]:
|
||||||
|
if self._is_closed:
|
||||||
|
raise ReplicaIsClosedError()
|
||||||
|
|
||||||
|
return [document for _, document in self._documents]
|
||||||
|
|
||||||
|
def _get_latest_docs(self) -> List[Document]:
|
||||||
|
if self._is_closed:
|
||||||
|
raise ReplicaIsClosedError()
|
||||||
|
|
||||||
|
docs_by_path: Dict[str, Document] = {}
|
||||||
|
|
||||||
|
for document in self._documents:
|
||||||
|
if (
|
||||||
|
str(document.path) not in docs_by_path
|
||||||
|
or docs_by_path[str(document.path)].timestamp <= document.timestamp
|
||||||
|
):
|
||||||
|
docs_by_path[str(document.path)] = document
|
||||||
|
|
||||||
|
return list(docs_by_path.values())
|
||||||
|
|
||||||
|
def query_docs(self, query: Query) -> List[Document]:
|
||||||
|
if self._is_closed:
|
||||||
|
raise ReplicaIsClosedError()
|
||||||
|
|
||||||
|
if query.history_mode == HistoryMode.ALL:
|
||||||
|
docs = self._get_all_docs()
|
||||||
|
else:
|
||||||
|
docs = self._get_latest_docs()
|
||||||
|
|
||||||
|
docs_to_local_index = {
|
||||||
|
document: local_index for document, local_index in self.docs_by_local_index
|
||||||
|
}
|
||||||
|
|
||||||
|
return query({docs_to_local_index[document]: document for document in docs})
|
||||||
|
|
||||||
|
def upsert(self, new_document: Document) -> None:
|
||||||
|
if self._is_closed:
|
||||||
|
raise ReplicaIsClosedError()
|
||||||
|
|
||||||
|
self._local_index += 1
|
||||||
|
|
||||||
|
self._documents = [
|
||||||
|
(local_index, document)
|
||||||
|
for local_index, document in self._documents
|
||||||
|
if document.author != new_document.author or document.path != new_document.path
|
||||||
|
]
|
||||||
|
self._documents.append((self._local_index, new_document))
|
Loading…
Reference in New Issue
Block a user