diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -52,6 +52,7 @@ pycompat, repository, repoview, + revlogstore, revset, revsetlang, scmutil, @@ -479,6 +480,8 @@ else: # standard vfs self.svfs.audit = self._getsvfsward(self.svfs.audit) self._applyopenerreqs() + self.filesstore = revlogstore.revlogfilesstore(self.svfs) + if create: self._writerequirements() diff --git a/mercurial/repository.py b/mercurial/repository.py --- a/mercurial/repository.py +++ b/mercurial/repository.py @@ -266,3 +266,33 @@ class legacypeer(peer, _baselegacywirecommands): """peer but with support for legacy wire protocol commands.""" + +class basefilesstore(object): + """Storage interface for repository files data. + + This interface defines mechanisms to access repository files data in a + storage agnostic manner. The goal of this interface is to abstract storage + implementations so implementation details of storage don't leak into + higher-level repository consumers. + """ + + __metaclass__ = abc.ABCMeta + + def resolvefilesdata(self, entries): + """Resolve the fulltext data for an iterable of files. + + Each entry is defined by a 2-tuple of (path, node). + + The method is a generator that emits results as they become available. + Each emitted item is a 4-tuple of (result, path, node, data), where + the first element can be one of the following to represent the operation + result for this request: + + ok + Successfully resolved fulltext data. Data field is a bytes-like + object. + missing + Data for this item not found. Data field is ``None``. + censored + Data for this revision is censored. Data field is ``None``. + """ diff --git a/mercurial/revlogstore.py b/mercurial/revlogstore.py new file mode 100644 --- /dev/null +++ b/mercurial/revlogstore.py @@ -0,0 +1,37 @@ +# revlogstore.py - storage interface for repositories using revlog storage +# +# Copyright 2018 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +from __future__ import absolute_import + +from . import ( + error, + filelog, + repository, +) + +class revlogfilesstore(repository.basefilesstore): + """Files storage layer using revlogs for files storage.""" + + def __init__(self, svfs): + self._svfs = svfs + + def resolvefilesdata(self, entries): + for path, node in entries: + fl = filelog.filelog(self._svfs, path) + + try: + rev = fl.rev(node) + except error.LookupError: + yield 'missing', path, node, None + continue + + if fl.iscensored(rev): + yield 'censored', path, node, None + continue + + data = fl.read(node) + yield 'ok', path, node, data