Rev 3749: Teach install_revisions to use inventory deltas when appropriate. in http://people.ubuntu.com/~robertc/baz2.0/repository

Robert Collins robertc at robertcollins.net
Tue Oct 14 05:33:39 BST 2008


At http://people.ubuntu.com/~robertc/baz2.0/repository

------------------------------------------------------------
revno: 3749
revision-id: robertc at robertcollins.net-20081014043332-e2c9ndq49701x6w0
parent: robertc at robertcollins.net-20081013063620-dos0y220vi51fose
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Tue 2008-10-14 15:33:32 +1100
message:
  Teach install_revisions to use inventory deltas when appropriate.
modified:
  bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
=== modified file 'bzrlib/fetch.py'
--- a/bzrlib/fetch.py	2008-10-09 04:50:37 +0000
+++ b/bzrlib/fetch.py	2008-10-14 04:33:32 +0000
@@ -242,7 +242,8 @@
             # know for unselected inventories whether all their required
             # texts are present in the other repository - it could be
             # corrupt.
-            if self.to_repository._format.supports_chks:
+            if (self.from_repository._format.supports_chks or
+                self.to_repository._format.supports_chks):
                 # Hack to make chk->chk fetch: copy the inventories as
                 # inventories.
                 total = len(revs)

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2008-10-13 06:36:20 +0000
+++ b/bzrlib/repository.py	2008-10-14 04:33:32 +0000
@@ -173,15 +173,20 @@
                 basis_id = self.parents[0]
             except IndexError:
                 basis_id = _mod_revision.NULL_REVISION
-            self.inv_sha1 = self.repository.add_inventory_delta(
-                basis_id, self.basis_delta, self._new_revision_id,
-                self.parents)
-        else:
-            self.inv_sha1 = self.repository.add_inventory(
-                self._new_revision_id,
-                self.new_inventory,
-                self.parents
-                )
+            try:
+                self.inv_sha1 = self.repository.add_inventory_delta(
+                    basis_id, self.basis_delta, self._new_revision_id,
+                    self.parents)
+                return
+            except errors.NoSuchRevision:
+                # The basis inventory wasn't actually available; fall back to
+                # add_inventory.
+                pass
+        self.inv_sha1 = self.repository.add_inventory(
+            self._new_revision_id,
+            self.new_inventory,
+            self.parents
+            )
 
     def _gen_revision_id(self):
         """Return new revision-id."""
@@ -2053,8 +2058,10 @@
     """
     repository.start_write_group()
     try:
+        inventory_cache = lru_cache.LRUCache(10)
         for n, (revision, revision_tree, signature) in enumerate(iterable):
-            _install_revision(repository, revision, revision_tree, signature)
+            _install_revision(repository, revision, revision_tree, signature,
+                inventory_cache)
             if pb is not None:
                 pb.update('Transferring revisions', n + 1, num_revisions)
     except:
@@ -2064,7 +2071,8 @@
         repository.commit_write_group()
 
 
-def _install_revision(repository, rev, revision_tree, signature):
+def _install_revision(repository, rev, revision_tree, signature,
+    inventory_cache):
     """Install all revision data into a repository."""
     present_parents = []
     parent_trees = {}
@@ -2107,7 +2115,19 @@
         repository.texts.add_lines(text_key, text_parents, lines)
     try:
         # install the inventory
-        repository.add_inventory(rev.revision_id, inv, present_parents)
+        if repository._format._commit_inv_deltas and len(rev.parent_ids):
+            # Cache this inventory
+            inventory_cache[rev.revision_id] = inv
+            try:
+                basis_inv = inventory_cache[rev.parent_ids[0]]
+            except KeyError:
+                repository.add_inventory(rev.revision_id, inv, present_parents)
+            else:
+                delta = _make_inv_delta(basis_inv, inv)
+                repository.add_inventory_delta(rev.parent_ids[0], delta,
+                    rev.revision_id, present_parents)
+        else:
+            repository.add_inventory(rev.revision_id, inv, present_parents)
     except errors.RevisionAlreadyPresent:
         pass
     if signature is not None:
@@ -2115,6 +2135,24 @@
     repository.add_revision(rev.revision_id, rev, inv)
 
 
+def _make_inv_delta(old, new):
+    """Make an inventory delta from two inventories."""
+    old_ids = set(old._byid.iterkeys())
+    new_ids = set(new._byid.iterkeys())
+    adds = new_ids - old_ids
+    deletes = old_ids - new_ids
+    common = old_ids.intersection(new_ids)
+    delta = []
+    for file_id in deletes:
+        delta.append((old.id2path(file_id), None, file_id, None))
+    for file_id in adds:
+        delta.append((None, new.id2path(file_id), file_id, new[file_id]))
+    for file_id in common:
+        if old[file_id] != new[file_id]:
+            delta.append((old.id2path(file_id), new.id2path(file_id),
+                file_id, new[file_id]))
+    return delta
+
 class MetaDirRepository(Repository):
     """Repositories in the new meta-dir layout.
     




More information about the bazaar-commits mailing list