Rev 2330: Correct generation of revisiontree inventories to handle out of order parents. in file:///home/robertc/source/baz/dirstate/
Robert Collins
robertc at robertcollins.net
Fri Feb 16 06:02:40 GMT 2007
At file:///home/robertc/source/baz/dirstate/
------------------------------------------------------------
revno: 2330
revision-id: robertc at robertcollins.net-20070216060239-yvf7pfd94kv9vqy4
parent: robertc at robertcollins.net-20070216023942-8oxrm3qtriwc54w0
committer: Robert Collins <robertc at robertcollins.net>
branch nick: dirstate
timestamp: Fri 2007-02-16 17:02:39 +1100
message:
Correct generation of revisiontree inventories to handle out of order parents.
modified:
bzrlib/dirstate.py dirstate.py-20060728012006-d6mvoihjb3je9peu-1
bzrlib/workingtree_4.py workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py 2007-02-15 22:28:34 +0000
+++ b/bzrlib/dirstate.py 2007-02-16 06:02:39 +0000
@@ -229,8 +229,7 @@
else:
size = stat.st_size
packed_stat = pack_stat(stat)
- parent_info = [DirState.NULL_PARENT_ROW] * (len(self._parents) -
- len(self._ghosts))
+ parent_info = self._empty_parent_info()
if kind == 'file':
row_data = ((dirname, basename, kind, file_id.encode('utf8'),
size, packed_stat, link_or_sha1), parent_info)
@@ -266,6 +265,10 @@
row_index = bisect.insort_left(block, new_row)
self._dirblock_state = DirState.IN_MEMORY_MODIFIED
+ def _empty_parent_info(self):
+ return [DirState.NULL_PARENT_ROW] * (len(self._parents) -
+ len(self._ghosts))
+
def _ensure_block(self, parent_block_index, parent_row_index, dirname):
"""Enssure a block for dirname exists.
@@ -803,15 +806,19 @@
if new_id.__class__ == unicode:
new_id = new_id.encode('utf8')
self._read_dirblocks_if_needed()
+ if len(path):
+ import pdb;pdb.set_trace()
+ # logic not written
+ raise NotImplementedError(self.set_path_id)
+ # TODO: check new id is unique
if new_id == self._root_row[0][3]:
# the root id is unchanged
return
- if len(path) or len(self._parents):
- import pdb;pdb.set_trace()
- # logic not written
- raise NotImplementedError(self.set_path_id)
root_info, root_parents = self._root_row
- self._root_row = (root_info[0:3] + (new_id, ) + root_info[4:7]), root_parents
+ if len(root_parents):
+ self.add_deleted(root_info[3], root_parents)
+ self._root_row = ((root_info[0:3] + (new_id, ) + root_info[4:7]),
+ self._empty_parent_info())
self._dirblock_state = DirState.IN_MEMORY_MODIFIED
def set_parent_trees(self, trees, ghosts):
=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py 2007-02-16 02:39:42 +0000
+++ b/bzrlib/workingtree_4.py 2007-02-16 06:02:39 +0000
@@ -207,10 +207,13 @@
This is relatively expensive: we have to walk the entire dirstate.
Ideally we would not, and can deprecate this function.
"""
- dirstate = self.current_dirstate()
- rows = self._dirstate._iter_rows()
- root_row = rows.next()
- inv = Inventory(root_id=root_row[0][3].decode('utf8'))
+ state = self.current_dirstate()
+ state._read_dirblocks_if_needed()
+ rows = state._iter_rows()
+ current_row = state._root_row
+ current_id = current_row[0][3].decode('utf8')
+ inv = Inventory(root_id=current_id)
+ rows.next()
# we could do this straight out of the dirstate; it might be fast
# and should be profiled - RBC 20070216
parent_ids = {'' : inv.root.file_id}
@@ -809,21 +812,29 @@
assert self._revision_id in self._dirstate.get_parent_ids(), \
'parent %s has disappeared from %s' % (
self._revision_id, self._dirstate.get_parent_ids())
+ # separate call for profiling - makes it clear where the costs are.
+ self._dirstate._read_dirblocks_if_needed()
parent_index = self._dirstate.get_parent_ids().index(self._revision_id)
+ # because the parent tree may look dramatically different to the current
+ # tree, we grab and sort the tree content all at once, then
+ # deserialise into an inventory.
rows = self._dirstate._iter_rows()
- root_row = rows.next()
- inv = Inventory(root_id=root_row[0][3].decode('utf8'),
- revision_id=self._revision_id)
+ parent_rows = []
+ for row in rows:
+ parent_rows.append((row[1][parent_index], row[0][3].decode('utf8')))
+ parent_rows = iter(sorted(parent_rows, key=lambda x:x[0][2:3]))
+ root_row = parent_rows.next()
+ inv = Inventory(root_id=root_row[1], revision_id=self._revision_id)
# we could do this straight out of the dirstate; it might be fast
# and should be profiled - RBC 20070216
parent_ids = {'' : inv.root.file_id}
- for line in rows:
- revid, kind, dirname, name, size, executable, sha1 = line[1][parent_index]
+ for line in parent_rows:
+ revid, kind, dirname, name, size, executable, sha1 = line[0]
if not revid:
# not in this revision tree.
continue
parent_id = parent_ids[dirname]
- file_id = line[0][3].decode('utf8')
+ file_id = line[1]
entry = entry_factory[kind](file_id, name.decode('utf8'), parent_id)
entry.revision = revid.decode('utf8')
if kind == 'file':
More information about the bazaar-commits
mailing list