Rev 2839: Retain packs and indices in memory within a lock, even when write groups are entered and exited. in http://people.ubuntu.com/~robertc/baz2.0/repository

Robert Collins robertc at robertcollins.net
Wed Oct 17 05:37:28 BST 2007


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

------------------------------------------------------------
revno: 2839
revision-id: robertc at robertcollins.net-20071017043720-rhwigxi4vzslph71
parent: robertc at robertcollins.net-20071017042152-vdjpy1o8jyvero69
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Wed 2007-10-17 14:37:20 +1000
message:
  Retain packs and indices in memory within a lock, even when write groups are entered and exited.
modified:
  bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
  bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
=== modified file 'bzrlib/repofmt/pack_repo.py'
--- a/bzrlib/repofmt/pack_repo.py	2007-10-17 04:21:52 +0000
+++ b/bzrlib/repofmt/pack_repo.py	2007-10-17 04:37:20 +0000
@@ -584,9 +584,6 @@
         # - which has already been flushed, so its safe.
         # XXX: - duplicate code warning with start_write_group; fix before
         #      considering 'done'.
-        if getattr(self.repo, '_open_pack_tuple', None) is not None:
-            raise errors.BzrError('call to create_pack_from_packs while '
-                'another pack is being written.')
         if self._new_pack is not None:
             raise errors.BzrError('call to create_pack_from_packs while '
                 'another pack is being written.')
@@ -748,27 +745,23 @@
     def pack(self):
         """Pack the pack collection totally."""
         self.ensure_loaded()
-        try:
-            total_packs = len(self._names)
-            if total_packs < 2:
-                return
-            total_revisions = self.revision_index.combined_index.key_count()
-            # XXX: the following may want to be a class, to pack with a given
-            # policy.
-            mutter('Packing repository %s, which has %d pack files, '
-                'containing %d revisions into 1 packs.', self, total_packs,
-                total_revisions)
-            # determine which packs need changing
-            pack_distribution = [1]
-            pack_operations = [[0, []]]
-            for pack in self.all_packs():
-                revision_count = pack.get_revision_count()
-                pack_operations[-1][0] += revision_count
-                pack_operations[-1][1].append(pack)
-            self._execute_pack_operations(pack_operations)
-        finally:
-            if not self.repo.is_in_write_group():
-                self.reset()
+        total_packs = len(self._names)
+        if total_packs < 2:
+            return
+        total_revisions = self.revision_index.combined_index.key_count()
+        # XXX: the following may want to be a class, to pack with a given
+        # policy.
+        mutter('Packing repository %s, which has %d pack files, '
+            'containing %d revisions into 1 packs.', self, total_packs,
+            total_revisions)
+        # determine which packs need changing
+        pack_distribution = [1]
+        pack_operations = [[0, []]]
+        for pack in self.all_packs():
+            revision_count = pack.get_revision_count()
+            pack_operations[-1][0] += revision_count
+            pack_operations[-1][1].append(pack)
+        self._execute_pack_operations(pack_operations)
 
     def plan_autopack_combinations(self, existing_packs, pack_distribution):
         """Plan a pack operation.
@@ -1033,6 +1026,10 @@
         """
         self._names.pop(pack.name)
         self._packs.pop(pack.name)
+        self._remove_pack_indices(pack)
+
+    def _remove_pack_indices(self, pack):
+        """Remove the indices for pack from the aggregated indices."""
         self.revision_index.remove_index(pack.revision_index, pack)
         self.inventory_index.remove_index(pack.inventory_index, pack)
         self.text_index.remove_index(pack.text_index, pack)
@@ -1193,36 +1190,31 @@
         self.signature_index.add_writable_index(self._new_pack.signature_index,
             self._new_pack)
 
-        self.repo._open_pack_tuple = (self._upload_transport, self._new_pack.random_name)
-
-        self.repo._revision_store.setup()
-        self.repo.weave_store.setup()
-        self.repo._inv_thunk.setup()
+        # reused revision and signature knits may need updating
+        if self.repo._revision_knit is not None:
+            self.repo._revision_knit._index._add_callback = \
+                self.revision_index.add_callback
+        if self.repo._signature_knit is not None:
+            self.repo._signature_knit._index._add_callback = \
+                self.signature_index.add_callback
+        # create a reused knit object for text addition in commit.
+        self.repo._text_knit = self.repo.weave_store.get_weave_or_empty(
+            'all-texts', None)
 
     def _abort_write_group(self):
         # FIXME: just drop the transient index.
         # forget what names there are
         self._new_pack.abort()
-        pack = self._new_pack
-        self.revision_index.remove_index(pack.revision_index, pack)
-        self.inventory_index.remove_index(pack.inventory_index, pack)
-        self.text_index.remove_index(pack.text_index, pack)
-        self.signature_index.remove_index(pack.signature_index, pack)
+        self._remove_pack_indices(self._new_pack)
         self._new_pack = None
-        self.reset()
+        self.repo._text_knit = None
 
     def _commit_write_group(self):
-        pack = self._new_pack
-        # remove the pack's write indices from the aggregate indices.
-        self.revision_index.remove_index(pack.revision_index, pack)
-        self.inventory_index.remove_index(pack.inventory_index, pack)
-        self.text_index.remove_index(pack.text_index, pack)
-        self.signature_index.remove_index(pack.signature_index, pack)
+        self._remove_pack_indices(self._new_pack)
         if self._new_pack.data_inserted():
             # get all the data to disk and read to use
             self._new_pack.finish()
             self.allocate(self._new_pack)
-            self.repo._open_pack_tuple = None
             self._new_pack = None
             if not self.autopack():
                 # when autopack takes no steps, the names list is still
@@ -1230,9 +1222,7 @@
                 self._save_pack_names()
         else:
             self._new_pack.abort()
-        # forget what names there are - XXX should just refresh them and apply
-        # the delta to our pack list and object maps.
-        self.reset()
+        self.repo._text_knit = None
 
 
 class GraphKnitRevisionStore(KnitRevisionStore):
@@ -1297,16 +1287,6 @@
             access_method=self.repo._packs.signature_index.knit_access)
         return self.repo._signature_knit
 
-    def setup(self):
-        # if knit indices have been handed out, add a mutable
-        # index to them
-        if self.repo._revision_knit is not None:
-            self.repo._revision_knit._index._add_callback = \
-                self.repo._packs.revision_index.add_callback
-        if self.repo._signature_knit is not None:
-            self.repo._signature_knit._index._add_callback = \
-                self.repo._packs.signature_index.add_callback
-
 
 class GraphKnitTextStore(VersionedFileStore):
     """An object to adapt access from VersionedFileStore's to use GraphKnits.
@@ -1372,11 +1352,6 @@
             ids.add(key[0])
         return iter(ids)
 
-    def setup(self):
-        # a reused knit object for commit.
-        self.repo._text_knit = self.get_weave_or_empty(
-            'all-texts', None)
-
 
 class InventoryKnitThunk(object):
     """An object to manage thunking get_inventory_weave to pack based knits."""
@@ -1406,18 +1381,6 @@
             index=knit_index, delta=True, factory=knit.KnitPlainFactory(),
             access_method=self.repo._packs.inventory_index.knit_access)
 
-    def setup(self):
-        pass
-        # we don't bother updating the knit layer, because there is not
-        # defined interface for adding inventories that should need the 
-        # existing knit to be changed - its all behind 'repo.add_inventory'.
-
-        ## # if knit indices have been handed out, add a mutable
-        ## # index to them
-        ## if self.repo._revision_knit is not None:
-        ##     self.repo._revision_knit._index._add_callback = \
-        ##         self.repo._packs.revision_index.add_callback
-
 
 class GraphKnitRepository(KnitRepository):
     """Experimental graph-knit using repository."""
@@ -1461,6 +1424,8 @@
         if self._write_lock_count == 1 or self.control_files._lock_count==1:
             # forget what names there are
             self._packs.reset()
+            # XXX: Better to do an in-memory merge, factor out code from
+            # _save_pack_names.
 
     def _start_write_group(self):
         self._packs._start_write_group()

=== modified file 'bzrlib/tests/test_repository.py'
--- a/bzrlib/tests/test_repository.py	2007-10-17 03:43:25 +0000
+++ b/bzrlib/tests/test_repository.py	2007-10-17 04:37:20 +0000
@@ -815,6 +815,8 @@
                     r2.abort_write_group()
                     raise
                 r2.commit_write_group()
+                # tell r1 to reload from disk
+                r1._packs.reset()
                 # Now both repositories should now about both names
                 r1._packs.ensure_loaded()
                 r2._packs.ensure_loaded()



More information about the bazaar-commits mailing list