rocksdb.py (3110B)
1 # standard imports 2 import datetime 3 import os 4 5 # external imports 6 import rocksdb 7 8 # local imports 9 from .base import StoreFactory 10 11 12 class RocksDbStore: 13 14 def __init__(self, path, db, binary=False): 15 self.db = db 16 self.__path = path 17 self.__binary = binary 18 19 20 def __to_key(self, k): 21 return k.encode('utf-8') 22 23 24 def __to_contents(self, v): 25 if isinstance(v, bytes): 26 return v 27 return v.encode('utf-8') 28 29 30 def __to_path(self, k): 31 return '.'.join([self.__path, k]) 32 33 34 def __from_path(self, s): 35 (left, right) = s.split('.', maxsplit=1) 36 return right 37 38 39 def __to_result(self, v): 40 if self.__binary: 41 return v 42 return v.decode('utf-8') 43 44 45 def put(self, k, contents=b''): 46 if contents == None: 47 contents = b'' 48 else: 49 contents = self.__to_contents(contents) 50 k = self.__to_path(k) 51 k = self.__to_key(k) 52 self.db.put(k, contents) 53 54 55 def remove(self, k): 56 k = self.__to_path(k) 57 k = self.__to_key(k) 58 self.db.delete(k) 59 60 61 def get(self, k): 62 k = self.__to_path(k) 63 k = self.__to_key(k) 64 v = self.db.get(k) 65 return self.__to_result(v) 66 67 68 def list(self): 69 it = self.db.iteritems() 70 kb_start = self.__to_key(self.__path) 71 it.seek(kb_start) 72 73 r = [] 74 l = len(self.__path) 75 for (kb, v) in it: 76 k = kb.decode('utf-8') 77 if len(k) < l or k[:l] != self.__path: 78 break 79 k = self.__from_path(k) 80 v = self.db.get(kb) 81 r.append((k, v,)) 82 83 return r 84 85 86 def path(self): 87 return None 88 89 90 def replace(self, k, contents): 91 if contents == None: 92 contents = b'' 93 else: 94 contents = self.__to_contents(contents) 95 k = self.__to_path(k) 96 k = self.__to_key(k) 97 v = self.db.get(k) 98 if v == None: 99 raise FileNotFoundError(k) 100 self.db.put(k, contents) 101 102 103 def modified(self, k): 104 k = self.__to_path(k) 105 k = '_mod' + k 106 v = self.db.get(k) 107 return int(v) 108 109 110 def register_modify(self, k): 111 k = self.__to_path(k) 112 k = '_mod' + k 113 ts = datetime.datetime.utcnow().timestamp() 114 self.db.set(k) 115 116 117 class RocksDbStoreFactory(StoreFactory): 118 119 def __init__(self, path, binary=False): 120 try: 121 os.stat(path) 122 except FileNotFoundError: 123 os.makedirs(path) 124 self.db = rocksdb.DB(path, rocksdb.Options(create_if_missing=True)) 125 self.__binary = binary 126 127 128 def add(self, k): 129 k = str(k) 130 return RocksDbStore(k, self.db, binary=self.__binary) 131 132 133 def close(self): 134 self.db.close() 135 136 137 def ls(self): 138 it = self.db.iterkeys() 139 it.seek_to_first() 140 r = [] 141 for k in it: 142 v = k.rsplit(b'.', maxsplit=1) 143 if v != k: 144 v = v[0].decode('utf-8') 145 if v not in r: 146 r.append(v) 147 return r