Rev 4721: Test that read-lock changes to a IndirectedDirstate preserve concurrent write-lock changes. in http://bazaar.launchpad.net/~lifeless/bzr/dirstate2
Robert Collins
robertc at robertcollins.net
Tue Sep 29 05:02:42 BST 2009
At http://bazaar.launchpad.net/~lifeless/bzr/dirstate2
------------------------------------------------------------
revno: 4721
revision-id: robertc at robertcollins.net-20090929040224-ofiqnl04w3e8v1i2
parent: robertc at robertcollins.net-20090929033218-b1os6edaaf8n2ame
committer: Robert Collins <robertc at robertcollins.net>
branch nick: dirstate2
timestamp: Tue 2009-09-29 14:02:24 +1000
message:
Test that read-lock changes to a IndirectedDirstate preserve concurrent write-lock changes.
=== modified file 'NEWS'
--- a/NEWS 2009-09-28 04:21:52 +0000
+++ b/NEWS 2009-09-29 04:02:24 +0000
@@ -141,6 +141,11 @@
Internals
*********
+* A new dirstate class ``IndirectedDirState`` has been introduced which
+ uses a link pointer to manage multiple dirstate files, permitting disk
+ bisection, stat cache updates, and writers and readers to not mutually
+ exclude. (Robert Collins)
+
* ``BTreeLeafParser.extract_key`` has been tweaked slightly to reduce
mallocs while parsing the index (approx 3=>1 mallocs per key read).
This results in a 10% speedup while reading an index.
=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py 2009-09-29 03:32:18 +0000
+++ b/bzrlib/dirstate.py 2009-09-29 04:02:24 +0000
@@ -3341,7 +3341,7 @@
# file.
self._transport.rename(name_check, 'current')
self._transport.delete(current_new)
- self._read_link.delete(name)
+ self._transport.delete(name)
# not saving in _save in a 'r' lock is not an error.
return True
# Claim that we're committing
=== modified file 'bzrlib/tests/test_dirstate.py'
--- a/bzrlib/tests/test_dirstate.py 2009-09-29 03:32:18 +0000
+++ b/bzrlib/tests/test_dirstate.py 2009-09-29 04:02:24 +0000
@@ -626,6 +626,62 @@
finally:
state.unlock()
+ def test_save_from_read_lock_preserves_concurrent_changes(self):
+ """If dirstate is locked, save will fail without complaining."""
+ self.build_tree(['a-file', 'b-file'])
+ state = self._dirstate_class.initialize('dirstate')
+ try:
+ # No stat and no sha1 sum.
+ state.add('a-file', 'a-file-id', 'file', None, '')
+ state.save()
+ finally:
+ state.unlock()
+
+ state = self._dirstate_class.on_file('dirstate')
+ state.lock_read()
+ try:
+ entry = state._get_entry(0, path_utf8='a-file')
+ sha1sum = dirstate.update_entry(state, entry, 'a-file',
+ os.lstat('a-file'))
+ # No sha - too new
+ self.assertEqual(None, sha1sum)
+ self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
+ state._dirblock_state)
+
+ # Now, before we try to save, grab another dirstate, and take out
+ # a write lock (it could be a read lock, but write locks are the
+ # ones we really care MUST NOT have their changes lost).
+ state2 = self._dirstate_class.on_file('dirstate')
+ try:
+ state2.lock_write()
+ except errors.LockContention:
+ if self._dirstate_class == dirstate.DirState:
+ # clearly we can't overwrite the write locks changes if we
+ # can't get a write lock at the same time ;)
+ return
+ else:
+ self.fail("unexpected lock contention")
+ try:
+ # The write executes a change:
+ state2.add('b-file', 'b-file-id', 'file', None, '')
+ state2.save()
+ # The read-locked state saves its hash update, which must not
+ # result in b-file being lost, not error.
+ state.save()
+ finally:
+ state2.unlock()
+ finally:
+ state.unlock()
+
+ # The file on disk should still contain b-file.
+ state = self._dirstate_class.on_file('dirstate')
+ state.lock_read()
+ try:
+ entry = state._get_entry(0, path_utf8='b-file')
+ self.assertEqual('', entry[1][0][1])
+ finally:
+ state.unlock()
+
def test_save_fails_quietly_if_locked(self):
"""If dirstate is locked, save will fail without complaining."""
self.build_tree(['a-file'])
More information about the bazaar-commits
mailing list