def __init__(self, storage=None): self._dict = dict() self._lock = Lock() self._storage = Storage(State.__FILENAME) if storage is not None: self._storage = storage self._refresh()
class State(object): __FILENAME = "pypaxos.state" def __init__(self, storage=None): self._dict = dict() self._lock = Lock() self._storage = Storage(State.__FILENAME) if storage is not None: self._storage = storage self._refresh() def read(self, key): return self._dict[key] def write(self, key, value): self._dict[key] = value self._flush() def set_default(self, key, value): if not key in self._dict: self.write(key, value) def _refresh(self): STATE_LOCK.acquire() try: self._dict = load(self._storage.get()) or dict() except FileNotFoundError: self._dict = dict() finally: STATE_LOCK.release() def _flush(self): STATE_LOCK.acquire() try: self._storage.put(dump(self._dict)) finally: STATE_LOCK.release()
def __init__(self, storage=None): self._lock = Lock() self._storage = Storage(Ledger.__FILENAME) if storage is not None: self._storage = storage
class Ledger(object): __FILENAME = "pypaxos.ledger" def __init__(self, storage=None): self._lock = Lock() self._storage = Storage(Ledger.__FILENAME) if storage is not None: self._storage = storage def append(self, ledger_entry): LEDGER_LOCK.acquire() try: self._append(ledger_entry) finally: LEDGER_LOCK.release() def _append(self, ledger_entry): self._storage.append(ledger_entry) def extend(self, ledger_entries): last = LedgerEntry(-1) LEDGER_LOCK.acquire() try: if len(self._storage) > 0: last = LedgerEntry(*self._storage[len(self._storage) - 1].split(LedgerEntry.SEPARATOR)) for entry in [n for n in ledger_entries if n.number > last.number]: self._append(entry) finally: LEDGER_LOCK.release() def get_range(self, start, end=None): LEDGER_LOCK.acquire() try: start_index = self._get_index(start) end_index = self._get_index(end) storage_range = [LedgerEntry(*l.split(LedgerEntry.SEPARATOR)) for l in self._storage[start_index:end_index]] finally: LEDGER_LOCK.release() return storage_range def _get_index(self, proposal): if proposal is None: return None # TODO: O(log n) Binary Search for index, line in enumerate(self._storage): entry = LedgerEntry(*line.split(LedgerEntry.SEPARATOR)) if entry.number == proposal.number: return index return None def __iter__(self): for line in self._storage: yield LedgerEntry(*line.split(LedgerEntry.SEPARATOR)) def __len__(self): return len(self._storage)