dumbdbm.py (4009B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\dumbdbm.py 2 import os as _os 3 import __builtin__ 4 import UserDict 5 _open = __builtin__.open 6 _BLOCKSIZE = 512 7 error = IOError 8 9 class _Database(UserDict.DictMixin): 10 _os = _os 11 _open = _open 12 13 def __init__(self, filebasename, mode): 14 self._mode = mode 15 self._dirfile = filebasename + _os.extsep + 'dir' 16 self._datfile = filebasename + _os.extsep + 'dat' 17 self._bakfile = filebasename + _os.extsep + 'bak' 18 self._index = None 19 try: 20 f = _open(self._datfile, 'r') 21 except IOError: 22 f = _open(self._datfile, 'w') 23 self._chmod(self._datfile) 24 25 f.close() 26 self._update() 27 28 def _update(self): 29 self._index = {} 30 try: 31 f = _open(self._dirfile) 32 except IOError: 33 pass 34 else: 35 for line in f: 36 line = line.rstrip() 37 key, pos_and_siz_pair = eval(line) 38 self._index[key] = pos_and_siz_pair 39 40 f.close() 41 42 def _commit(self): 43 if self._index is None: 44 return 45 try: 46 self._os.unlink(self._bakfile) 47 except self._os.error: 48 pass 49 50 try: 51 self._os.rename(self._dirfile, self._bakfile) 52 except self._os.error: 53 pass 54 55 f = self._open(self._dirfile, 'w') 56 self._chmod(self._dirfile) 57 for key, pos_and_siz_pair in self._index.iteritems(): 58 f.write('%r, %r\n' % (key, pos_and_siz_pair)) 59 60 f.close() 61 62 sync = _commit 63 64 def __getitem__(self, key): 65 pos, siz = self._index[key] 66 f = _open(self._datfile, 'rb') 67 f.seek(pos) 68 dat = f.read(siz) 69 f.close() 70 return dat 71 72 def _addval(self, val): 73 f = _open(self._datfile, 'rb+') 74 f.seek(0, 2) 75 pos = int(f.tell()) 76 npos = (pos + _BLOCKSIZE - 1) // _BLOCKSIZE * _BLOCKSIZE 77 f.write('\x00' * (npos - pos)) 78 pos = npos 79 f.write(val) 80 f.close() 81 return (pos, len(val)) 82 83 def _setval(self, pos, val): 84 f = _open(self._datfile, 'rb+') 85 f.seek(pos) 86 f.write(val) 87 f.close() 88 return (pos, len(val)) 89 90 def _addkey(self, key, pos_and_siz_pair): 91 self._index[key] = pos_and_siz_pair 92 f = _open(self._dirfile, 'a') 93 self._chmod(self._dirfile) 94 f.write('%r, %r\n' % (key, pos_and_siz_pair)) 95 f.close() 96 97 def __setitem__(self, key, val): 98 if not type(key) == type('') == type(val): 99 raise TypeError, 'keys and values must be strings' 100 if key not in self._index: 101 self._addkey(key, self._addval(val)) 102 else: 103 pos, siz = self._index[key] 104 oldblocks = (siz + _BLOCKSIZE - 1) // _BLOCKSIZE 105 newblocks = (len(val) + _BLOCKSIZE - 1) // _BLOCKSIZE 106 if newblocks <= oldblocks: 107 self._index[key] = self._setval(pos, val) 108 else: 109 self._index[key] = self._addval(val) 110 111 def __delitem__(self, key): 112 del self._index[key] 113 self._commit() 114 115 def keys(self): 116 return self._index.keys() 117 118 def has_key(self, key): 119 return key in self._index 120 121 def __contains__(self, key): 122 return key in self._index 123 124 def iterkeys(self): 125 return self._index.iterkeys() 126 127 __iter__ = iterkeys 128 129 def __len__(self): 130 return len(self._index) 131 132 def close(self): 133 self._commit() 134 self._index = self._datfile = self._dirfile = self._bakfile = None 135 136 __del__ = close 137 138 def _chmod(self, file): 139 if hasattr(self._os, 'chmod'): 140 self._os.chmod(file, self._mode) 141 142 143 def open(file, flag = None, mode = 438): 144 try: 145 um = _os.umask(0) 146 _os.umask(um) 147 except AttributeError: 148 pass 149 else: 150 mode = mode & ~um 151 152 return _Database(file, mode)