36
from __future__ import print_function
36
38
from spyderlib.utils.external.path import path as Path
38
import cPickle as pickle
39
from spyderlib.py3compat import pickle, MutableMapping
43
47
def gethashfile(key):
44
48
return ("%02x" % abs(hash(key) % 256))[-2:]
46
50
_sentinel = object()
48
class PickleShareDB(UserDict.DictMixin):
52
class PickleShareDB(MutableMapping):
49
53
""" The main 'connection' object for PickleShare database """
50
def __init__(self,root):
54
def __init__(self, root):
51
55
""" Return a db object that will manage the specied directory"""
52
56
self.root = Path(root).expanduser().abspath()
53
57
if not self.root.isdir():
54
58
self.root.makedirs()
55
59
# cache has { 'key' : (obj, orig_mod_time) }
62
#==========================================================================
63
# Only affects Python 3
65
return iter(self.cache)
67
return len(self.cache)
68
#==========================================================================
59
def __getitem__(self,key):
70
def __getitem__(self, key):
60
71
""" db['key'] reading """
61
72
fil = self.root / key
68
79
return self.cache[fil][0]
70
81
# The cached item has expired, need to read
71
obj = pickle.load(fil.open())
82
obj = pickle.load(fil.open('rb'))
73
84
raise KeyError(key)
75
self.cache[fil] = (obj,mtime)
86
self.cache[fil] = (obj, mtime)
78
def __setitem__(self,key,value):
89
def __setitem__(self, key, value):
79
90
""" db['key'] = 5 """
80
91
fil = self.root / key
81
92
parent = fil.parent
82
93
if parent and not parent.isdir():
84
pickled = pickle.dump(value,fil.open('w'))
95
# We specify protocol 2, so that we can mostly go between Python 2
96
# and Python 3. We can upgrade to protocol 3 when Python 2 is obsolete.
97
pickled = pickle.dump(value, fil.open('wb'), protocol=2)
86
self.cache[fil] = (value,fil.mtime)
99
self.cache[fil] = (value, fil.mtime)
101
if e.errno != errno.ENOENT:
91
104
def hset(self, hashroot, key, value):
179
192
def _normalized(self, p):
180
193
""" Make a key suitable for user's eyes """
181
return str(self.root.relpathto(p)).replace('\\','/')
194
return str(self.root.relpathto(p)).replace('\\', '/')
183
196
def keys(self, globpat = None):
184
197
""" All keys in DB, or all keys matching a glob"""
234
247
if tries < len(wtimes) -1:
237
def getlink(self,folder):
250
def getlink(self, folder):
238
251
""" Get a convenient link for accessing items """
239
252
return PickleShareLink(self, folder)
256
269
def __init__(self, db, keydir ):
257
270
self.__dict__.update(locals())
259
def __getattr__(self,key):
272
def __getattr__(self, key):
260
273
return self.__dict__['db'][self.__dict__['keydir']+'/' + key]
261
def __setattr__(self,key,val):
274
def __setattr__(self, key, val):
262
275
self.db[self.keydir+'/' + key] = val
263
276
def __repr__(self):
264
277
db = self.__dict__['db']
272
285
db = PickleShareDB('~/testpickleshare')
274
print "Should be empty:",db.items()
287
print("Should be empty:", list(db.items()))
276
db['aku ankka'] = [1,2,313]
277
db['paths/nest/ok/keyname'] = [1,(5,46)]
289
db['aku ankka'] = [1, 2, 313]
290
db['paths/nest/ok/keyname'] = [1, (5, 46)]
278
291
db.hset('hash', 'aku', 12)
279
292
db.hset('hash', 'ankka', 313)
280
print "12 =",db.hget('hash','aku')
281
print "313 =",db.hget('hash','ankka')
282
print "all hashed",db.hdict('hash')
284
print db.keys('paths/nest/ok/k*')
285
print dict(db) # snapsot of whole db
293
print("12 =", db.hget('hash', 'aku'))
294
print("313 =", db.hget('hash', 'ankka'))
295
print("all hashed", db.hdict('hash'))
296
print(list(db.keys()))
297
print(db.keys('paths/nest/ok/k*'))
298
print(dict(db)) # snapsot of whole db
286
299
db.uncache() # frees memory, causes re-reads later
288
301
# shorthand for accessing deeply nested files
289
302
lnk = db.getlink('myobjects/test')
291
304
lnk.bar = lnk.foo + 5
295
308
db = PickleShareDB('~/fsdbtest')
297
310
for i in range(1000):
298
311
for j in range(1000):
299
312
if i % 15 == 0 and i < 200:
307
db[str(j)] = db.get(str(j), []) + [(i,j,"proc %d" % os.getpid())]
308
db.hset('hash',j, db.hget('hash',j,15) + 1 )
320
db[str(j)] = db.get(str(j), []) + [(i, j, "proc %d" % os.getpid())]
321
db.hset('hash', j, db.hget('hash', j, 15) + 1 )
311
324
sys.stdout.flush()