mercurial/manifest.py
author Augie Fackler <raf@durin42.com>
Wed, 08 Oct 2014 14:47:30 -0400
changeset 22929 bf69cb09a6c9
parent 22788 160efd225b24
child 22930 1acb81d10eaf
permissions -rw-r--r--
manifest: move manifestdict-to-text encoding to manifest class A future patch will introduce a new format, with a new class.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
     1
# manifest.py - manifest revision class for mercurial
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     2
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9420
diff changeset
     6
# GNU General Public License version 2 or any later version.
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     7
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
     8
from i18n import _
18821
40b4b1f9b7a0 manifestdict: add a method to diff _flags
Siddharth Agarwal <sid0@fb.com>
parents: 18604
diff changeset
     9
import mdiff, parsers, error, revlog, util, dicthelpers
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8225
diff changeset
    10
import array, struct
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
    11
2835
a9f5d4149123 Combine manifest dict and flags dict into a single object
Matt Mackall <mpm@selenic.com>
parents: 2834
diff changeset
    12
class manifestdict(dict):
2857
18cf5349a361 Fix some bugs introduced during the manifest refactoring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2841
diff changeset
    13
    def __init__(self, mapping=None, flags=None):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    14
        if mapping is None:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    15
            mapping = {}
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    16
        if flags is None:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    17
            flags = {}
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
    18
        dict.__init__(self, mapping)
2839
b4f05ecf4ee8 Switch to simpler manifestdict
Matt Mackall <mpm@selenic.com>
parents: 2835
diff changeset
    19
        self._flags = flags
2834
35af2e56f15a manifestflags: eliminate remaining users of direct dict access
Matt Mackall <mpm@selenic.com>
parents: 2833
diff changeset
    20
    def flags(self, f):
2839
b4f05ecf4ee8 Switch to simpler manifestdict
Matt Mackall <mpm@selenic.com>
parents: 2835
diff changeset
    21
        return self._flags.get(f, "")
16646
a1dcd842ce17 localrepo: optimize internode status calls using withflags
Jesse Glick <jesse.glick@oracle.com>
parents: 15657
diff changeset
    22
    def withflags(self):
a1dcd842ce17 localrepo: optimize internode status calls using withflags
Jesse Glick <jesse.glick@oracle.com>
parents: 15657
diff changeset
    23
        return set(self._flags.keys())
6743
86e8187b721a simplify flag handling
Matt Mackall <mpm@selenic.com>
parents: 6389
diff changeset
    24
    def set(self, f, flags):
86e8187b721a simplify flag handling
Matt Mackall <mpm@selenic.com>
parents: 6389
diff changeset
    25
        self._flags[f] = flags
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
    26
    def copy(self):
9416
eecbaac5ca88 manifestdict: remove unnecessary dictionary copy
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9415
diff changeset
    27
        return manifestdict(self, dict.copy(self._flags))
21879
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    28
    def intersectfiles(self, files):
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    29
        '''make a new manifestdict with the intersection of self with files
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    30
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    31
        The algorithm assumes that files is much smaller than self.'''
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    32
        ret = manifestdict()
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    33
        for fn in files:
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    34
            if fn in self:
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    35
                ret[fn] = self[fn]
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    36
                flags = self._flags.get(fn, None)
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    37
                if flags:
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    38
                    ret._flags[fn] = flags
090dcaaf3fff manifestdict: add a new method to intersect with a set of files
Siddharth Agarwal <sid0@fb.com>
parents: 20075
diff changeset
    39
        return ret
18821
40b4b1f9b7a0 manifestdict: add a method to diff _flags
Siddharth Agarwal <sid0@fb.com>
parents: 18604
diff changeset
    40
    def flagsdiff(self, d2):
40b4b1f9b7a0 manifestdict: add a method to diff _flags
Siddharth Agarwal <sid0@fb.com>
parents: 18604
diff changeset
    41
        return dicthelpers.diff(self._flags, d2._flags, "")
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
    42
22929
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
    43
    def text(self):
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
    44
        fl = sorted(self)
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
    45
        _checkforbidden(fl)
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
    46
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
    47
        hex, flags = revlog.hex, self.flags
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
    48
        # if this is changed to support newlines in filenames,
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
    49
        # be sure to check the templates/ dir again (especially *-raw.tmpl)
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
    50
        return ''.join("%s\0%s%s\n" % (f, hex(self[f]), flags(f)) for f in fl)
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
    51
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
    52
def _checkforbidden(l):
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
    53
    """Check filenames for illegal characters."""
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
    54
    for f in l:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
    55
        if '\n' in f or '\r' in f:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
    56
            raise error.RevlogError(
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
    57
                _("'\\n' and '\\r' disallowed in filenames: %r") % f)
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
    58
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
    59
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    60
# apply the changes collected during the bisect loop to our addlist
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    61
# return a delta suitable for addrevision
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
    62
def _addlistdelta(addlist, x):
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    63
    # for large addlist arrays, building a new array is cheaper
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    64
    # than repeatedly modifying the existing one
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    65
    currentposition = 0
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    66
    newaddlist = array.array('c')
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    67
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    68
    for start, end, content in x:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    69
        newaddlist += addlist[currentposition:start]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    70
        if content:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    71
            newaddlist += array.array('c', content)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    72
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    73
        currentposition = end
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    74
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    75
    newaddlist += addlist[currentposition:]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    76
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    77
    deltatext = "".join(struct.pack(">lll", start, end, len(content))
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    78
                   + content for start, end, content in x)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    79
    return deltatext, newaddlist
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    80
22786
079a0ed5ee4a manifest: move manifest parsing to module-level
Augie Fackler <raf@durin42.com>
parents: 22415
diff changeset
    81
def _parse(lines):
079a0ed5ee4a manifest: move manifest parsing to module-level
Augie Fackler <raf@durin42.com>
parents: 22415
diff changeset
    82
    mfdict = manifestdict()
079a0ed5ee4a manifest: move manifest parsing to module-level
Augie Fackler <raf@durin42.com>
parents: 22415
diff changeset
    83
    parsers.parse_manifest(mfdict, mfdict._flags, lines)
079a0ed5ee4a manifest: move manifest parsing to module-level
Augie Fackler <raf@durin42.com>
parents: 22415
diff changeset
    84
    return mfdict
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
    85
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
    86
class manifest(revlog.revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
    87
    def __init__(self, opener):
20075
f8737bce736a manifest: increase lrucache from 3 to 4
Durham Goode <durham@fb.com>
parents: 18821
diff changeset
    88
        # we expect to deal with not more than four revs at a time,
f8737bce736a manifest: increase lrucache from 3 to 4
Durham Goode <durham@fb.com>
parents: 18821
diff changeset
    89
        # during a commit --amend
f8737bce736a manifest: increase lrucache from 3 to 4
Durham Goode <durham@fb.com>
parents: 18821
diff changeset
    90
        self._mancache = util.lrucachedict(4)
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
    91
        revlog.revlog.__init__(self, opener, "00manifest.i")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    92
3196
f3b939444c72 Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents: 3148
diff changeset
    93
    def readdelta(self, node):
7362
6db4a2ccef3a revlog: remove delta function
Matt Mackall <mpm@selenic.com>
parents: 6765
diff changeset
    94
        r = self.rev(node)
22786
079a0ed5ee4a manifest: move manifest parsing to module-level
Augie Fackler <raf@durin42.com>
parents: 22415
diff changeset
    95
        return _parse(mdiff.patchtext(self.revdiff(self.deltaparent(r), r)))
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3196
diff changeset
    96
13711
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
    97
    def readfast(self, node):
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
    98
        '''use the faster of readdelta or read'''
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
    99
        r = self.rev(node)
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 13711
diff changeset
   100
        deltaparent = self.deltaparent(r)
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 13711
diff changeset
   101
        if deltaparent != revlog.nullrev and deltaparent in self.parentrevs(r):
13711
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   102
            return self.readdelta(node)
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   103
        return self.read(node)
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
   104
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   105
    def read(self, node):
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   106
        if node == revlog.nullid:
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   107
            return manifestdict() # don't upset local cache
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   108
        if node in self._mancache:
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   109
            return self._mancache[node][0]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   110
        text = self.revision(node)
9414
65dc516363ee manifest: simplify cache handling, use a unique cache
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9413
diff changeset
   111
        arraytext = array.array('c', text)
22786
079a0ed5ee4a manifest: move manifest parsing to module-level
Augie Fackler <raf@durin42.com>
parents: 22415
diff changeset
   112
        mapping = _parse(text)
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   113
        self._mancache[node] = (mapping, arraytext)
2835
a9f5d4149123 Combine manifest dict and flags dict into a single object
Matt Mackall <mpm@selenic.com>
parents: 2834
diff changeset
   114
        return mapping
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   115
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   116
    def _search(self, m, s, lo=0, hi=None):
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   117
        '''return a tuple (start, end) that says where to find s within m.
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   118
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   119
        If the string is found m[start:end] are the line containing
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   120
        that string.  If start == end the string was not found and
17426
9724f8f8850b delete some dead comments and docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 16683
diff changeset
   121
        they indicate the proper sorted insertion point.
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   122
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   123
        m should be a buffer or a string
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   124
        s is a string'''
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   125
        def advance(i, c):
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   126
            while i < lenm and m[i] != c:
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   127
                i += 1
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   128
            return i
7405
f1944e74e83c manifest: fix _search() corner-case
Patrick Mezard <pmezard@gmail.com>
parents: 7362
diff changeset
   129
        if not s:
f1944e74e83c manifest: fix _search() corner-case
Patrick Mezard <pmezard@gmail.com>
parents: 7362
diff changeset
   130
            return (lo, lo)
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   131
        lenm = len(m)
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   132
        if not hi:
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   133
            hi = lenm
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   134
        while lo < hi:
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   135
            mid = (lo + hi) // 2
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   136
            start = mid
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   137
            while start > 0 and m[start - 1] != '\n':
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   138
                start -= 1
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   139
            end = advance(start, '\0')
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   140
            if m[start:end] < s:
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   141
                # we know that after the null there are 40 bytes of sha1
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   142
                # this translates to the bisect lo = mid + 1
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   143
                lo = advance(end + 40, '\n') + 1
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   144
            else:
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   145
                # this translates to the bisect hi = mid
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   146
                hi = start
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   147
        end = advance(lo, '\0')
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   148
        found = m[lo:end]
11763
69e0bcf36961 manifest: removed usage of the global cmp function
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
   149
        if s == found:
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   150
            # we know that after the null there are 40 bytes of sha1
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   151
            end = advance(end + 40, '\n')
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   152
            return (lo, end + 1)
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   153
        else:
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   154
            return (lo, lo)
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   155
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   156
    def find(self, node, f):
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   157
        '''look up entry for a single file efficiently.
4159
a896607d3ec3 fix manifest.find
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3891
diff changeset
   158
        return (node, flags) pair if found, (None, None) if not.'''
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   159
        if node in self._mancache:
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   160
            mapping = self._mancache[node][0]
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   161
            return mapping.get(f), mapping.flags(f)
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   162
        text = self.revision(node)
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   163
        start, end = self._search(text, f)
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   164
        if start == end:
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   165
            return None, None
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   166
        l = text[start:end]
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   167
        f, n = l.split('\0')
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   168
        return revlog.bin(n[:40]), n[40:-1]
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   169
22787
4a13849ca359 manifest: simplify manifest.add() by making args required
Augie Fackler <raf@durin42.com>
parents: 22786
diff changeset
   170
    def add(self, map, transaction, link, p1, p2, added, removed):
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   171
        if p1 in self._mancache:
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   172
            # If our first parent is in the manifest cache, we can
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   173
            # compute a delta here using properties we know about the
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   174
            # manifest up-front, which may save time later for the
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   175
            # revlog layer.
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   176
            addlist = self._mancache[p1][1]
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   177
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   178
            _checkforbidden(added)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   179
            # combine the changed lists into one list for sorting
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   180
            work = [(x, False) for x in added]
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   181
            work.extend((x, True) for x in removed)
17428
72803c8edaa4 avoid using abbreviations that look like spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17426
diff changeset
   182
            # this could use heapq.merge() (from Python 2.6+) or equivalent
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   183
            # since the lists are already sorted
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   184
            work.sort()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   185
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   186
            delta = []
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   187
            dstart = None
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   188
            dend = None
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   189
            dline = [""]
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   190
            start = 0
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   191
            # zero copy representation of addlist as a buffer
15657
d976b1ef6760 util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents: 14632
diff changeset
   192
            addbuf = util.buffer(addlist)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   193
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   194
            # start with a readonly loop that finds the offset of
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   195
            # each line and creates the deltas
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   196
            for f, todelete in work:
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   197
                # bs will either be the index of the item or the insert point
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   198
                start, end = self._search(addbuf, f, start)
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   199
                if not todelete:
14632
4819241ec1ad manifest: use "\0" instead of "\000"
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   200
                    l = "%s\0%s%s\n" % (f, revlog.hex(map[f]), map.flags(f))
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   201
                else:
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   202
                    if start == end:
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   203
                        # item we want to delete was not found, error out
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   204
                        raise AssertionError(
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   205
                                _("failed to remove %s from manifest") % f)
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   206
                    l = ""
13031
3da456d0c885 code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 12011
diff changeset
   207
                if dstart is not None and dstart <= start and dend >= start:
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   208
                    if dend < end:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   209
                        dend = end
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   210
                    if l:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   211
                        dline.append(l)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   212
                else:
13031
3da456d0c885 code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 12011
diff changeset
   213
                    if dstart is not None:
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   214
                        delta.append([dstart, dend, "".join(dline)])
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   215
                    dstart = start
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   216
                    dend = end
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   217
                    dline = [l]
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   218
13031
3da456d0c885 code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 12011
diff changeset
   219
            if dstart is not None:
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   220
                delta.append([dstart, dend, "".join(dline)])
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   221
            # apply the delta to the addlist, and get a delta for addrevision
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   222
            deltatext, addlist = _addlistdelta(addlist, delta)
17983
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   223
            cachedelta = (self.rev(p1), deltatext)
9414
65dc516363ee manifest: simplify cache handling, use a unique cache
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9413
diff changeset
   224
            arraytext = addlist
15657
d976b1ef6760 util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents: 14632
diff changeset
   225
            text = util.buffer(arraytext)
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   226
        else:
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   227
            # The first parent manifest isn't already loaded, so we'll
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   228
            # just encode a fulltext of the manifest and pass that
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   229
            # through to the revlog layer, and let it handle the delta
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   230
            # process.
22929
bf69cb09a6c9 manifest: move manifestdict-to-text encoding to manifest class
Augie Fackler <raf@durin42.com>
parents: 22788
diff changeset
   231
            text = map.text()
22788
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   232
            arraytext = array.array('c', text)
160efd225b24 manifest: rearrange add() method and add comments for clarity
Augie Fackler <raf@durin42.com>
parents: 22787
diff changeset
   233
            cachedelta = None
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   234
9420
d0db168136dc manifest/revlog: do not let the revlog cache mutable objects
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9416
diff changeset
   235
        n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   236
        self._mancache[n] = (map, arraytext)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   237
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   238
        return n