On Sat, Dec 24, 2016 at 9:36 AM, Remi Chaintron <r...@fb.com> wrote: > # HG changeset patch > # User Remi Chaintron <r...@fb.com> > # Date 1482596881 18000 > # Sat Dec 24 11:28:01 2016 -0500 > # Node ID c94d2907a470ca03b4a4a8da514b66d2f8952bce > # Parent b1d220e584e6fc861a40a5aeefa0c3b19ae09126 > revlog: processflags() > > diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py > --- a/mercurial/bundlerepo.py > +++ b/mercurial/bundlerepo.py > @@ -148,7 +148,9 @@ > delta = self._chunk(chain.pop()) > text = mdiff.patches(text, [delta]) > > - self.checkhash(text, node, rev=rev) > + text, validatehash = self.processflags(text, self.flags(rev), > raw=raw) > + if validatehash is True: > + self.checkhash(text, node, rev=rev) > self._cache = (node, rev, text) > return text > > diff --git a/mercurial/revlog.py b/mercurial/revlog.py > --- a/mercurial/revlog.py > +++ b/mercurial/revlog.py > @@ -56,6 +56,10 @@ > REVIDX_ISCENSORED = (1 << 15) # revision has censor metadata, must be > verified > REVIDX_DEFAULT_FLAGS = 0 > REVIDX_KNOWN_FLAGS = REVIDX_ISCENSORED > +# stable order in which flags need to be processed and their transforms > applied > +REVIDX_FLAGS_ORDER = [ > + REVIDX_ISCENSORED, > +] > > # max size of revlog with inline data > _maxinline = 131072 > @@ -65,6 +69,33 @@ > LookupError = error.LookupError > CensoredNodeError = error.CensoredNodeError > > +# 'flagtransform' namedtuple type for extensions to use to register > transforms > +# on revlog flags. > +# - The apply transform will be used as a default behavior. > +# - The applyraw transform will be used for changegroup generation and > debug > +# methods. > +flagtransform = collections.namedtuple('flagtransform', ['apply', > 'applyraw']) >
String literals in namedtuple declarations need u'' prefixes to prevent Python 3 from barfing. This can likely be done as a follow-up, since Python 3 isn't officially supported. > +# Store flag transforms (cf. 'addflagtransform()' to register) > +_flagtransforms = { } > + > +def addflagtransform(flag, transform): > + """Register transforms on revision data flags. > + > + Invariant: > + - Flags need to be defined in REVIDX_KNOWN_FLAGS and > REVIDX_FLAGS_ORDER. > + - Only one transform can be registered on a specific flag. > + - the transform must be of type 'flagtransform' > + """ > + if not flag & REVIDX_KNOWN_FLAGS: > + raise error.Abort(_("cannot register transform on unknown flag.")) > + if not flag in REVIDX_FLAGS_ORDER: > + raise error.Abort(_("flag need to be defined in > REVIDX_FLAGS_ORDER.")) > + if _flagtransforms.get(flag, None) is not None: > + raise error.Abort(_("cannot register multiple transforms on > flag.")) > + if not isinstance(transform, flagtransform): > + raise error.Abort(_("invalid transform type.")) > + _flagtransforms[flag] = transform > + > def getoffset(q): > return int(q >> 16) > > @@ -1248,7 +1279,11 @@ > bins = bins[1:] > > text = mdiff.patches(text, bins) > - self.checkhash(text, node, rev=rev) > + > + text, validatehash = self.processflags(text, self.flags(rev), > raw=raw) > + if validatehash: > + self.checkhash(text, node, rev=rev) > + > self._cache = (node, rev, text) > return text > > @@ -1260,6 +1295,56 @@ > """ > return hash(text, p1, p2) > > + def processflags(self, text, flags, raw=False, reverse=False): > + """Process revision flags and apply registered transforms. > + > + ``text`` - the revision data to process > + ``flags`` - the revision flags > + ``raw`` - an optional argument describing if the raw transform > should be > + applied. > + ``reverse`` - an optional argument describing whether the flags > should > + be processed in order or reverse order. > + > + This method processes the flags in the order (or reverse order if > + ``reverse`` is False) defined by REVIDX_FLAGS_ORDER, applying the > + transforms registered for present flags. The order of flags > defined in > + REVIDX_FLAGS_ORDER needs to be stable for non-commutative > + operations. > + > + If a ``flagtransform`` namedtuple has been registered on a flag, > the > + ``raw`` argument is used to determine which transform apply. If > ``raw`` > + is True, the ``applyraw`` field is used, ``apply`` if not > (default). > + If the ``raw`` argument is set, it indicates we are currently > processing > + flags in the context of changegroup generation or debug commands. > + > + Returns a 2-tuple of ``(text, validatehash)`` where ``text`` is > the > + processed text and ``validatehash`` is a bool indicating whether > the > + returned text should be checked for hash integrity. > + """ > + # Check all flags are known. > + if flags & ~REVIDX_KNOWN_FLAGS: > + raise RevlogError(_('incompatible revision flag %x') % > + (flags & ~REVIDX_KNOWN_FLAGS)) > + validatehash = True > + # Depending on the operation (read or write), the order might be > + # reversed due to non-commutative transforms. > + orderedflags = REVIDX_FLAGS_ORDER > + if reverse: > + orderedflags = reversed(orderedflags) > + > + for flag in orderedflags: > + # If a transform has been registered for a known flag, apply > and > + # update result tuple. > + if flag & flags: > + transform = _flagtransforms.get(flag, None) > + if transform is not None: > + apply, applyraw = transform > + f = apply > + if raw: > + f = applyraw > + text, validatehash = f(self, text) > + return text, validatehash > + > def checkhash(self, text, node, p1=None, p2=None, rev=None): > """Check node hash integrity. > > @@ -1447,7 +1532,11 @@ > btext[0] = mdiff.patch(basetext, delta) > > try: > - self.checkhash(btext[0], node, p1=p1, p2=p2) > + btext[0], validatehash = self.processflags(btext[0], > flags, > + raw=raw, > + reverse=True) > + if validatehash is True: > + self.checkhash(btext[0], node, p1=p1, p2=p2) > if flags & REVIDX_ISCENSORED: > raise RevlogError(_('node %s is not censored') % node) > except CensoredNodeError: > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >
_______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel