Add revlog.strip to truncate away revisions.
authormason@suse.com
Fri, 11 Nov 2005 18:20:24 -0800
changeset 1535 7ae0ce7a3dc4
parent 1534 80a3d6a0af71
child 1538 482b4efdf013
child 1540 8ca9f5b17257
Add revlog.strip to truncate away revisions. This updates the revlog data structures for index and nodemap in place so the .d and .i files don't need to be reread after stripping away a revision.
mercurial/revlog.py
--- a/mercurial/revlog.py	Fri Nov 11 18:20:22 2005 -0800
+++ b/mercurial/revlog.py	Fri Nov 11 18:20:24 2005 -0800
@@ -71,6 +71,9 @@
         self.all = 0
         self.revlog = revlog
 
+    def trunc(self, pos):
+        self.l = pos/self.s
+
     def load(self, pos=None):
         if self.all: return
         if pos is not None:
@@ -104,8 +107,12 @@
         return self.p.index[pos]
     def __getitem__(self, pos):
         return self.p.index[pos] or self.load(pos)
+    def __delitem__(self, pos):
+        del self.p.index[pos]
     def append(self, e):
         self.p.index.append(e)
+    def trunc(self, pos):
+        self.p.trunc(pos)
 
 class lazymap:
     """a lazy version of the node map"""
@@ -140,6 +147,8 @@
                 raise KeyError("node " + hex(key))
     def __setitem__(self, key, val):
         self.p.map[key] = val
+    def __delitem__(self, key):
+        del self.p.map[key]
 
 class RevlogError(Exception): pass
 
@@ -834,6 +843,36 @@
         ifh.close()
         return node
 
+    def strip(self, rev, minlink):
+        if self.count() == 0 or rev >= self.count():
+            return
+
+        # When stripping away a revision, we need to make sure it
+        # does not actually belong to an older changeset.
+        # The minlink parameter defines the oldest revision
+        # we're allowed to strip away.
+        while minlink > self.index[rev][3]:
+            rev += 1
+            if rev >= self.count():
+                return
+
+        # first truncate the files on disk
+        end = self.start(rev)
+        self.opener(self.datafile, "a").truncate(end)
+        end = rev * struct.calcsize(indexformat)
+        self.opener(self.indexfile, "a").truncate(end)
+
+        # then reset internal state in memory to forget those revisions
+        self.cache = None
+        for p in self.index[rev:]:
+            del self.nodemap[p[6]]
+        del self.index[rev:]
+
+        # truncating the lazyindex also truncates the lazymap.
+        if isinstance(self.index, lazyindex):
+            self.index.trunc(end)
+
+
     def checksize(self):
         expected = 0
         if self.count():