mercurial/manifest.py
author Siddharth Agarwal <sid0@fb.com>
Sat, 09 Feb 2013 15:43:02 +0000
changeset 18604 a1141f04e368
parent 17983 c64e646af81e
child 18821 40b4b1f9b7a0
permissions -rw-r--r--
manifest: use a size 3 LRU cache to store parsed manifests Previously, the manifest cache would store the last manifest parsed. We could run into situations with operations like update where we would try parsing the manifest for a revision r1, then r2, then r1 again. This increases the cache size to 3 to avoid that bit of performance fragility.
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 _
15657
d976b1ef6760 util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents: 14632
diff changeset
     9
import mdiff, parsers, error, revlog, util
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))
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
    28
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
    29
class manifest(revlog.revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
    30
    def __init__(self, opener):
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
    31
        # we expect to deal with not more than three revs at a time in merge
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
    32
        self._mancache = util.lrucachedict(3)
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
    33
        revlog.revlog.__init__(self, opener, "00manifest.i")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    34
4995
e45fc5d03798 manifest: speed up creation of the manifestdict
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    35
    def parse(self, lines):
e45fc5d03798 manifest: speed up creation of the manifestdict
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    36
        mfdict = manifestdict()
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents: 6212
diff changeset
    37
        parsers.parse_manifest(mfdict, mfdict._flags, lines)
4995
e45fc5d03798 manifest: speed up creation of the manifestdict
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    38
        return mfdict
3196
f3b939444c72 Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents: 3148
diff changeset
    39
f3b939444c72 Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents: 3148
diff changeset
    40
    def readdelta(self, node):
7362
6db4a2ccef3a revlog: remove delta function
Matt Mackall <mpm@selenic.com>
parents: 6765
diff changeset
    41
        r = self.rev(node)
12011
f38b0a3308b6 deltaparent(): don't return nullrev for a revision containing a full snapshot
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11962
diff changeset
    42
        return self.parse(mdiff.patchtext(self.revdiff(self.deltaparent(r), r)))
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3196
diff changeset
    43
13711
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
    44
    def readfast(self, node):
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
    45
        '''use the faster of readdelta or read'''
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
    46
        r = self.rev(node)
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 13711
diff changeset
    47
        deltaparent = self.deltaparent(r)
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 13711
diff changeset
    48
        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
    49
            return self.readdelta(node)
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
    50
        return self.read(node)
ed913fd7837b manifest: add readfast method
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
    51
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    52
    def read(self, node):
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
    53
        if node == revlog.nullid:
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
    54
            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
    55
        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
    56
            return self._mancache[node][0]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    57
        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
    58
        arraytext = array.array('c', text)
4995
e45fc5d03798 manifest: speed up creation of the manifestdict
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    59
        mapping = self.parse(text)
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
    60
        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
    61
        return mapping
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    62
2320
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
    63
    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
    64
        '''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
    65
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
    66
        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
    67
        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
    68
        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
    69
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
    70
        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
    71
        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
    72
        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
    73
            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
    74
                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
    75
            return i
7405
f1944e74e83c manifest: fix _search() corner-case
Patrick Mezard <pmezard@gmail.com>
parents: 7362
diff changeset
    76
        if not s:
f1944e74e83c manifest: fix _search() corner-case
Patrick Mezard <pmezard@gmail.com>
parents: 7362
diff changeset
    77
            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
    78
        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
    79
        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
    80
            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
    81
        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
    82
            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
    83
            start = mid
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    84
            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
    85
                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
    86
            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
    87
            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
    88
                # 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
    89
                # 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
    90
                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
    91
            else:
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
    92
                # 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
    93
                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
    94
        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
    95
        found = m[lo:end]
11763
69e0bcf36961 manifest: removed usage of the global cmp function
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
    96
        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
    97
            # 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
    98
            end = advance(end + 40, '\n')
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    99
            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
   100
        else:
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   101
            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
   102
dbdce3b99988 fix parsing of tags. make parse errors useful. add new tag tests.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2142
diff changeset
   103
    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
   104
        '''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
   105
        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
   106
        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
   107
            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
   108
            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
   109
        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
   110
        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
   111
        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
   112
            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
   113
        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
   114
        f, n = l.split('\0')
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   115
        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
   116
2841
e3fb4223e750 Remove manifest.readflags
Matt Mackall <mpm@selenic.com>
parents: 2839
diff changeset
   117
    def add(self, map, transaction, link, p1=None, p2=None,
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   118
            changed=None):
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   119
        # apply the changes collected during the bisect loop to our addlist
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   120
        # return a delta suitable for addrevision
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   121
        def addlistdelta(addlist, x):
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
   122
            # for large addlist arrays, building a new array is cheaper
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   123
            # than repeatedly modifying the existing one
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   124
            currentposition = 0
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   125
            newaddlist = array.array('c')
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   126
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   127
            for start, end, content in x:
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   128
                newaddlist += addlist[currentposition:start]
9413
a5adf55ee533 manifest.add(): simplify with iterators and generator expressions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8390
diff changeset
   129
                if content:
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
   130
                    newaddlist += array.array('c', content)
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   131
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   132
                currentposition = end
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   133
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   134
            newaddlist += addlist[currentposition:]
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   135
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   136
            deltatext = "".join(struct.pack(">lll", start, end, len(content))
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16646
diff changeset
   137
                           + content for start, end, content in x)
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
   138
            return deltatext, newaddlist
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   139
6765
be142cb994ff manifest: make checkforbidden take a list
Matt Mackall <mpm@selenic.com>
parents: 6762
diff changeset
   140
        def checkforbidden(l):
be142cb994ff manifest: make checkforbidden take a list
Matt Mackall <mpm@selenic.com>
parents: 6762
diff changeset
   141
            for f in l:
be142cb994ff manifest: make checkforbidden take a list
Matt Mackall <mpm@selenic.com>
parents: 6762
diff changeset
   142
                if '\n' in f or '\r' in f:
7633
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7405
diff changeset
   143
                    raise error.RevlogError(
8077
d051342f1ad1 manifest: improve error message about newlines in filenames
Greg Ward <greg-hg@gerg.ca>
parents: 7634
diff changeset
   144
                        _("'\\n' and '\\r' disallowed in filenames: %r") % f)
3607
f4c9bb4ad7b1 issue352: disallow '\n' and '\r' in filenames (dirstate and manifest)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3223
diff changeset
   145
9414
65dc516363ee manifest: simplify cache handling, use a unique cache
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9413
diff changeset
   146
        # if we're using the cache, make sure it is valid and
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   147
        # parented by the same node we're diffing against
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   148
        if not (changed and p1 and (p1 in self._mancache)):
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 8077
diff changeset
   149
            files = sorted(map)
6765
be142cb994ff manifest: make checkforbidden take a list
Matt Mackall <mpm@selenic.com>
parents: 6762
diff changeset
   150
            checkforbidden(files)
3607
f4c9bb4ad7b1 issue352: disallow '\n' and '\r' in filenames (dirstate and manifest)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3223
diff changeset
   151
1651
cf40d2a30fef Fix comment syntax
Matt Mackall <mpm@selenic.com>
parents: 1650
diff changeset
   152
            # if this is changed to support newlines in filenames,
cf40d2a30fef Fix comment syntax
Matt Mackall <mpm@selenic.com>
parents: 1650
diff changeset
   153
            # be sure to check the templates/ dir again (especially *-raw.tmpl)
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
   154
            hex, flags = revlog.hex, map.flags
14632
4819241ec1ad manifest: use "\0" instead of "\000"
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   155
            text = ''.join("%s\0%s%s\n" % (f, hex(map[f]), flags(f))
9420
d0db168136dc manifest/revlog: do not let the revlog cache mutable objects
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9416
diff changeset
   156
                           for f in files)
d0db168136dc manifest/revlog: do not let the revlog cache mutable objects
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9416
diff changeset
   157
            arraytext = array.array('c', text)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   158
            cachedelta = None
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   159
        else:
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   160
            added, removed = changed
18604
a1141f04e368 manifest: use a size 3 LRU cache to store parsed manifests
Siddharth Agarwal <sid0@fb.com>
parents: 17983
diff changeset
   161
            addlist = self._mancache[p1][1]
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   162
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   163
            checkforbidden(added)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   164
            # 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
   165
            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
   166
            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
   167
            # 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
   168
            # since the lists are already sorted
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   169
            work.sort()
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   170
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   171
            delta = []
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   172
            dstart = None
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   173
            dend = None
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   174
            dline = [""]
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   175
            start = 0
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   176
            # 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
   177
            addbuf = util.buffer(addlist)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   178
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   179
            # start with a readonly loop that finds the offset of
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   180
            # 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
   181
            for f, todelete in work:
741
156dc2f3be7f Fix some line wrapping
mpm@selenic.com
parents: 740
diff changeset
   182
                # 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
   183
                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
   184
                if not todelete:
14632
4819241ec1ad manifest: use "\0" instead of "\000"
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   185
                    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
   186
                else:
9415
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   187
                    if start == end:
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   188
                        # 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
   189
                        raise AssertionError(
e0cc9fa2a576 manifest.add(): cleanup worklist construction and iteration
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9414
diff changeset
   190
                                _("failed to remove %s from manifest") % f)
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   191
                    l = ""
13031
3da456d0c885 code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 12011
diff changeset
   192
                if dstart is not None and dstart <= start and dend >= start:
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   193
                    if dend < end:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   194
                        dend = end
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   195
                    if l:
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   196
                        dline.append(l)
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   197
                else:
13031
3da456d0c885 code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 12011
diff changeset
   198
                    if dstart is not None:
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   199
                        delta.append([dstart, dend, "".join(dline)])
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   200
                    dstart = start
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   201
                    dend = end
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   202
                    dline = [l]
644
6ebe118280bd Performance enhancements for manifest.add()
mason@suse.com
parents: 639
diff changeset
   203
13031
3da456d0c885 code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 12011
diff changeset
   204
            if dstart is not None:
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   205
                delta.append([dstart, dend, "".join(dline)])
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   206
            # apply the delta to the addlist, and get a delta for addrevision
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
   207
            deltatext, addlist = addlistdelta(addlist, delta)
c64e646af81e commit: increase perf by building a new addlist instead of editing the old one
Durham Goode <durham@fb.com>
parents: 17428
diff changeset
   208
            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
   209
            arraytext = addlist
15657
d976b1ef6760 util: don't mess with builtins to emulate buffer()
Matt Mackall <mpm@selenic.com>
parents: 14632
diff changeset
   210
            text = util.buffer(arraytext)
1534
80a3d6a0af71 Optimize manifest.add
mason@suse.com
parents: 1451
diff changeset
   211
9420
d0db168136dc manifest/revlog: do not let the revlog cache mutable objects
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9416
diff changeset
   212
        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
   213
        self._mancache[n] = (map, arraytext)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   214
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   215
        return n