| 185 | f.write("%r, %r\n" % (key.decode("Latin-1"), pos_and_siz_pair)) |
| 186 | |
| 187 | def __setitem__(self, key, val): |
| 188 | if self._readonly: |
| 189 | raise error('The database is opened for reading only') |
| 190 | if isinstance(key, str): |
| 191 | key = key.encode('utf-8') |
| 192 | elif not isinstance(key, (bytes, bytearray)): |
| 193 | raise TypeError("keys must be bytes or strings") |
| 194 | if isinstance(val, str): |
| 195 | val = val.encode('utf-8') |
| 196 | elif not isinstance(val, (bytes, bytearray)): |
| 197 | raise TypeError("values must be bytes or strings") |
| 198 | self._verify_open() |
| 199 | self._modified = True |
| 200 | if key not in self._index: |
| 201 | self._addkey(key, self._addval(val)) |
| 202 | else: |
| 203 | # See whether the new value is small enough to fit in the |
| 204 | # (padded) space currently occupied by the old value. |
| 205 | pos, siz = self._index[key] |
| 206 | oldblocks = (siz + _BLOCKSIZE - 1) // _BLOCKSIZE |
| 207 | newblocks = (len(val) + _BLOCKSIZE - 1) // _BLOCKSIZE |
| 208 | if newblocks <= oldblocks: |
| 209 | self._index[key] = self._setval(pos, val) |
| 210 | else: |
| 211 | # The new value doesn't fit in the (padded) space used |
| 212 | # by the old value. The blocks used by the old value are |
| 213 | # forever lost. |
| 214 | self._index[key] = self._addval(val) |
| 215 | |
| 216 | # Note that _index may be out of synch with the directory |
| 217 | # file now: _setval() and _addval() don't update the directory |
| 218 | # file. This also means that the on-disk directory and data |
| 219 | # files are in a mutually inconsistent state, and they'll |
| 220 | # remain that way until _commit() is called. Note that this |
| 221 | # is a disaster (for the database) if the program crashes |
| 222 | # (so that _commit() never gets called). |
| 223 | |
| 224 | def __delitem__(self, key): |
| 225 | if self._readonly: |