95 lines
2.0 KiB
Python
95 lines
2.0 KiB
Python
# standard imports
|
|
import os
|
|
import logging
|
|
|
|
# external imports
|
|
from leveldir.hex import HexDir
|
|
|
|
# local imports
|
|
from chainqueue.error import (
|
|
DuplicateTxError,
|
|
NotLocalTxError,
|
|
)
|
|
|
|
logg = logging.getLogger(__name__)
|
|
|
|
|
|
class IndexStore(HexDir):
|
|
|
|
def __init__(self, root_path, digest_bytes=32):
|
|
os.path.join(root_path, 'contents')
|
|
self.store = HexDir(root_path, digest_bytes)
|
|
|
|
|
|
def __exists(self, k):
|
|
existing = None
|
|
try:
|
|
existing = self.get(k)
|
|
except NotLocalTxError:
|
|
pass
|
|
return existing != None
|
|
|
|
|
|
def put(self, k, v):
|
|
kb = bytes.fromhex(k)
|
|
vb = v.encode('utf-8')
|
|
if self.__exists(k):
|
|
raise DuplicateTxError(k)
|
|
self.store.add(kb, vb)
|
|
|
|
|
|
def get(self, k):
|
|
fp = self.store.to_filepath(k)
|
|
f = None
|
|
err = None
|
|
try:
|
|
f = open(fp, 'rb')
|
|
except FileNotFoundError as e:
|
|
err = e
|
|
if err != None:
|
|
raise NotLocalTxError(err)
|
|
v = f.read()
|
|
f.close()
|
|
return v.decode('utf-8')
|
|
|
|
|
|
class CounterStore:
|
|
|
|
def __init__(self, root_path):
|
|
try:
|
|
os.stat(root_path)
|
|
except FileNotFoundError:
|
|
os.makedirs(root_path)
|
|
|
|
fp = os.path.join(root_path, '.counter')
|
|
f = None
|
|
try:
|
|
f = open(fp, 'rb+')
|
|
except FileNotFoundError:
|
|
logg.debug('counter not found, creating new in {}'.format(fp))
|
|
f = open(fp, 'wb+')
|
|
f.write(b'\x00' * 8)
|
|
f.close()
|
|
f = open(fp, 'rb+')
|
|
|
|
v = f.read(8)
|
|
self.count = int.from_bytes(v, byteorder='big')
|
|
logg.debug('counter starts at {}'.format(self.count))
|
|
|
|
f.seek(0)
|
|
|
|
self.f = f
|
|
|
|
|
|
def __del__(self):
|
|
self.f.close()
|
|
|
|
|
|
def next(self):
|
|
c = self.count
|
|
self.count += 1
|
|
v = self.count.to_bytes(8, 'big')
|
|
self.f.write(v)
|
|
self.f.seek(0)
|
|
return c
|