annotate Lib/dumbdbm.py @ 4566:6403c94de50d legacy-trunk

Added safeguard against failure in __del__.
author Guido van Rossum <guido@python.org>
date Wed, 27 Nov 1996 19:39:58 +0000
parents 985134375672
children cde9b2e64c00
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2952
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 """A dumb and slow but simple dbm clone.
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3 For database spam, spam.dir contains the index (a text file),
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4 spam.bak *may* contain a backup of the index (also a text file),
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
5 while spam.dat contains the data (a binary file).
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
6
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
7 XXX TO DO:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
8
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
9 - seems to contain a bug when updating...
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
10
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
11 - reclaim free space (currently, space once occupied by deleted or expanded
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
12 items is never reused)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
13
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
14 - support concurrent access (currently, if two processes take turns making
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
15 updates, they can mess up the index)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
16
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
17 - support efficient access to large databases (currently, the whole index
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
18 is read when the database is opened, and some updates rewrite the whole index)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
19
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 - support opening for read-only (flag = 'm')
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
21
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
22 """
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
23
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
24 _os = __import__('os')
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
25 import __builtin__
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
26
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
27 _open = __builtin__.open
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
28
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 _BLOCKSIZE = 512
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
30
3631
985134375672 export error == IOError
Guido van Rossum <guido@python.org>
parents: 3358
diff changeset
31 error = IOError # For anydbm
985134375672 export error == IOError
Guido van Rossum <guido@python.org>
parents: 3358
diff changeset
32
2952
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
33 class _Database:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
34
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
35 def __init__(self, file):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
36 self._dirfile = file + '.dir'
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 self._datfile = file + '.dat'
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
38 self._bakfile = file + '.bak'
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 # Mod by Jack: create data file if needed
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
40 try:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
41 f = _open(self._datfile, 'r')
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
42 except IOError:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
43 f = _open(self._datfile, 'w')
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
44 f.close()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
45 self._update()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
46
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
47 def _update(self):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
48 self._index = {}
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
49 try:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
50 f = _open(self._dirfile)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
51 except IOError:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
52 pass
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
53 else:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
54 while 1:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
55 line = f.readline()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
56 if not line: break
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
57 key, (pos, siz) = eval(line)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
58 self._index[key] = (pos, siz)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
59 f.close()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
60
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
61 def _commit(self):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
62 try: _os.unlink(self._bakfile)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
63 except _os.error: pass
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
64 try: _os.rename(self._dirfile, self._bakfile)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
65 except _os.error: pass
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
66 f = _open(self._dirfile, 'w')
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
67 for key, (pos, siz) in self._index.items():
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
68 f.write("%s, (%s, %s)\n" % (`key`, `pos`, `siz`))
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
69 f.close()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
70
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
71 def __getitem__(self, key):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
72 pos, siz = self._index[key] # may raise KeyError
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
73 f = _open(self._datfile, 'rb')
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
74 f.seek(pos)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
75 dat = f.read(siz)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
76 f.close()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
77 return dat
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
78
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
79 def _addval(self, val):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 f = _open(self._datfile, 'rb+')
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
81 f.seek(0, 2)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
82 pos = f.tell()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
83 ## Does not work under MW compiler
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
84 ## pos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
85 ## f.seek(pos)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
86 npos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
87 f.write('\0'*(npos-pos))
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
88 pos = npos
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
89
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
90 f.write(val)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
91 f.close()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
92 return (pos, len(val))
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
93
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
94 def _setval(self, pos, val):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
95 f = _open(self._datfile, 'rb+')
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
96 f.seek(pos)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
97 f.write(val)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
98 f.close()
3358
21d89698329c fix typo in _setval() return value
Guido van Rossum <guido@python.org>
parents: 2952
diff changeset
99 return (pos, len(val))
2952
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
100
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
101 def _addkey(self, key, (pos, siz)):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
102 self._index[key] = (pos, siz)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
103 f = _open(self._dirfile, 'a')
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
104 f.write("%s, (%s, %s)\n" % (`key`, `pos`, `siz`))
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
105 f.close()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
106
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
107 def __setitem__(self, key, val):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
108 if not type(key) == type('') == type(val):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
109 raise TypeError, "keys and values must be strings"
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
110 if not self._index.has_key(key):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
111 (pos, siz) = self._addval(val)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
112 self._addkey(key, (pos, siz))
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
113 else:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
114 pos, siz = self._index[key]
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
115 oldblocks = (siz + _BLOCKSIZE - 1) / _BLOCKSIZE
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
116 newblocks = (len(val) + _BLOCKSIZE - 1) / _BLOCKSIZE
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
117 if newblocks <= oldblocks:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
118 pos, siz = self._setval(pos, val)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
119 self._index[key] = pos, siz
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
120 else:
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
121 pos, siz = self._addval(val)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
122 self._index[key] = pos, siz
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
123 self._addkey(key, (pos, siz))
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
124
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
125 def __delitem__(self, key):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
126 del self._index[key]
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
127 self._commit()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
128
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
129 def keys(self):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
130 return self._index.keys()
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
131
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
132 def has_key(self, key):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
133 return self._index.has_key(key)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
134
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
135 def __len__(self):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
136 return len(self._index)
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
137
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
138 def close(self):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
139 self._index = None
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
140 self._datfile = self._dirfile = self._bakfile = None
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
141
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
142
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
143 def open(file, flag = None, mode = None):
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
144 # flag, mode arguments are currently ignored
21df421f03fe Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
145 return _Database(file)