def store(self, ns: List[Notification]): notifs = [] for n in ns: key = Key(self._deviceID, 0, n.key.path, n.key.key) notifs.append(Notification(key, n.value, n.meta)) # enforce creation of a partition for every path which allows us to get keys key = Key(self._deviceID, 0, n.key.path, None) if not self._store.hasPartition(key): self._store.createPartition(key) self._store.store(notifs)
def __init__(self, st: Store, deviceID: str): self._store = st self._deviceID = deviceID key = Key(deviceID, 0, None, None) if not self._store.hasPartition(key): self._store.createPartition(key) self._key = key
def _deserialize_time_indexed_key(self, b: bytes) -> Key: k = b.split(self.KEY_DELIMITER) if len(k) < 4: if b[-1:] in [self.START_PARTITION, self.END_PARTITION]: raise PartitionKey try: return Key( str(k[0], 'utf-8'), # deviceID float(k[1]) if len(k) > 1 else None, # time str(k[2], 'utf-8') if len(k) > 2 else None, # path k[3] if len(k) > 3 else None, # key ) except: raise ValueError("unable to deserialize key: " + str(b, 'utf-8'))
def main(): class Mock(dict): DESC = 1 def open(self, file, cachesize=None): return self def close(self): pass def flush(self): pass def items(self, start=None, end=None, flags=0): rev = flags & Mock.DESC == Mock.DESC items = iter( sorted(super().items(), key=lambda a: a[0], reverse=rev)) if rev: start, end = end, start filt = lambda e: \ (e[0] >= start if start else True) and \ (e[0] < end if end else True) return filter(filt, items) import io try: import btree bt = Btree(btree, io.BytesIO()) except (ImportError, ModuleNotFoundError): bt = Btree(Mock(), io.BytesIO()) data = [ (Key("devA", 10, "/some/path", b'col'), b"value A1"), (Key("devA", 11, "/some/path", b'col'), b"value A2"), (Key("devA", 12, "/some/path", b'col'), b"value A3"), (Key("devB", 10, "/some/path", b'col'), b"value B1"), (Key("devB", 11, "/some/path", b'col'), b"value B2"), (Key("devB", 12, "/some/path", b'col'), b"value B3"), ] # test writes for (k, v) in data: bt.store(k, v) # test reads for k, v in data: assert v == bt.get(k), "unexpected data for {0}: {1}".format( k, bt.get(k)) # test create partitions partKeyA, partKeyB = Key("devA", None, None, None), Key("devB", None, None, None) assert bt.hasPartition( partKeyA) == False, "expected partition not to exist" bt.createPartition(partKeyA) bt.createPartition(partKeyB) assert bt.hasPartition(partKeyA), "expected hasPartition for devA" assert bt.hasPartition(partKeyB), "expected hasPartition for devB" # test getRange rng = list(bt.getRange(partKeyA, partKeyA)) #print(rng) assert len(rng) == 3, "wrong number of elements from getRange" for i, kv in enumerate(rng): assert data[i] == kv, "expected kv {0}, got {1}".format(data[i], kv) ok = False for i, kv in enumerate(bt.getRange(partKeyB, partKeyB, True)): ok = True assert data[5 - i] == kv, "expected kv {0}, got {1}".format( data[5 - i], kv) assert ok # test close print("PASS") return 0
def __init__(self, store: Store, deviceID: str): self.localStorage = LocalStorage(store, Key(deviceID, None, None, None)) self.localStorage.getPath(str(self.DEVICES_PATH))
def deviceKey(device_id: str) -> Key: return Key(device_id, None, None, None)
def getRangeLocal(self, path: str) -> Generator[Notification, None, None]: key = Key(self._key.device_id, 0, path, None) return self._store.getRange(key, key)
def getLocal(self, path: str, key: bytes) -> object: return self._store.get(Key(self._key.device_id, 0, path, key))
def get(self, key: Key) -> Notification: return self._store.get(Key(key.device_id, 0, key.path, key.key))
def storeLocal(self, path: str, key: bytes, value: object): self.store( [Notification(Key(self._key.device_id, 0, path, key), value)])
def getPath(self, path: str, key: bytes = None) -> Generator[Notification, None, None]: k = Key(self._key.device_id, None, path, key) return self._store.getRange(k, k, index=Base.BY_PATH_INDEX)