This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ysj.ray
Recipients ysj.ray
Date 2011-02-28.09:53:05
SpamBayes Score 0.0
Marked as misclassified No
Message-id <1298886786.25.0.421725723062.issue11350@psf.upfronthosting.co.za>
In-reply-to
Content
By reading the Lib/dbm/dumb.py source, there seems to be an distinct problem which is pointed out in comments: the __setitem__() should call self._commit() in order to keep .dat file and .dir file consist.

Here is a piece of comment found at the end of __setitem__():

# Note that _index may be out of synch with the directory
# file now:  _setval() and _addval() don't update the directory
# file.  This also means that the on-disk directory and data
# files are in a mutually inconsistent state, and they'll
# remain that way until _commit() is called.  Note that this
# is a disaster (for the database) if the program crashes
# (so that _commit() never gets called).


And another piece found in __delitem__():

# XXX It's unclear why we do a _commit() here (the code always
# XXX has, so I'm not changing it).  __setitem__ doesn't try to
# XXX keep the directory file in synch.  Why should we?  Or
# XXX why shouldn't __setitem__?


One probable reason I guess is that the self._commit() method which writes the keys information to .dir file is regarded as a slow process, and the __setitem__() is called frequently at most cases while __deltiem__ is not, so calling self._commit() at each __setitem__ could make the program very slow.

But based on the fact that "The dbm.dumb module is not written for speed and is not nearly as heavily used as the other database modules."(found on dbm's library document), maybe correctness is more important than speed.

So I think it should be fixed:

Index: Lib/dbm/dumb.py
===================================================================
--- Lib/dbm/dumb.py	(revision 88674)
+++ Lib/dbm/dumb.py	(working copy)
@@ -196,6 +196,7 @@
             # remain that way until _commit() is called.  Note that this
             # is a disaster (for the database) if the program crashes
             # (so that _commit() never gets called).
+            self._commit()
 
     def __delitem__(self, key):
         if isinstance(key, str):

And the remaining comments can be deleted.
History
Date User Action Args
2011-02-28 09:53:06ysj.raysetrecipients: + ysj.ray
2011-02-28 09:53:06ysj.raysetmessageid: <1298886786.25.0.421725723062.issue11350@psf.upfronthosting.co.za>
2011-02-28 09:53:05ysj.raylinkissue11350 messages
2011-02-28 09:53:05ysj.raycreate