[PATCH 02 of 12] Add overlay index and map for use with overlay revlogs

Brendan Cully brendan at kublai.com
Tue Jan 2 15:42:14 CST 2007


# HG changeset patch
# User Brendan Cully <brendan at kublai.com>
# Date 1167777079 18000
# Node ID b0145149b0692405f9aff4181c33ae9dc56188a1
# Parent  0ececd8212ea7acd43accf4fbdee8a5ca64ea0e0
Add overlay index and map for use with overlay revlogs.

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -244,6 +244,35 @@ class lazyindex(object):
     def append(self, e):
         self.p.index.append(e)
 
+class overlayindex(object):
+    "partial index with a parent"
+    def __init__(self, index, parent, start):
+        self.index = index
+        self.parent = parent
+        self.start = start
+    def __len__(self):
+        return self.start + len(self.index)
+    def __getitem__(self, i):
+        if i < self.start:
+            return self.parent[i]
+        return self.index[self._offset(i)]
+    def __setitem__(self, i, val):
+        if i < self.start:
+            self.parent[i] = val
+        else:
+            self.index[self._offset(i)] = val
+    def __delitem__(self, i):
+        if i < self.start:
+            del self.parent[i]
+        else:
+            del self.index[self._offset(i)]
+    def _offset(self, i):
+        if isinstance(i, slice):
+            return slice(i.start - self.start, i.step, i.stop)
+        return i - self.start
+    def append(self, val):
+        self.index.append(val)
+
 class lazymap(object):
     """a lazy version of the node map"""
     def __init__(self, parser):
@@ -281,6 +310,38 @@ class lazymap(object):
     def __delitem__(self, key):
         del self.p.map[key]
 
+class overlaymap(object):
+    def __init__(self, nodemap, pmap, start):
+        self.nodemap = nodemap
+        self.pmap = pmap
+        self.start = start
+        if nullid in self.nodemap:
+            del self.nodemap[nullid]
+    def __contains__(self, key):
+        if key in self.nodemap:
+            return True
+        return key in self.pmap
+    def __iter__(self):
+        for i in self.pmap:
+            yield i
+        for i in self.nodemap:
+            if i != nullid:
+                yield i
+    def __getitem__(self, key):
+        if key in self.nodemap:
+            return self.nodemap[key] + self.start
+        return self.pmap[key]
+    def __setitem__(self, key, val):
+        if key in self.pmap:
+            self.pmap[key] = val
+        else:
+            self.nodemap[key] = val
+    def __delitem__(self, key):
+        if key in self.nodemap:
+            del self.nodemap[key]
+        else:
+            del self.pmap[key]
+
 class RevlogError(Exception): pass
 class LookupError(RevlogError): pass
 
@@ -310,7 +371,7 @@ class revlog(object):
     for locking while reading.
     """
     def __init__(self, opener, indexfile, datafile,
-                 defversion=REVLOG_DEFAULT_VERSION):
+                 defversion=REVLOG_DEFAULT_VERSION, parent=None):
         """
         create a revlog object
 
@@ -325,6 +386,8 @@ class revlog(object):
         self.cache = None
         self.chunkcache = None
         self.defversion = defversion
+        self.parent = parent
+        self.startrev = 0
         self.load()
 
     def load(self):
@@ -389,9 +452,19 @@ class revlog(object):
                 if flags & REVLOGNGOVERLAY:
                     self.startrev = self.base(0)
                 self.index[0] = e
-        else:
-            self.nodemap = {nullid: nullrev}
-            self.index = []
+            if flags & REVLOGNGOVERLAY and self.parent:
+                self.index = overlayindex(self.index, self.parent.index,
+                                          self.startrev)
+                self.nodemap = overlaymap(self.nodemap, self.parent.nodemap,
+                                          self.startrev)
+        else:
+            if self.parent:
+                self.startrev = self.parent.count()
+                self.nodemap = self.parent.nodemap
+                self.index = self.parent.index
+            else:
+                self.nodemap = {nullid: nullrev}
+                self.index = []
 
 
     def parseindex(self, fp, st):
@@ -902,6 +975,9 @@ class revlog(object):
         text = None
         rev = self.rev(node)
         base = self.base(rev)
+        
+        if rev < self.startrev:
+            return self.parent.revision(node)
 
         if self.inlinedata():
             # we probably have the whole chunk cached


More information about the Mercurial-devel mailing list