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