tests/simplestorerepo.py
changeset 41157 c4639fdae1b9
parent 40389 1b183edbb68e
child 41158 ad51e6117095
--- a/tests/simplestorerepo.py	Tue Dec 04 11:22:31 2018 -0800
+++ b/tests/simplestorerepo.py	Mon Jan 07 18:22:20 2019 -0500
@@ -66,17 +66,24 @@
     pass
 
 @interfaceutil.implementer(repository.irevisiondelta)
-@attr.s(slots=True, frozen=True)
+@attr.s(slots=True)
 class simplestorerevisiondelta(object):
     node = attr.ib()
     p1node = attr.ib()
     p2node = attr.ib()
     basenode = attr.ib()
-    linknode = attr.ib()
     flags = attr.ib()
     baserevisionsize = attr.ib()
     revision = attr.ib()
     delta = attr.ib()
+    linknode = attr.ib(default=None)
+
+@interfaceutil.implementer(repository.iverifyproblem)
+@attr.s(frozen=True)
+class simplefilestoreproblem(object):
+    warning = attr.ib(default=None)
+    error = attr.ib(default=None)
+    node = attr.ib(default=None)
 
 @interfaceutil.implementer(repository.ifilestorage)
 class filestorage(object):
@@ -192,6 +199,13 @@
 
         return self._indexbyrev[rev][b'node']
 
+    def hasnode(self, node):
+        validatenode(node)
+        return node in self._indexbynode
+
+    def censorrevision(self, tr, censornode, tombstone=b''):
+        raise NotImplementedError('TODO')
+
     def lookup(self, node):
         if isinstance(node, int):
             return self.node(node)
@@ -290,7 +304,11 @@
             raise simplestoreerror(_("integrity check failed on %s") %
                 self._path)
 
-    def revision(self, node, raw=False):
+    def revision(self, nodeorrev, raw=False):
+        if isinstance(nodeorrev, int):
+            node = self.node(nodeorrev)
+        else:
+            node = nodeorrev
         validatenode(node)
 
         if node == nullid:
@@ -409,6 +427,44 @@
 
         return [b'/'.join((self._storepath, f)) for f in entries]
 
+    def storageinfo(self, exclusivefiles=False, sharedfiles=False,
+                    revisionscount=False, trackedsize=False,
+                    storedsize=False):
+        # TODO do a real implementation of this
+        return {
+            'exclusivefiles': [],
+            'sharedfiles': [],
+            'revisionscount': len(self),
+            'trackedsize': 0,
+            'storedsize': None,
+        }
+
+    def verifyintegrity(self, state):
+        state['skipread'] = set()
+        for rev in self:
+            node = self.node(rev)
+            try:
+                self.revision(node)
+            except Exception as e:
+                yield simplefilestoreproblem(
+                    error='unpacking %s: %s' % (node, e),
+                    node=node)
+                state['skipread'].add(node)
+
+    def emitrevisions(self, nodes, nodesorder=None, revisiondata=False,
+                      assumehaveparentrevisions=False,
+                      deltamode=repository.CG_DELTAMODE_STD):
+        # TODO this will probably break on some ordering options.
+        nodes = [n for n in nodes if n != nullid]
+        if not nodes:
+            return
+        for delta in storageutil.emitrevisions(
+                self, nodes, nodesorder, simplestorerevisiondelta,
+                revisiondata=revisiondata,
+                assumehaveparentrevisions=assumehaveparentrevisions,
+                deltamode=deltamode):
+            yield delta
+
     def add(self, text, meta, transaction, linkrev, p1, p2):
         if meta or text.startswith(b'\1\n'):
             text = storageutil.packmeta(meta, text)
@@ -489,15 +545,26 @@
 
             if addrevisioncb:
                 addrevisioncb(self, node)
+        return nodes
 
-        return nodes
+    def _headrevs(self):
+        # Assume all revisions are heads by default.
+        revishead = {rev: True for rev in self._indexbyrev}
+
+        for rev, entry in self._indexbyrev.items():
+            # Unset head flag for all seen parents.
+            revishead[self.rev(entry[b'p1'])] = False
+            revishead[self.rev(entry[b'p2'])] = False
+
+        return [rev for rev, ishead in sorted(revishead.items())
+                if ishead]
 
     def heads(self, start=None, stop=None):
         # This is copied from revlog.py.
         if start is None and stop is None:
             if not len(self):
                 return [nullid]
-            return [self.node(r) for r in self.headrevs()]
+            return [self.node(r) for r in self._headrevs()]
 
         if start is None:
             start = nullid
@@ -537,41 +604,9 @@
         return c
 
     def getstrippoint(self, minlink):
-
-        # This is largely a copy of revlog.getstrippoint().
-        brokenrevs = set()
-        strippoint = len(self)
-
-        heads = {}
-        futurelargelinkrevs = set()
-        for head in self.heads():
-            headlinkrev = self.linkrev(self.rev(head))
-            heads[head] = headlinkrev
-            if headlinkrev >= minlink:
-                futurelargelinkrevs.add(headlinkrev)
-
-        # This algorithm involves walking down the rev graph, starting at the
-        # heads. Since the revs are topologically sorted according to linkrev,
-        # once all head linkrevs are below the minlink, we know there are
-        # no more revs that could have a linkrev greater than minlink.
-        # So we can stop walking.
-        while futurelargelinkrevs:
-            strippoint -= 1
-            linkrev = heads.pop(strippoint)
-
-            if linkrev < minlink:
-                brokenrevs.add(strippoint)
-            else:
-                futurelargelinkrevs.remove(linkrev)
-
-            for p in self.parentrevs(strippoint):
-                if p != nullrev:
-                    plinkrev = self.linkrev(p)
-                    heads[p] = plinkrev
-                    if plinkrev >= minlink:
-                        futurelargelinkrevs.add(plinkrev)
-
-        return strippoint, brokenrevs
+        return storageutil.resolvestripinfo(
+            minlink, len(self) - 1, self._headrevs(), self.linkrev,
+            self.parentrevs)
 
     def strip(self, minlink, transaction):
         if not len(self):
@@ -631,9 +666,9 @@
 def featuresetup(ui, supported):
     supported.add(REQUIREMENT)
 
-def newreporequirements(orig, ui):
+def newreporequirements(orig, ui, createopts):
     """Modifies default requirements for new repos to use the simple store."""
-    requirements = orig(ui)
+    requirements = orig(ui, createopts)
 
     # These requirements are only used to affect creation of the store
     # object. We have our own store. So we can remove them.
@@ -665,5 +700,5 @@
 
     extensions.wrapfunction(localrepo, 'newreporequirements',
                             newreporequirements)
-    extensions.wrapfunction(store, 'store', makestore)
+    extensions.wrapfunction(localrepo, 'makestore', makestore)
     extensions.wrapfunction(verify.verifier, '__init__', verifierinit)