mercurial/manifest.py
author Jun Wu <quark@fb.com>
Sat, 22 Apr 2017 16:50:08 -0700
changeset 32112 31763785094b
parent 31876 94c1d3c1aea2
child 32171 fb9b6bfb54b5
permissions -rw-r--r--
worker: rewrite error handling so os._exit covers all cases Previously the worker error handling is like: pid = os.fork() --+ if pid == 0: | .... | problematic .... --+ try: --+ .... | worker error handling --+ If a signal arrives when Python is executing the "problematic" lines, an external error handling (dispatch.py) will take over the control flow and it's no longer guaranteed "os._exit" is called (see 86cd09bc13ba for why it is necessary). This patch rewrites the error handling so it covers all possible code paths for a worker even during fork. Note: "os.getpid() == parentpid" is used to test if the process is parent or not intentionally, instead of checking "pid", because "pid = os.fork()" may be not atomic - it's possible that that a signal hits the worker before the assignment completes [1]. The newly added test replaces "os.fork" to exercise that extreme case. [1]: CPython compiles "pid = os.fork()" to 2 byte codes: "CALL_FUNCTION" and "STORE_FAST", so it's probably not atomic: def f(): pid = os.fork() dis.dis(f) 2 0 LOAD_GLOBAL 0 (os) 3 LOAD_ATTR 1 (fork) 6 CALL_FUNCTION 0 9 STORE_FAST 0 (pid) 12 LOAD_CONST 0 (None) 15 RETURN_VALUE
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
27502
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
     8
from __future__ import absolute_import
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
     9
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    10
import heapq
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    11
import os
27502
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    12
import struct
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    13
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    14
from .i18n import _
31530
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
    15
from .node import (
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
    16
    bin,
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
    17
    hex,
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
    18
)
27502
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    19
from . import (
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    20
    error,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    21
    mdiff,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    22
    parsers,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    23
    revlog,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    24
    util,
2df7f5c09c34 manifest: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27466
diff changeset
    25
)
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
    26
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
    27
propertycache = util.propertycache
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
    28
24572
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    29
def _parsev1(data):
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    30
    # This method does a little bit of excessive-looking
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    31
    # precondition checking. This is so that the behavior of this
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    32
    # class exactly matches its C counterpart to try and help
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    33
    # prevent surprise breakage for anyone that develops against
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    34
    # the pure version.
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    35
    if data and data[-1] != '\n':
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    36
        raise ValueError('Manifest did not end in a newline.')
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    37
    prev = None
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    38
    for l in data.splitlines():
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    39
        if prev is not None and prev > l:
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    40
            raise ValueError('Manifest lines not in sorted order.')
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    41
        prev = l
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    42
        f, n = l.split('\0')
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    43
        if len(n) > 40:
31366
45347d4a4f07 manifest: now that node.bin is available, use it directly
Augie Fackler <augie@google.com>
parents: 31365
diff changeset
    44
            yield f, bin(n[:40]), n[40:]
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    45
        else:
31366
45347d4a4f07 manifest: now that node.bin is available, use it directly
Augie Fackler <augie@google.com>
parents: 31365
diff changeset
    46
            yield f, bin(n), ''
24524
63b6031384fc manifest: extract method for parsing manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24502
diff changeset
    47
24572
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    48
def _parsev2(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    49
    metadataend = data.find('\n')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    50
    # Just ignore metadata for now
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    51
    pos = metadataend + 1
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    52
    prevf = ''
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    53
    while pos < len(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    54
        end = data.find('\n', pos + 1) # +1 to skip stem length byte
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    55
        if end == -1:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    56
            raise ValueError('Manifest ended with incomplete file entry.')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    57
        stemlen = ord(data[pos])
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    58
        items = data[pos + 1:end].split('\0')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    59
        f = prevf[:stemlen] + items[0]
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    60
        if prevf > f:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    61
            raise ValueError('Manifest entries not in sorted order.')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    62
        fl = items[1]
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    63
        # Just ignore metadata (items[2:] for now)
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    64
        n = data[end + 1:end + 21]
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    65
        yield f, n, fl
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    66
        pos = end + 22
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    67
        prevf = f
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    68
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    69
def _parse(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    70
    """Generates (path, node, flags) tuples from a manifest text"""
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    71
    if data.startswith('\0'):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    72
        return iter(_parsev2(data))
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    73
    else:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    74
        return iter(_parsev1(data))
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
    75
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    76
def _text(it, usemanifestv2):
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    77
    """Given an iterator over (path, node, flags) tuples, returns a manifest
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    78
    text"""
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    79
    if usemanifestv2:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    80
        return _textv2(it)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    81
    else:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    82
        return _textv1(it)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    83
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    84
def _textv1(it):
24525
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    85
    files = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    86
    lines = []
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    87
    _hex = revlog.hex
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    88
    for f, n, fl in it:
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    89
        files.append(f)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    90
        # if this is changed to support newlines in filenames,
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    91
        # be sure to check the templates/ dir again (especially *-raw.tmpl)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    92
        lines.append("%s\0%s%s\n" % (f, _hex(n), fl))
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    93
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    94
    _checkforbidden(files)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    95
    return ''.join(lines)
e118f74d246f manifest: extract method for creating manifest text
Martin von Zweigbergk <martinvonz@google.com>
parents: 24524
diff changeset
    96
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    97
def _textv2(it):
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    98
    files = []
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
    99
    lines = ['\0\n']
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   100
    prevf = ''
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   101
    for f, n, fl in it:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   102
        files.append(f)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   103
        stem = os.path.commonprefix([prevf, f])
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   104
        stemlen = min(len(stem), 255)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   105
        lines.append("%c%s\0%s\n%s\n" % (stemlen, f[stemlen:], fl, n))
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   106
        prevf = f
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   107
    _checkforbidden(files)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   108
    return ''.join(lines)
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   109
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   110
class lazymanifestiter(object):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   111
    def __init__(self, lm):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   112
        self.pos = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   113
        self.lm = lm
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   114
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   115
    def __iter__(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   116
        return self
24223
b4df0d0c49e7 manifest: move parsing functions up in file
Augie Fackler <augie@google.com>
parents: 24215
diff changeset
   117
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   118
    def next(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   119
        try:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   120
            data, pos = self.lm._get(self.pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   121
        except IndexError:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   122
            raise StopIteration
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   123
        if pos == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   124
            self.pos += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   125
            return data[0]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   126
        self.pos += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   127
        zeropos = data.find('\x00', pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   128
        return data[pos:zeropos]
24224
d71837d06597 manifest: do parsing inside manifestdict contstructor
Augie Fackler <augie@google.com>
parents: 24223
diff changeset
   129
31364
91874c247d61 manifest: add __next__ methods for Python 3
Augie Fackler <augie@google.com>
parents: 31352
diff changeset
   130
    __next__ = next
91874c247d61 manifest: add __next__ methods for Python 3
Augie Fackler <augie@google.com>
parents: 31352
diff changeset
   131
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   132
class lazymanifestiterentries(object):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   133
    def __init__(self, lm):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   134
        self.lm = lm
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   135
        self.pos = 0
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   136
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   137
    def __iter__(self):
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   138
        return self
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   139
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   140
    def next(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   141
        try:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   142
            data, pos = self.lm._get(self.pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   143
        except IndexError:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   144
            raise StopIteration
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   145
        if pos == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   146
            self.pos += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   147
            return data
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   148
        zeropos = data.find('\x00', pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   149
        hashval = unhexlify(data, self.lm.extrainfo[self.pos],
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   150
                            zeropos + 1, 40)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   151
        flags = self.lm._getflags(data, self.pos, zeropos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   152
        self.pos += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   153
        return (data[pos:zeropos], hashval, flags)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   154
31364
91874c247d61 manifest: add __next__ methods for Python 3
Augie Fackler <augie@google.com>
parents: 31352
diff changeset
   155
    __next__ = next
91874c247d61 manifest: add __next__ methods for Python 3
Augie Fackler <augie@google.com>
parents: 31352
diff changeset
   156
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   157
def unhexlify(data, extra, pos, length):
31365
28e3471a21ef manifest: use node.bin instead of .decode('hex')
Augie Fackler <augie@google.com>
parents: 31364
diff changeset
   158
    s = bin(data[pos:pos + length])
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   159
    if extra:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   160
        s += chr(extra & 0xff)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   161
    return s
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   162
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   163
def _cmp(a, b):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   164
    return (a > b) - (a < b)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   165
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   166
class _lazymanifest(object):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   167
    def __init__(self, data, positions=None, extrainfo=None, extradata=None):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   168
        if positions is None:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   169
            self.positions = self.findlines(data)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   170
            self.extrainfo = [0] * len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   171
            self.data = data
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   172
            self.extradata = []
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   173
        else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   174
            self.positions = positions[:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   175
            self.extrainfo = extrainfo[:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   176
            self.extradata = extradata[:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   177
            self.data = data
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   178
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   179
    def findlines(self, data):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   180
        if not data:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   181
            return []
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   182
        pos = data.find("\n")
31352
667e88568087 manifest: unbreak pure-python manifest parsing on Python 3
Augie Fackler <augie@google.com>
parents: 31346
diff changeset
   183
        if pos == -1 or data[-1:] != '\n':
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   184
            raise ValueError("Manifest did not end in a newline.")
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   185
        positions = [0]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   186
        prev = data[:data.find('\x00')]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   187
        while pos < len(data) - 1 and pos != -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   188
            positions.append(pos + 1)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   189
            nexts = data[pos + 1:data.find('\x00', pos + 1)]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   190
            if nexts < prev:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   191
                raise ValueError("Manifest lines not in sorted order.")
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   192
            prev = nexts
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   193
            pos = data.find("\n", pos + 1)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   194
        return positions
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   195
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   196
    def _get(self, index):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   197
        # get the position encoded in pos:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   198
        #   positive number is an index in 'data'
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   199
        #   negative number is in extrapieces
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   200
        pos = self.positions[index]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   201
        if pos >= 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   202
            return self.data, pos
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   203
        return self.extradata[-pos - 1], -1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   204
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   205
    def _getkey(self, pos):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   206
        if pos >= 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   207
            return self.data[pos:self.data.find('\x00', pos + 1)]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   208
        return self.extradata[-pos - 1][0]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   209
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   210
    def bsearch(self, key):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   211
        first = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   212
        last = len(self.positions) - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   213
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   214
        while first <= last:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   215
            midpoint = (first + last)//2
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   216
            nextpos = self.positions[midpoint]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   217
            candidate = self._getkey(nextpos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   218
            r = _cmp(key, candidate)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   219
            if r == 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   220
                return midpoint
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   221
            else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   222
                if r < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   223
                    last = midpoint - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   224
                else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   225
                    first = midpoint + 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   226
        return -1
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   227
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   228
    def bsearch2(self, key):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   229
        # same as the above, but will always return the position
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   230
        # done for performance reasons
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   231
        first = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   232
        last = len(self.positions) - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   233
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   234
        while first <= last:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   235
            midpoint = (first + last)//2
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   236
            nextpos = self.positions[midpoint]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   237
            candidate = self._getkey(nextpos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   238
            r = _cmp(key, candidate)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   239
            if r == 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   240
                return (midpoint, True)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   241
            else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   242
                if r < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   243
                    last = midpoint - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   244
                else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   245
                    first = midpoint + 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   246
        return (first, False)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   247
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   248
    def __contains__(self, key):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   249
        return self.bsearch(key) != -1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   250
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   251
    def _getflags(self, data, needle, pos):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   252
        start = pos + 41
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   253
        end = data.find("\n", start)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   254
        if end == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   255
            end = len(data) - 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   256
        if start == end:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   257
            return ''
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   258
        return self.data[start:end]
24297
0178f500d61e lazymanifest: fix pure hg iterkeys()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24295
diff changeset
   259
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   260
    def __getitem__(self, key):
31367
ef50b491c17d manifest: ensure paths are bytes (not str) in pure parser
Augie Fackler <augie@google.com>
parents: 31366
diff changeset
   261
        if not isinstance(key, bytes):
ef50b491c17d manifest: ensure paths are bytes (not str) in pure parser
Augie Fackler <augie@google.com>
parents: 31366
diff changeset
   262
            raise TypeError("getitem: manifest keys must be a bytes.")
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   263
        needle = self.bsearch(key)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   264
        if needle == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   265
            raise KeyError
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   266
        data, pos = self._get(needle)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   267
        if pos == -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   268
            return (data[1], data[2])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   269
        zeropos = data.find('\x00', pos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   270
        assert 0 <= needle <= len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   271
        assert len(self.extrainfo) == len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   272
        hashval = unhexlify(data, self.extrainfo[needle], zeropos + 1, 40)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   273
        flags = self._getflags(data, needle, zeropos)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   274
        return (hashval, flags)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   275
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   276
    def __delitem__(self, key):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   277
        needle, found = self.bsearch2(key)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   278
        if not found:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   279
            raise KeyError
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   280
        cur = self.positions[needle]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   281
        self.positions = self.positions[:needle] + self.positions[needle + 1:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   282
        self.extrainfo = self.extrainfo[:needle] + self.extrainfo[needle + 1:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   283
        if cur >= 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   284
            self.data = self.data[:cur] + '\x00' + self.data[cur + 1:]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   285
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   286
    def __setitem__(self, key, value):
31531
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   287
        if not isinstance(key, bytes):
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   288
            raise TypeError("setitem: manifest keys must be a byte string.")
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   289
        if not isinstance(value, tuple) or len(value) != 2:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   290
            raise TypeError("Manifest values must be a tuple of (node, flags).")
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   291
        hashval = value[0]
31531
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   292
        if not isinstance(hashval, bytes) or not 20 <= len(hashval) <= 22:
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   293
            raise TypeError("node must be a 20-byte byte string")
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   294
        flags = value[1]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   295
        if len(hashval) == 22:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   296
            hashval = hashval[:-1]
31531
326bca5477d0 manifest: refer to bytestrings as bytes, not str
Augie Fackler <augie@google.com>
parents: 31530
diff changeset
   297
        if not isinstance(flags, bytes) or len(flags) > 1:
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   298
            raise TypeError("flags must a 0 or 1 byte string, got %r", flags)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   299
        needle, found = self.bsearch2(key)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   300
        if found:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   301
            # put the item
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   302
            pos = self.positions[needle]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   303
            if pos < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   304
                self.extradata[-pos - 1] = (key, hashval, value[1])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   305
            else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   306
                # just don't bother
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   307
                self.extradata.append((key, hashval, value[1]))
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   308
                self.positions[needle] = -len(self.extradata)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   309
        else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   310
            # not found, put it in with extra positions
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   311
            self.extradata.append((key, hashval, value[1]))
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   312
            self.positions = (self.positions[:needle] + [-len(self.extradata)]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   313
                              + self.positions[needle:])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   314
            self.extrainfo = (self.extrainfo[:needle] + [0] +
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   315
                              self.extrainfo[needle:])
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   316
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
   317
    def copy(self):
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   318
        # XXX call _compact like in C?
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   319
        return _lazymanifest(self.data, self.positions, self.extrainfo,
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   320
            self.extradata)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   321
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   322
    def _compact(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   323
        # hopefully not called TOO often
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   324
        if len(self.extradata) == 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   325
            return
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   326
        l = []
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   327
        last_cut = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   328
        i = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   329
        offset = 0
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   330
        self.extrainfo = [0] * len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   331
        while i < len(self.positions):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   332
            if self.positions[i] >= 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   333
                cur = self.positions[i]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   334
                last_cut = cur
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   335
                while True:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   336
                    self.positions[i] = offset
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   337
                    i += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   338
                    if i == len(self.positions) or self.positions[i] < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   339
                        break
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   340
                    offset += self.positions[i] - cur
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   341
                    cur = self.positions[i]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   342
                end_cut = self.data.find('\n', cur)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   343
                if end_cut != -1:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   344
                    end_cut += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   345
                offset += end_cut - cur
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   346
                l.append(self.data[last_cut:end_cut])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   347
            else:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   348
                while i < len(self.positions) and self.positions[i] < 0:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   349
                    cur = self.positions[i]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   350
                    t = self.extradata[-cur - 1]
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   351
                    l.append(self._pack(t))
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   352
                    self.positions[i] = offset
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   353
                    if len(t[1]) > 20:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   354
                        self.extrainfo[i] = ord(t[1][21])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   355
                    offset += len(l[-1])
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   356
                    i += 1
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   357
        self.data = ''.join(l)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   358
        self.extradata = []
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   359
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   360
    def _pack(self, d):
31530
160e7ad941e9 manifest: use node.hex instead of .encode('hex')
Augie Fackler <augie@google.com>
parents: 31476
diff changeset
   361
        return d[0] + '\x00' + hex(d[1][:20]) + d[2] + '\n'
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   362
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   363
    def text(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   364
        self._compact()
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   365
        return self.data
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   366
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   367
    def diff(self, m2, clean=False):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   368
        '''Finds changes between the current manifest and m2.'''
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   369
        # XXX think whether efficiency matters here
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   370
        diff = {}
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   371
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   372
        for fn, e1, flags in self.iterentries():
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   373
            if fn not in m2:
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   374
                diff[fn] = (e1, flags), (None, '')
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   375
            else:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   376
                e2 = m2[fn]
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   377
                if (e1, flags) != e2:
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   378
                    diff[fn] = (e1, flags), e2
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   379
                elif clean:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   380
                    diff[fn] = None
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   381
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   382
        for fn, e2, flags in m2.iterentries():
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   383
            if fn not in self:
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   384
                diff[fn] = (None, ''), (e2, flags)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   385
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   386
        return diff
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   387
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   388
    def iterentries(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   389
        return lazymanifestiterentries(self)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   390
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   391
    def iterkeys(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   392
        return lazymanifestiter(self)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   393
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   394
    def __iter__(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   395
        return lazymanifestiter(self)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   396
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   397
    def __len__(self):
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   398
        return len(self.positions)
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   399
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   400
    def filtercopy(self, filterfn):
30042
d24e03da24b5 lazymanifest: write a more efficient, pypy friendly version of lazymanifest
Maciej Fijalkowski <fijall@gmail.com>
parents: 29998
diff changeset
   401
        # XXX should be optimized
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   402
        c = _lazymanifest('')
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   403
        for f, n, fl in self.iterentries():
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   404
            if filterfn(f):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   405
                c[f] = n, fl
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   406
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   407
24226
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   408
try:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   409
    _lazymanifest = parsers.lazymanifest
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   410
except AttributeError:
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   411
    pass
b992769dd1be manifest: use custom C implementation of lazymanifest
Augie Fackler <augie@google.com>
parents: 24225
diff changeset
   412
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   413
class manifestdict(object):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   414
    def __init__(self, data=''):
24572
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   415
        if data.startswith('\0'):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   416
            #_lazymanifest can not parse v2
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   417
            self._lm = _lazymanifest('')
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   418
            for f, n, fl in _parsev2(data):
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   419
                self._lm[f] = n, fl
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   420
        else:
b83679eb5f86 manifestv2: add support for reading new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24571
diff changeset
   421
            self._lm = _lazymanifest(data)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   422
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   423
    def __getitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   424
        return self._lm[key][0]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   425
24277
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   426
    def find(self, key):
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   427
        return self._lm[key]
22d560fe1516 manifest: don't let find() look inside manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24226
diff changeset
   428
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   429
    def __len__(self):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   430
        return len(self._lm)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   431
30331
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   432
    def __nonzero__(self):
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   433
        # nonzero is covered by the __len__ function, but implementing it here
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   434
        # makes it easier for extensions to override.
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   435
        return len(self._lm) != 0
b19291e5d506 manifest: add __nonzero__ method
Durham Goode <durham@fb.com>
parents: 30295
diff changeset
   436
31476
413b44003462 py3: add __bool__ to every class defining __nonzero__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31367
diff changeset
   437
    __bool__ = __nonzero__
413b44003462 py3: add __bool__ to every class defining __nonzero__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31367
diff changeset
   438
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   439
    def __setitem__(self, key, node):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   440
        self._lm[key] = node, self.flags(key, '')
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   441
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   442
    def __contains__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   443
        return key in self._lm
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   444
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   445
    def __delitem__(self, key):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   446
        del self._lm[key]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   447
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   448
    def __iter__(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   449
        return self._lm.__iter__()
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   450
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   451
    def iterkeys(self):
24295
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   452
        return self._lm.iterkeys()
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   453
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   454
    def keys(self):
2b7ab29627fd lazymanifest: add iterkeys() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24292
diff changeset
   455
        return list(self.iterkeys())
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   456
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   457
    def filesnotin(self, m2, match=None):
24184
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   458
        '''Set of files in this manifest that are not in the other'''
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   459
        if match:
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   460
            m1 = self.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   461
            m2 = m2.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   462
            return m1.filesnotin(m2)
29056
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   463
        diff = self.diff(m2)
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   464
        files = set(filepath
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   465
                    for filepath, hashflags in diff.iteritems()
e2178f7d17c0 manifest: improve filesnotin performance by using lazymanifest diff
Tony Tung <tonytung@merly.org>
parents: 28240
diff changeset
   466
                    if hashflags[1][0] is None)
24184
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   467
        return files
cd66080ef6d4 copies: move code into new manifestdict.filesnotin() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 24147
diff changeset
   468
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   469
    @propertycache
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   470
    def _dirs(self):
24635
21e1ece30f8c util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents: 24600
diff changeset
   471
        return util.dirs(self)
24322
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   472
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   473
    def dirs(self):
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   474
        return self._dirs
f263814c72ac manifest: add dirs() to manifestdict
Drew Gottlieb <drgott@google.com>
parents: 24298
diff changeset
   475
24324
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   476
    def hasdir(self, dir):
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   477
        return dir in self._dirs
149cc171e4a0 manifest: add manifestdict.hasdir() method
Drew Gottlieb <drgott@google.com>
parents: 24322
diff changeset
   478
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   479
    def _filesfastpath(self, match):
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   480
        '''Checks whether we can correctly and quickly iterate over matcher
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   481
        files instead of over manifest files.'''
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   482
        files = match.files()
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   483
        return (len(files) < 100 and (match.isexact() or
25276
c436ba9d6ac0 manifest: use match.prefix() instead of 'not match.anypats()'
Martin von Zweigbergk <martinvonz@google.com>
parents: 25222
diff changeset
   484
            (match.prefix() and all(fn in self for fn in files))))
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   485
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   486
    def walk(self, match):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   487
        '''Generates matching file names.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   488
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   489
        Equivalent to manifest.matches(match).iterkeys(), but without creating
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   490
        an entirely new manifest.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   491
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   492
        It also reports nonexistent files by marking them bad with match.bad().
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   493
        '''
24683
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   494
        if match.always():
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   495
            for f in iter(self):
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   496
                yield f
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   497
            return
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   498
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   499
        fset = set(match.files())
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   500
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   501
        # avoid the entire walk if we're only looking for specific files
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   502
        if self._filesfastpath(match):
24667
19c5b0913960 manifest.walk: join nested if-conditions
Martin von Zweigbergk <martinvonz@google.com>
parents: 24666
diff changeset
   503
            for fn in sorted(fset):
19c5b0913960 manifest.walk: join nested if-conditions
Martin von Zweigbergk <martinvonz@google.com>
parents: 24666
diff changeset
   504
                yield fn
24682
aef3d1469773 manifest.walk: use return instead of StopIteration in generator
Martin von Zweigbergk <martinvonz@google.com>
parents: 24670
diff changeset
   505
            return
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   506
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   507
        for fn in self:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   508
            if fn in fset:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   509
                # specified pattern is the exact name
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   510
                fset.remove(fn)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   511
            if match(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   512
                yield fn
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   513
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   514
        # for dirstate.walk, files=['.'] means "walk the whole tree".
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   515
        # follow that here, too
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   516
        fset.discard('.')
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   517
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   518
        for fn in sorted(fset):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   519
            if not self.hasdir(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   520
                match.bad(fn, None)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   521
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   522
    def matches(self, match):
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   523
        '''generate a new manifest filtered by the match argument'''
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   524
        if match.always():
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   525
            return self.copy()
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   526
24685
b3d78d82d84c manifestdict: extract condition for _intersectfiles() and use for walk()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24684
diff changeset
   527
        if self._filesfastpath(match):
24666
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   528
            m = manifestdict()
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   529
            lm = self._lm
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   530
            for fn in match.files():
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   531
                if fn in lm:
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   532
                    m._lm[fn] = lm[fn]
3092885b5b32 manifestdict: inline _intersectfiles()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24665
diff changeset
   533
            return m
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   534
24700
32b268cbff00 manifestdict: drop empty-string argument when creating empty manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24685
diff changeset
   535
        m = manifestdict()
24664
ea4a7c8909ae manifestdict.matches: avoid name 'lm' for a not-lazymanifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24647
diff changeset
   536
        m._lm = self._lm.filtercopy(match)
ea4a7c8909ae manifestdict.matches: avoid name 'lm' for a not-lazymanifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24647
diff changeset
   537
        return m
23305
0cc283f44655 manifest: add matches() method
Martin von Zweigbergk <martinvonz@google.com>
parents: 22966
diff changeset
   538
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   539
    def diff(self, m2, match=None, clean=False):
23756
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   540
        '''Finds changes between the current manifest and m2.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   541
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   542
        Args:
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   543
          m2: the manifest to which this manifest should be compared.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   544
          clean: if true, include files unchanged between these manifests
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   545
                 with a None value in the returned dictionary.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   546
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   547
        The result is returned as a dict with filename as key and
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   548
        values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   549
        nodeid in the current/other manifest and fl1/fl2 is the flag
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   550
        in the current/other manifest. Where the file does not exist,
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   551
        the nodeid will be None and the flags will be the empty
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   552
        string.
829f640b5540 manifest: add optional recording of clean entries to diff
Augie Fackler <augie@google.com>
parents: 23602
diff changeset
   553
        '''
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   554
        if match:
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   555
            m1 = self.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   556
            m2 = m2.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   557
            return m1.diff(m2, clean=clean)
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   558
        return self._lm.diff(m2._lm, clean)
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   559
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   560
    def setflag(self, key, flag):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   561
        self._lm[key] = self[key], flag
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   562
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   563
    def get(self, key, default=None):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   564
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   565
            return self._lm[key][0]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   566
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   567
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   568
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   569
    def flags(self, key, default=''):
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   570
        try:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   571
            return self._lm[key][1]
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   572
        except KeyError:
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   573
            return default
22965
b697fa74b475 manifest: for diff(), only iterate over files, not flags
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22964
diff changeset
   574
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   575
    def copy(self):
24700
32b268cbff00 manifestdict: drop empty-string argument when creating empty manifest
Martin von Zweigbergk <martinvonz@google.com>
parents: 24685
diff changeset
   576
        c = manifestdict()
24225
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   577
        c._lm = self._lm.copy()
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   578
        return c
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   579
3e5c4af69808 manifest: split manifestdict into high-level and low-level logic
Augie Fackler <augie@google.com>
parents: 24224
diff changeset
   580
    def iteritems(self):
24298
49cd847fd69a lazymanifest: make __iter__ generate filenames, not 3-tuples
Martin von Zweigbergk <martinvonz@google.com>
parents: 24297
diff changeset
   581
        return (x[:2] for x in self._lm.iterentries())
2831
0b50a580be36 Add manifestflags class
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
   582
28203
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
   583
    def iterentries(self):
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
   584
        return self._lm.iterentries()
7297e9e13a8a verify: check directory manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 27502
diff changeset
   585
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   586
    def text(self, usemanifestv2=False):
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   587
        if usemanifestv2:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   588
            return _textv2(self._lm.iterentries())
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   589
        else:
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   590
            # use (probably) native version for v1
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
   591
            return self._lm.text()
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   592
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   593
    def fastdelta(self, base, changes):
31787
6bfea18df609 manifest: update comment to be about bytearray
Martin von Zweigbergk <martinvonz@google.com>
parents: 31650
diff changeset
   594
        """Given a base manifest text as a bytearray and a list of changes
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   595
        relative to that text, compute a delta that can be used by revlog.
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   596
        """
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   597
        delta = []
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   598
        dstart = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   599
        dend = None
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   600
        dline = [""]
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   601
        start = 0
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   602
        # zero copy representation of base as a buffer
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   603
        addbuf = util.buffer(base)
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   604
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   605
        changes = list(changes)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   606
        if len(changes) < 1000:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   607
            # start with a readonly loop that finds the offset of
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   608
            # each line and creates the deltas
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   609
            for f, todelete in changes:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   610
                # bs will either be the index of the item or the insert point
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   611
                start, end = _msearch(addbuf, f, start)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   612
                if not todelete:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   613
                    h, fl = self._lm[f]
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   614
                    l = "%s\0%s%s\n" % (f, revlog.hex(h), fl)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   615
                else:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   616
                    if start == end:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   617
                        # item we want to delete was not found, error out
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   618
                        raise AssertionError(
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   619
                                _("failed to remove %s from manifest") % f)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   620
                    l = ""
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   621
                if dstart is not None and dstart <= start and dend >= start:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   622
                    if dend < end:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   623
                        dend = end
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   624
                    if l:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   625
                        dline.append(l)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   626
                else:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   627
                    if dstart is not None:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   628
                        delta.append([dstart, dend, "".join(dline)])
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   629
                    dstart = start
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   630
                    dend = end
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   631
                    dline = [l]
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   632
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   633
            if dstart is not None:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   634
                delta.append([dstart, dend, "".join(dline)])
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   635
            # apply the delta to the base, and get a delta for addrevision
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   636
            deltatext, arraytext = _addlistdelta(base, delta)
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   637
        else:
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   638
            # For large changes, it's much cheaper to just build the text and
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   639
            # diff it.
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   640
            arraytext = bytearray(self.text())
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   641
            deltatext = mdiff.textdiff(
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   642
                util.buffer(base), util.buffer(arraytext))
26871
1cbf144fd8a1 manifest: skip fastdelta if the change is large
Durham Goode <durham@fb.com>
parents: 26402
diff changeset
   643
22931
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   644
        return arraytext, deltatext
48c0b101a9de manifest: add fastdelta method to manifestdict
Augie Fackler <raf@durin42.com>
parents: 22930
diff changeset
   645
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   646
def _msearch(m, s, lo=0, hi=None):
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   647
    '''return a tuple (start, end) that says where to find s within m.
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   648
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   649
    If the string is found m[start:end] are the line containing
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   650
    that string.  If start == end the string was not found and
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   651
    they indicate the proper sorted insertion point.
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   652
31650
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   653
    m should be a buffer, a memoryview or a byte string.
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   654
    s is a byte string'''
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   655
    def advance(i, c):
31650
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   656
        while i < lenm and m[i:i + 1] != c:
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   657
            i += 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   658
        return i
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   659
    if not s:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   660
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   661
    lenm = len(m)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   662
    if not hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   663
        hi = lenm
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   664
    while lo < hi:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   665
        mid = (lo + hi) // 2
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   666
        start = mid
31650
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   667
        while start > 0 and m[start - 1:start] != '\n':
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   668
            start -= 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   669
        end = advance(start, '\0')
31650
23391acfc421 py3: fix manifestdict.fastdelta() to be compatible with memoryview
Yuya Nishihara <yuya@tcha.org>
parents: 31531
diff changeset
   670
        if bytes(m[start:end]) < s:
22930
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   671
            # we know that after the null there are 40 bytes of sha1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   672
            # this translates to the bisect lo = mid + 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   673
            lo = advance(end + 40, '\n') + 1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   674
        else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   675
            # this translates to the bisect hi = mid
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   676
            hi = start
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   677
    end = advance(lo, '\0')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   678
    found = m[lo:end]
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   679
    if s == found:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   680
        # we know that after the null there are 40 bytes of sha1
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   681
        end = advance(end + 40, '\n')
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   682
        return (lo, end + 1)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   683
    else:
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   684
        return (lo, lo)
1acb81d10eaf manifest: move _search to module level and rename to _msearch
Augie Fackler <raf@durin42.com>
parents: 22929
diff changeset
   685
22415
65ec6c5c0fb3 manifest: mark addlistdelta and checkforbidden as module-private
Augie Fackler <raf@durin42.com>
parents: 22409
diff changeset
   686
def _checkforbidden(l):
22408
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   687
    """Check filenames for illegal characters."""
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   688
    for f in l:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   689
        if '\n' in f or '\r' in f:
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   690
            raise error.RevlogError(
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   691
                _("'\\n' and '\\r' disallowed in filenames: %r") % f)
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   692
dc97e04c12ad manifest: move checkforbidden to module-level
Augie Fackler <raf@durin42.com>
parents: 21879
diff changeset
   693
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   694
# 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
   695
# 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
   696
def _addlistdelta(addlist, x):
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   697
    # 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
   698
    # than repeatedly modifying the existing one
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   699
    currentposition = 0
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   700
    newaddlist = bytearray()
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   701
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   702
    for start, end, content in x:
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   703
        newaddlist += addlist[currentposition:start]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   704
        if content:
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
   705
            newaddlist += bytearray(content)
22409
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   706
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   707
        currentposition = end
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   708
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   709
    newaddlist += addlist[currentposition:]
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   710
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   711
    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
   712
                   + content for start, end, content in x)
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   713
    return deltatext, newaddlist
8f09b785b59b manifest: move addlistdelta to module-level
Augie Fackler <raf@durin42.com>
parents: 22408
diff changeset
   714
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   715
def _splittopdir(f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   716
    if '/' in f:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   717
        dir, subpath = f.split('/', 1)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   718
        return dir + '/', subpath
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   719
    else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   720
        return '', f
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   721
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   722
_noop = lambda s: None
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   723
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   724
class treemanifest(object):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   725
    def __init__(self, dir='', text=''):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   726
        self._dir = dir
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   727
        self._node = revlog.nullid
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   728
        self._loadfunc = _noop
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   729
        self._copyfunc = _noop
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   730
        self._dirty = False
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   731
        self._dirs = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   732
        # Using _lazymanifest here is a little slower than plain old dicts
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   733
        self._files = {}
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   734
        self._flags = {}
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   735
        if text:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   736
            def readsubtree(subdir, subm):
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   737
                raise AssertionError('treemanifest constructor only accepts '
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   738
                                     'flat manifests')
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   739
            self.parse(text, readsubtree)
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   740
            self._dirty = True # Mark flat manifest dirty after parsing
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   741
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   742
    def _subpath(self, path):
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   743
        return self._dir + path
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   744
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   745
    def __len__(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   746
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   747
        size = len(self._files)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   748
        for m in self._dirs.values():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   749
            size += m.__len__()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   750
        return size
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   751
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   752
    def _isempty(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   753
        self._load() # for consistency; already loaded by all callers
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   754
        return (not self._files and (not self._dirs or
25151
6eb4bdad198f cleanup: use __builtins__.all instead of util.all
Augie Fackler <augie@google.com>
parents: 25119
diff changeset
   755
                all(m._isempty() for m in self._dirs.values())))
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   756
26400
6f9d9e2a661f manifest: add id(self) to treemanifest __repr__
Augie Fackler <augie@google.com>
parents: 26199
diff changeset
   757
    def __repr__(self):
6f9d9e2a661f manifest: add id(self) to treemanifest __repr__
Augie Fackler <augie@google.com>
parents: 26199
diff changeset
   758
        return ('<treemanifest dir=%s, node=%s, loaded=%s, dirty=%s at 0x%x>' %
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   759
                (self._dir, revlog.hex(self._node),
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   760
                 bool(self._loadfunc is _noop),
26400
6f9d9e2a661f manifest: add id(self) to treemanifest __repr__
Augie Fackler <augie@google.com>
parents: 26199
diff changeset
   761
                 self._dirty, id(self)))
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   762
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   763
    def dir(self):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   764
        '''The directory that this tree manifest represents, including a
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   765
        trailing '/'. Empty string for the repo root directory.'''
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   766
        return self._dir
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   767
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   768
    def node(self):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   769
        '''This node of this instance. nullid for unsaved instances. Should
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   770
        be updated when the instance is read or written from a revlog.
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   771
        '''
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   772
        assert not self._dirty
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   773
        return self._node
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   774
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   775
    def setnode(self, node):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   776
        self._node = node
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   777
        self._dirty = False
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   778
28206
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   779
    def iterentries(self):
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   780
        self._load()
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   781
        for p, n in sorted(self._dirs.items() + self._files.items()):
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   782
            if p in self._files:
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   783
                yield self._subpath(p), n, self._flags.get(p, '')
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   784
            else:
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   785
                for x in n.iterentries():
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   786
                    yield x
8ab91d9290ce treemanifest: implement iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28203
diff changeset
   787
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   788
    def iteritems(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   789
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   790
        for p, n in sorted(self._dirs.items() + self._files.items()):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   791
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   792
                yield self._subpath(p), n
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   793
            else:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   794
                for f, sn in n.iteritems():
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   795
                    yield f, sn
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   796
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   797
    def iterkeys(self):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   798
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   799
        for p in sorted(self._dirs.keys() + self._files.keys()):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   800
            if p in self._files:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   801
                yield self._subpath(p)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   802
            else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   803
                for f in self._dirs[p].iterkeys():
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   804
                    yield f
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   805
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   806
    def keys(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   807
        return list(self.iterkeys())
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   808
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   809
    def __iter__(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   810
        return self.iterkeys()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   811
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   812
    def __contains__(self, f):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   813
        if f is None:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   814
            return False
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   815
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   816
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   817
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   818
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   819
                return False
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   820
            return self._dirs[dir].__contains__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   821
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   822
            return f in self._files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   823
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   824
    def get(self, f, default=None):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   825
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   826
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   827
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   828
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   829
                return default
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   830
            return self._dirs[dir].get(subpath, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   831
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   832
            return self._files.get(f, default)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   833
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   834
    def __getitem__(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   835
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   836
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   837
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   838
            return self._dirs[dir].__getitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   839
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   840
            return self._files[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   841
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   842
    def flags(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   843
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   844
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   845
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   846
            if dir not in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   847
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   848
            return self._dirs[dir].flags(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   849
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   850
            if f in self._dirs:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   851
                return ''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   852
            return self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   853
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   854
    def find(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   855
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   856
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   857
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   858
            return self._dirs[dir].find(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   859
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   860
            return self._files[f], self._flags.get(f, '')
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   861
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   862
    def __delitem__(self, f):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   863
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   864
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   865
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   866
            self._dirs[dir].__delitem__(subpath)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   867
            # If the directory is now empty, remove it
24551
4fdf5eac5b39 treemanifest: add treemanifest._isempty()
Drew Gottlieb <drgott@google.com>
parents: 24550
diff changeset
   868
            if self._dirs[dir]._isempty():
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   869
                del self._dirs[dir]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   870
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   871
            del self._files[f]
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   872
            if f in self._flags:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   873
                del self._flags[f]
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   874
        self._dirty = True
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   875
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   876
    def __setitem__(self, f, n):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   877
        assert n is not None
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   878
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   879
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   880
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   881
            if dir not in self._dirs:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   882
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   883
            self._dirs[dir].__setitem__(subpath, n)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   884
        else:
24467
bfb754050ccd treemanifest: drop 22nd byte for consistency with manifestdict
Martin von Zweigbergk <martinvonz@google.com>
parents: 24448
diff changeset
   885
            self._files[f] = n[:21] # to match manifestdict's behavior
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   886
        self._dirty = True
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   887
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   888
    def _load(self):
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   889
        if self._loadfunc is not _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   890
            lf, self._loadfunc = self._loadfunc, _noop
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   891
            lf(self)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   892
        elif self._copyfunc is not _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   893
            cf, self._copyfunc = self._copyfunc, _noop
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   894
            cf(self)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   895
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   896
    def setflag(self, f, flags):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   897
        """Set the flags (symlink, executable) for path f."""
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   898
        self._load()
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   899
        dir, subpath = _splittopdir(f)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   900
        if dir:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   901
            if dir not in self._dirs:
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   902
                self._dirs[dir] = treemanifest(self._subpath(dir))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   903
            self._dirs[dir].setflag(subpath, flags)
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   904
        else:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   905
            self._flags[f] = flags
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   906
        self._dirty = True
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   907
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   908
    def copy(self):
24403
0e23faa1511c treemanifest: store directory path in treemanifest nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 24402
diff changeset
   909
        copy = treemanifest(self._dir)
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
   910
        copy._node = self._node
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   911
        copy._dirty = self._dirty
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   912
        if self._copyfunc is _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   913
            def _copyfunc(s):
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   914
                self._load()
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   915
                for d in self._dirs:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   916
                    s._dirs[d] = self._dirs[d].copy()
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   917
                s._files = dict.copy(self._files)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   918
                s._flags = dict.copy(self._flags)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   919
            if self._loadfunc is _noop:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   920
                _copyfunc(copy)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   921
            else:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   922
                copy._copyfunc = _copyfunc
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   923
        else:
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
   924
            copy._copyfunc = self._copyfunc
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   925
        return copy
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   926
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   927
    def filesnotin(self, m2, match=None):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   928
        '''Set of files in this manifest that are not in the other'''
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   929
        if match:
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   930
            m1 = self.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   931
            m2 = m2.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   932
            return m1.filesnotin(m2)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
   933
24405
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   934
        files = set()
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   935
        def _filesnotin(t1, t2):
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   936
            if t1._node == t2._node and not t1._dirty and not t2._dirty:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
   937
                return
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   938
            t1._load()
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   939
            t2._load()
24405
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   940
            for d, m1 in t1._dirs.iteritems():
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   941
                if d in t2._dirs:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   942
                    m2 = t2._dirs[d]
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   943
                    _filesnotin(m1, m2)
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   944
                else:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   945
                    files.update(m1.iterkeys())
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   946
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   947
            for fn in t1._files.iterkeys():
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   948
                if fn not in t2._files:
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   949
                    files.add(t1._subpath(fn))
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   950
cbe9d50d9e65 treemanifest: make filesnotin() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24404
diff changeset
   951
        _filesnotin(self, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   952
        return files
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   953
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   954
    @propertycache
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   955
    def _alldirs(self):
24635
21e1ece30f8c util: move dirs() and finddirs() from scmutil to util
Drew Gottlieb <drgott@google.com>
parents: 24600
diff changeset
   956
        return util.dirs(self)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   957
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   958
    def dirs(self):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   959
        return self._alldirs
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   960
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   961
    def hasdir(self, dir):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
   962
        self._load()
24406
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   963
        topdir, subdir = _splittopdir(dir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   964
        if topdir:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   965
            if topdir in self._dirs:
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   966
                return self._dirs[topdir].hasdir(subdir)
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   967
            return False
1297480ed347 treemanifest: make hasdir() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24405
diff changeset
   968
        return (dir + '/') in self._dirs
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
   969
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   970
    def walk(self, match):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   971
        '''Generates matching file names.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   972
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   973
        Equivalent to manifest.matches(match).iterkeys(), but without creating
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   974
        an entirely new manifest.
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   975
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   976
        It also reports nonexistent files by marking them bad with match.bad().
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   977
        '''
24683
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   978
        if match.always():
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   979
            for f in iter(self):
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   980
                yield f
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   981
            return
4eaea0ed8dc1 manifest.walk: special-case match.always() for speed
Martin von Zweigbergk <martinvonz@google.com>
parents: 24682
diff changeset
   982
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   983
        fset = set(match.files())
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   984
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   985
        for fn in self._walk(match):
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   986
            if fn in fset:
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   987
                # specified pattern is the exact name
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   988
                fset.remove(fn)
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
   989
            yield fn
24646
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   990
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   991
        # for dirstate.walk, files=['.'] means "walk the whole tree".
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   992
        # follow that here, too
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   993
        fset.discard('.')
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   994
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   995
        for fn in sorted(fset):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   996
            if not self.hasdir(fn):
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   997
                match.bad(fn, None)
5693c834bcb4 manifest: move changectx.walk() to manifests
Drew Gottlieb <drgott@google.com>
parents: 24636
diff changeset
   998
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
   999
    def _walk(self, match):
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
  1000
        '''Recursively generates matching file names for walk().'''
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
  1001
        if not match.visitdir(self._dir[:-1] or '.'):
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
  1002
            return
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1003
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1004
        # yield this dir's files and walk its submanifests
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1005
        self._load()
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1006
        for p in sorted(self._dirs.keys() + self._files.keys()):
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1007
            if p in self._files:
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1008
                fullp = self._subpath(p)
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1009
                if match(fullp):
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1010
                    yield fullp
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1011
            else:
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
  1012
                for f in self._dirs[p]._walk(match):
24647
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1013
                    yield f
fb446c57f8f9 treemanifest: refactor treemanifest.walk()
Drew Gottlieb <drgott@google.com>
parents: 24646
diff changeset
  1014
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1015
    def matches(self, match):
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1016
        '''generate a new manifest filtered by the match argument'''
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1017
        if match.always():
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1018
            return self.copy()
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1019
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1020
        return self._matches(match)
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1021
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
  1022
    def _matches(self, match):
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1023
        '''recursively generate a new manifest filtered by the match argument.
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
  1024
        '''
27343
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
  1025
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
  1026
        visit = match.visitdir(self._dir[:-1] or '.')
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
  1027
        if visit == 'all':
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
  1028
            return self.copy()
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1029
        ret = treemanifest(self._dir)
27343
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27271
diff changeset
  1030
        if not visit:
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
  1031
            return ret
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1032
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1033
        self._load()
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1034
        for fn in self._files:
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1035
            fullp = self._subpath(fn)
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1036
            if not match(fullp):
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1037
                continue
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1038
            ret._files[fn] = self._files[fn]
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1039
            if fn in self._flags:
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1040
                ret._flags[fn] = self._flags[fn]
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1041
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1042
        for dir, subm in self._dirs.iteritems():
25188
2773540c3650 match: remove unnecessary optimization where visitdir() returns 'all'
Drew Gottlieb <drgott@google.com>
parents: 25185
diff changeset
  1043
            m = subm._matches(match)
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1044
            if not m._isempty():
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1045
                ret._dirs[dir] = m
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1046
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1047
        if not ret._isempty():
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1048
            ret._dirty = True
24552
a2292da6d821 treemanifest: make treemanifest.matches() faster
Drew Gottlieb <drgott@google.com>
parents: 24551
diff changeset
  1049
        return ret
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1050
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1051
    def diff(self, m2, match=None, clean=False):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1052
        '''Finds changes between the current manifest and m2.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1053
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1054
        Args:
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1055
          m2: the manifest to which this manifest should be compared.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1056
          clean: if true, include files unchanged between these manifests
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1057
                 with a None value in the returned dictionary.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1058
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1059
        The result is returned as a dict with filename as key and
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1060
        values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1061
        nodeid in the current/other manifest and fl1/fl2 is the flag
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1062
        in the current/other manifest. Where the file does not exist,
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1063
        the nodeid will be None and the flags will be the empty
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1064
        string.
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1065
        '''
31255
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1066
        if match:
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1067
            m1 = self.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1068
            m2 = m2.matches(match)
959ebff3505a manifest: add match argument to diff and filesnotin
Durham Goode <durham@fb.com>
parents: 31153
diff changeset
  1069
            return m1.diff(m2, clean=clean)
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1070
        result = {}
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1071
        emptytree = treemanifest()
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1072
        def _diff(t1, t2):
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1073
            if t1._node == t2._node and not t1._dirty and not t2._dirty:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1074
                return
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1075
            t1._load()
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1076
            t2._load()
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1077
            for d, m1 in t1._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1078
                m2 = t2._dirs.get(d, emptytree)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1079
                _diff(m1, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1080
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1081
            for d, m2 in t2._dirs.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1082
                if d not in t1._dirs:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1083
                    _diff(emptytree, m2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1084
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1085
            for fn, n1 in t1._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1086
                fl1 = t1._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1087
                n2 = t2._files.get(fn, None)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1088
                fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1089
                if n1 != n2 or fl1 != fl2:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1090
                    result[t1._subpath(fn)] = ((n1, fl1), (n2, fl2))
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1091
                elif clean:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1092
                    result[t1._subpath(fn)] = None
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1093
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1094
            for fn, n2 in t2._files.iteritems():
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1095
                if fn not in t1._files:
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1096
                    fl2 = t2._flags.get(fn, '')
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1097
                    result[t2._subpath(fn)] = ((None, ''), (n2, fl2))
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1098
24404
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1099
        _diff(self, m2)
96cccf1e3257 treemanifest: make diff() faster
Martin von Zweigbergk <martinvonz@google.com>
parents: 24403
diff changeset
  1100
        return result
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1101
25221
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1102
    def unmodifiedsince(self, m2):
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1103
        return not self._dirty and not m2._dirty and self._node == m2._node
eafa06e9edde treemanifest: speed up commit using dirty flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 25220
diff changeset
  1104
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1105
    def parse(self, text, readsubtree):
24781
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
  1106
        for f, n, fl in _parse(text):
27271
2a31433a59ba manifest: use 't' for tree manifest flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 26871
diff changeset
  1107
            if fl == 't':
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1108
                f = f + '/'
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1109
                self._dirs[f] = readsubtree(self._subpath(f), n)
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1110
            elif '/' in f:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1111
                # This is a flat manifest, so use __setitem__ and setflag rather
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1112
                # than assigning directly to _files and _flags, so we can
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1113
                # assign a path in a subdirectory, and to mark dirty (compared
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1114
                # to nullid).
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1115
                self[f] = n
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1116
                if fl:
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1117
                    self.setflag(f, fl)
25220
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1118
            else:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1119
                # Assigning to _files and _flags avoids marking as dirty,
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1120
                # and should be a little faster.
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1121
                self._files[f] = n
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1122
                if fl:
f0fbd88b21fb treemanifest: speed up diff by keeping track of dirty nodes
Martin von Zweigbergk <martinvonz@google.com>
parents: 25188
diff changeset
  1123
                    self._flags[f] = fl
24781
055b3cbe6c57 treemanifest: extract parse method from constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 24780
diff changeset
  1124
24573
701d3554de0e manifestv2: add support for writing new manifest format
Martin von Zweigbergk <martinvonz@google.com>
parents: 24572
diff changeset
  1125
    def text(self, usemanifestv2=False):
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1126
        """Get the full data of this manifest as a bytestring."""
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1127
        self._load()
28207
43edd3003456 treemanifest: rewrite text() using iterentries()
Martin von Zweigbergk <martinvonz@google.com>
parents: 28206
diff changeset
  1128
        return _text(self.iterentries(), usemanifestv2)
24401
e6e023d57e94 treemanifest: create treemanifest class
Martin von Zweigbergk <martinvonz@google.com>
parents: 24396
diff changeset
  1129
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1130
    def dirtext(self, usemanifestv2=False):
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1131
        """Get the full data of this directory as a bytestring. Make sure that
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1132
        any submanifests have been written first, so their nodeids are correct.
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1133
        """
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1134
        self._load()
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1135
        flags = self.flags
27271
2a31433a59ba manifest: use 't' for tree manifest flag
Martin von Zweigbergk <martinvonz@google.com>
parents: 26871
diff changeset
  1136
        dirs = [(d[:-1], self._dirs[d]._node, 't') for d in self._dirs]
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1137
        files = [(f, self._files[f], flags(f)) for f in self._files]
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1138
        return _text(sorted(dirs + files), usemanifestv2)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1139
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1140
    def read(self, gettext, readsubtree):
26402
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
  1141
        def _load_for_read(s):
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
  1142
            s.parse(gettext(), readsubtree)
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
  1143
            s._dirty = False
05871262acd5 treemanifest: rework lazy-copying code (issue4840)
Augie Fackler <augie@google.com>
parents: 26401
diff changeset
  1144
        self._loadfunc = _load_for_read
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1145
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1146
    def writesubtrees(self, m1, m2, writesubtree):
25222
0de132d5328a treemanifest: lazily load manifests
Martin von Zweigbergk <martinvonz@google.com>
parents: 25221
diff changeset
  1147
        self._load() # for consistency; should never have any effect here
29888
8a84347b9907 manifest: call m1.load and m2.load before writing a subtree
Durham Goode <durham@fb.com>
parents: 29826
diff changeset
  1148
        m1._load()
8a84347b9907 manifest: call m1.load and m2.load before writing a subtree
Durham Goode <durham@fb.com>
parents: 29826
diff changeset
  1149
        m2._load()
25091
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1150
        emptytree = treemanifest()
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1151
        for d, subm in self._dirs.iteritems():
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1152
            subp1 = m1._dirs.get(d, emptytree)._node
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1153
            subp2 = m2._dirs.get(d, emptytree)._node
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1154
            if subp1 == revlog.nullid:
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1155
                subp1, subp2 = subp2, subp1
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1156
            writesubtree(subm, subp1, subp2)
b5052fc73300 treemanifest: store submanifest revlog per directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 24956
diff changeset
  1157
31876
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1158
    def walksubtrees(self, matcher=None):
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1159
        """Returns an iterator of the subtrees of this manifest, including this
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1160
        manifest itself.
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1161
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1162
        If `matcher` is provided, it only returns subtrees that match.
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1163
        """
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1164
        if matcher and not matcher.visitdir(self._dir[:-1] or '.'):
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1165
            return
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1166
        if not matcher or matcher(self._dir[:-1]):
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1167
            yield self
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1168
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1169
        self._load()
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1170
        for d, subm in self._dirs.iteritems():
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1171
            for subtree in subm.walksubtrees(matcher=matcher):
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1172
                yield subtree
94c1d3c1aea2 treemanifest: add walksubtrees api
Durham Goode <durham@fb.com>
parents: 31787
diff changeset
  1173
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1174
class manifestrevlog(revlog.revlog):
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1175
    '''A revlog that stores manifest texts. This is responsible for caching the
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1176
    full-text manifest contents.
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1177
    '''
31151
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1178
    def __init__(self, opener, dir='', dirlogcache=None, indexfile=None):
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1179
        """Constructs a new manifest revlog
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1180
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1181
        `indexfile` - used by extensions to have two manifests at once, like
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1182
        when transitioning between flatmanifeset and treemanifests.
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1183
        """
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1184
        # During normal operations, we expect to deal with not more than four
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1185
        # revs at a time (such as during commit --amend). When rebasing large
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1186
        # stacks of commits, the number can go up, hence the config knob below.
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1187
        cachesize = 4
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1188
        usetreemanifest = False
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1189
        usemanifestv2 = False
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1190
        opts = getattr(opener, 'options', None)
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1191
        if opts is not None:
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1192
            cachesize = opts.get('manifestcachesize', cachesize)
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1193
            usetreemanifest = opts.get('treemanifest', usetreemanifest)
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1194
            usemanifestv2 = opts.get('manifestv2', usemanifestv2)
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1195
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1196
        self._treeondisk = usetreemanifest
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1197
        self._usemanifestv2 = usemanifestv2
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1198
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1199
        self._fulltextcache = util.lrucachedict(cachesize)
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1200
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1201
        if dir:
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1202
            assert self._treeondisk, 'opts is %r' % opts
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1203
            if not dir.endswith('/'):
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1204
                dir = dir + '/'
31151
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1205
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1206
        if indexfile is None:
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1207
            indexfile = '00manifest.i'
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1208
            if dir:
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1209
                indexfile = "meta/" + dir + indexfile
6d9f8bc2b5ea manifest: allow specifying the revlog filename
Durham Goode <durham@fb.com>
parents: 31097
diff changeset
  1210
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1211
        self._dir = dir
29941
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1212
        # The dirlogcache is kept on the root manifest log
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1213
        if dir:
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1214
            self._dirlogcache = dirlogcache
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1215
        else:
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1216
            self._dirlogcache = {'': self}
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1217
29998
14ad8e2a4abe manifest: specify checkambig=True to revlog.__init__, to avoid ambiguity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29962
diff changeset
  1218
        super(manifestrevlog, self).__init__(opener, indexfile,
14ad8e2a4abe manifest: specify checkambig=True to revlog.__init__, to avoid ambiguity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29962
diff changeset
  1219
                                             checkambig=bool(dir))
29940
fa145a205a7f manifest: move revlog specific options from manifest to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29939
diff changeset
  1220
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1221
    @property
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1222
    def fulltextcache(self):
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1223
        return self._fulltextcache
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1224
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1225
    def clearcaches(self):
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1226
        super(manifestrevlog, self).clearcaches()
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1227
        self._fulltextcache.clear()
29941
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1228
        self._dirlogcache = {'': self}
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1229
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1230
    def dirlog(self, dir):
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1231
        if dir:
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1232
            assert self._treeondisk
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1233
        if dir not in self._dirlogcache:
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1234
            self._dirlogcache[dir] = manifestrevlog(self.opener, dir,
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1235
                                                    self._dirlogcache)
1cc93a154723 manifest: move dirlog up to manifestrevlog
Durham Goode <durham@fb.com>
parents: 29940
diff changeset
  1236
        return self._dirlogcache[dir]
29824
58d4ecdc531e manifest: make manifest derive from manifestrevlog
Durham Goode <durham@fb.com>
parents: 29823
diff changeset
  1237
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1238
    def add(self, m, transaction, link, p1, p2, added, removed, readtree=None):
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1239
        if (p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta')
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1240
            and not self._usemanifestv2):
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1241
            # If our first parent is in the manifest cache, we can
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1242
            # compute a delta here using properties we know about the
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1243
            # manifest up-front, which may save time later for the
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1244
            # revlog layer.
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1245
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1246
            _checkforbidden(added)
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1247
            # combine the changed lists into one sorted iterator
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1248
            work = heapq.merge([(x, False) for x in added],
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1249
                               [(x, True) for x in removed])
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1250
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1251
            arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1252
            cachedelta = self.rev(p1), deltatext
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1253
            text = util.buffer(arraytext)
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1254
            n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1255
        else:
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1256
            # The first parent manifest isn't already loaded, so we'll
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1257
            # just encode a fulltext of the manifest and pass that
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1258
            # through to the revlog layer, and let it handle the delta
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1259
            # process.
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1260
            if self._treeondisk:
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1261
                assert readtree, "readtree must be set for treemanifest writes"
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1262
                m1 = readtree(self._dir, p1)
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1263
                m2 = readtree(self._dir, p2)
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1264
                n = self._addtree(m, transaction, link, m1, m2, readtree)
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1265
                arraytext = None
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1266
            else:
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1267
                text = m.text(self._usemanifestv2)
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1268
                n = self.addrevision(text, transaction, link, p1, p2)
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
  1269
                arraytext = bytearray(text)
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1270
30209
9d06b65c5df2 manifest: don't store None in fulltextcache
Martin von Zweigbergk <martinvonz@google.com>
parents: 30207
diff changeset
  1271
        if arraytext is not None:
9d06b65c5df2 manifest: don't store None in fulltextcache
Martin von Zweigbergk <martinvonz@google.com>
parents: 30207
diff changeset
  1272
            self.fulltextcache[n] = arraytext
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1273
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1274
        return n
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1275
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1276
    def _addtree(self, m, transaction, link, m1, m2, readtree):
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1277
        # If the manifest is unchanged compared to one parent,
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1278
        # don't write a new revision
31294
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1279
        if self._dir != '' and (m.unmodifiedsince(m1) or m.unmodifiedsince(m2)):
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1280
            return m.node()
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1281
        def writesubtree(subm, subp1, subp2):
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1282
            sublog = self.dirlog(subm.dir())
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1283
            sublog.add(subm, transaction, link, subp1, subp2, None, None,
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1284
                       readtree=readtree)
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1285
        m.writesubtrees(m1, m2, writesubtree)
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1286
        text = m.dirtext(self._usemanifestv2)
31294
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1287
        n = None
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1288
        if self._dir != '':
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1289
            # Double-check whether contents are unchanged to one parent
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1290
            if text == m1.dirtext(self._usemanifestv2):
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1291
                n = m1.node()
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1292
            elif text == m2.dirtext(self._usemanifestv2):
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1293
                n = m2.node()
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1294
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1295
        if not n:
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1296
            n = self.addrevision(text, transaction, link, m1.node(), m2.node())
31294
c134a33b1d73 treemanifest: make node reuse match flat manifest behavior
Durham Goode <durham@fb.com>
parents: 31255
diff changeset
  1297
29961
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1298
        # Save nodeid so parent manifest can calculate its nodeid
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1299
        m.setnode(n)
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1300
        return n
774a15b129e8 manifest: move manifest.add onto manifestrevlog
Durham Goode <durham@fb.com>
parents: 29960
diff changeset
  1301
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1302
class manifestlog(object):
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1303
    """A collection class representing the collection of manifest snapshots
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1304
    referenced by commits in the repository.
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1305
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1306
    In this situation, 'manifest' refers to the abstract concept of a snapshot
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1307
    of the list of files in the given commit. Consumers of the output of this
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1308
    class do not care about the implementation details of the actual manifests
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1309
    they receive (i.e. tree or flat or lazily loaded, etc)."""
29826
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
  1310
    def __init__(self, opener, repo):
29959
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1311
        usetreemanifest = False
30372
7c7d845f8b64 manifest: make manifestlog use it's own cache
Durham Goode <durham@fb.com>
parents: 30371
diff changeset
  1312
        cachesize = 4
29959
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1313
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1314
        opts = getattr(opener, 'options', None)
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1315
        if opts is not None:
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1316
            usetreemanifest = opts.get('treemanifest', usetreemanifest)
30372
7c7d845f8b64 manifest: make manifestlog use it's own cache
Durham Goode <durham@fb.com>
parents: 30371
diff changeset
  1317
            cachesize = opts.get('manifestcachesize', cachesize)
29959
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1318
        self._treeinmem = usetreemanifest
483003c27938 manifest: move treeinmem onto manifestlog
Durham Goode <durham@fb.com>
parents: 29941
diff changeset
  1319
30219
3c8811efdddc manifest: make manifestlog a storecache
Durham Goode <durham@fb.com>
parents: 30209
diff changeset
  1320
        self._oldmanifest = repo._constructmanifest()
3c8811efdddc manifest: make manifestlog a storecache
Durham Goode <durham@fb.com>
parents: 30209
diff changeset
  1321
        self._revlog = self._oldmanifest
3c8811efdddc manifest: make manifestlog a storecache
Durham Goode <durham@fb.com>
parents: 30209
diff changeset
  1322
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1323
        # A cache of the manifestctx or treemanifestctx for each directory
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1324
        self._dirmancache = {}
30372
7c7d845f8b64 manifest: make manifestlog use it's own cache
Durham Goode <durham@fb.com>
parents: 30371
diff changeset
  1325
        self._dirmancache[''] = util.lrucachedict(cachesize)
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1326
30372
7c7d845f8b64 manifest: make manifestlog use it's own cache
Durham Goode <durham@fb.com>
parents: 30371
diff changeset
  1327
        self.cachesize = cachesize
29826
93b44aa17691 manifest: use property instead of field for manifest revlog storage
Durham Goode <durham@fb.com>
parents: 29825
diff changeset
  1328
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1329
    def __getitem__(self, node):
30290
1a0c1ad57833 manifest: throw LookupError if node not in revlog
Durham Goode <durham@fb.com>
parents: 30221
diff changeset
  1330
        """Retrieves the manifest instance for the given node. Throws a
1a0c1ad57833 manifest: throw LookupError if node not in revlog
Durham Goode <durham@fb.com>
parents: 30221
diff changeset
  1331
        LookupError if not found.
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1332
        """
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1333
        return self.get('', node)
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1334
30403
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1335
    def get(self, dir, node, verify=True):
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1336
        """Retrieves the manifest instance for the given node. Throws a
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1337
        LookupError if not found.
30403
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1338
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1339
        `verify` - if True an exception will be thrown if the node is not in
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1340
                   the revlog
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1341
        """
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1342
        if node in self._dirmancache.get(dir, ()):
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1343
            cachemf = self._dirmancache[dir][node]
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1344
            # The old manifest may put non-ctx manifests in the cache, so
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1345
            # skip those since they don't implement the full api.
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1346
            if (isinstance(cachemf, manifestctx) or
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1347
                isinstance(cachemf, treemanifestctx)):
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1348
                return cachemf
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1349
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1350
        if dir:
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1351
            if self._revlog._treeondisk:
30403
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1352
                if verify:
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1353
                    dirlog = self._revlog.dirlog(dir)
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1354
                    if node not in dirlog.nodemap:
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1355
                        raise LookupError(node, dirlog.indexfile,
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1356
                                          _('no node'))
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1357
                m = treemanifestctx(self, dir, node)
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1358
            else:
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1359
                raise error.Abort(
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1360
                        _("cannot ask for manifest directory '%s' in a flat "
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1361
                          "manifest") % dir)
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1362
        else:
30403
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1363
            if verify:
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1364
                if node not in self._revlog.nodemap:
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1365
                    raise LookupError(node, self._revlog.indexfile,
a431daa93f8c manifest: make revlog verification optional
Durham Goode <durham@fb.com>
parents: 30377
diff changeset
  1366
                                      _('no node'))
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1367
            if self._treeinmem:
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1368
                m = treemanifestctx(self, '', node)
30291
dc21ea3323c4 manifest: add manifestlog.get to obtain subdirectory instances
Durham Goode <durham@fb.com>
parents: 30290
diff changeset
  1369
            else:
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1370
                m = manifestctx(self, node)
30292
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1371
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1372
        if node != revlog.nullid:
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1373
            mancache = self._dirmancache.get(dir)
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1374
            if not mancache:
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1375
                mancache = util.lrucachedict(self.cachesize)
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1376
                self._dirmancache[dir] = mancache
d4b340bf68c5 manifest: change manifestlog mancache to be directory based
Durham Goode <durham@fb.com>
parents: 30291
diff changeset
  1377
            mancache[node] = m
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1378
        return m
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1379
30370
10c924596e5c manifest: move clearcaches to manifestlog
Durham Goode <durham@fb.com>
parents: 30369
diff changeset
  1380
    def clearcaches(self):
10c924596e5c manifest: move clearcaches to manifestlog
Durham Goode <durham@fb.com>
parents: 30369
diff changeset
  1381
        self._dirmancache.clear()
10c924596e5c manifest: move clearcaches to manifestlog
Durham Goode <durham@fb.com>
parents: 30369
diff changeset
  1382
        self._revlog.clearcaches()
10c924596e5c manifest: move clearcaches to manifestlog
Durham Goode <durham@fb.com>
parents: 30369
diff changeset
  1383
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1384
class memmanifestctx(object):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1385
    def __init__(self, manifestlog):
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1386
        self._manifestlog = manifestlog
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1387
        self._manifestdict = manifestdict()
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1388
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1389
    def _revlog(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1390
        return self._manifestlog._revlog
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1391
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1392
    def new(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1393
        return memmanifestctx(self._manifestlog)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1394
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1395
    def copy(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1396
        memmf = memmanifestctx(self._manifestlog)
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1397
        memmf._manifestdict = self.read().copy()
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1398
        return memmf
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1399
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1400
    def read(self):
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1401
        return self._manifestdict
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1402
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1403
    def write(self, transaction, link, p1, p2, added, removed):
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1404
        return self._revlog().add(self._manifestdict, transaction, link, p1, p2,
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1405
                                  added, removed)
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1406
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1407
class manifestctx(object):
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1408
    """A class representing a single revision of a manifest, including its
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1409
    contents, its parent revs, and its linkrev.
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1410
    """
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1411
    def __init__(self, manifestlog, node):
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1412
        self._manifestlog = manifestlog
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1413
        self._data = None
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1414
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1415
        self._node = node
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1416
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1417
        # TODO: We eventually want p1, p2, and linkrev exposed on this class,
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1418
        # but let's add it later when something needs it and we can load it
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1419
        # lazily.
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1420
        #self.p1, self.p2 = revlog.parents(node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1421
        #rev = revlog.rev(node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1422
        #self.linkrev = revlog.linkrev(rev)
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1423
30341
3dfb5a0171c9 manifestctx: add _revlog() function
Durham Goode <durham@fb.com>
parents: 30340
diff changeset
  1424
    def _revlog(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1425
        return self._manifestlog._revlog
30341
3dfb5a0171c9 manifestctx: add _revlog() function
Durham Goode <durham@fb.com>
parents: 30340
diff changeset
  1426
29825
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1427
    def node(self):
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1428
        return self._node
426d931e5db2 manifest: introduce manifestlog and manifestctx classes
Durham Goode <durham@fb.com>
parents: 29824
diff changeset
  1429
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1430
    def new(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1431
        return memmanifestctx(self._manifestlog)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1432
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1433
    def copy(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1434
        memmf = memmanifestctx(self._manifestlog)
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1435
        memmf._manifestdict = self.read().copy()
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1436
        return memmf
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1437
30565
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1438
    @propertycache
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1439
    def parents(self):
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1440
        return self._revlog().parents(self._node)
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1441
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1442
    def read(self):
31097
4a1486c73fdf manifest: check 'if x is None' instead of 'if not x'
Durham Goode <durham@fb.com>
parents: 30565
diff changeset
  1443
        if self._data is None:
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1444
            if self._node == revlog.nullid:
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1445
                self._data = manifestdict()
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1446
            else:
30341
3dfb5a0171c9 manifestctx: add _revlog() function
Durham Goode <durham@fb.com>
parents: 30340
diff changeset
  1447
                rl = self._revlog()
30220
acc8885a6450 manifest: make manifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30219
diff changeset
  1448
                text = rl.revision(self._node)
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
  1449
                arraytext = bytearray(text)
30220
acc8885a6450 manifest: make manifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30219
diff changeset
  1450
                rl._fulltextcache[self._node] = arraytext
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1451
                self._data = manifestdict(text)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1452
        return self._data
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1453
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1454
    def readfast(self, shallow=False):
30294
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1455
        '''Calls either readdelta or read, based on which would be less work.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1456
        readdelta is called if the delta is against the p1, and therefore can be
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1457
        read quickly.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1458
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1459
        If `shallow` is True, nothing changes since this is a flat manifest.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1460
        '''
30341
3dfb5a0171c9 manifestctx: add _revlog() function
Durham Goode <durham@fb.com>
parents: 30340
diff changeset
  1461
        rl = self._revlog()
29939
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1462
        r = rl.rev(self._node)
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1463
        deltaparent = rl.deltaparent(r)
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1464
        if deltaparent != revlog.nullrev and deltaparent in rl.parentrevs(r):
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1465
            return self.readdelta()
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1466
        return self.read()
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1467
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1468
    def readdelta(self, shallow=False):
30295
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1469
        '''Returns a manifest containing just the entries that are present
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1470
        in this manifest, but not in its p1 manifest. This is efficient to read
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1471
        if the revlog delta is already p1.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1472
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1473
        Changing the value of `shallow` has no effect on flat manifests.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1474
        '''
30341
3dfb5a0171c9 manifestctx: add _revlog() function
Durham Goode <durham@fb.com>
parents: 30340
diff changeset
  1475
        revlog = self._revlog()
29938
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1476
        if revlog._usemanifestv2:
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1477
            # Need to perform a slow delta
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1478
            r0 = revlog.deltaparent(revlog.rev(self._node))
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1479
            m0 = self._manifestlog[revlog.node(r0)].read()
29938
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1480
            m1 = self.read()
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1481
            md = manifestdict()
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1482
            for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1483
                if n1:
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1484
                    md[f] = n1
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1485
                    if fl1:
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1486
                        md.setflag(f, fl1)
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1487
            return md
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1488
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1489
        r = revlog.rev(self._node)
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1490
        d = mdiff.patchtext(revlog.revdiff(revlog.deltaparent(r), r))
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1491
        return manifestdict(d)
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1492
30340
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1493
    def find(self, key):
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1494
        return self.read().find(key)
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1495
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1496
class memtreemanifestctx(object):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1497
    def __init__(self, manifestlog, dir=''):
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1498
        self._manifestlog = manifestlog
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1499
        self._dir = dir
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1500
        self._treemanifest = treemanifest()
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1501
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1502
    def _revlog(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1503
        return self._manifestlog._revlog
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1504
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1505
    def new(self, dir=''):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1506
        return memtreemanifestctx(self._manifestlog, dir=dir)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1507
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1508
    def copy(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1509
        memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1510
        memmf._treemanifest = self._treemanifest.copy()
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1511
        return memmf
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1512
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1513
    def read(self):
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1514
        return self._treemanifest
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1515
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1516
    def write(self, transaction, link, p1, p2, added, removed):
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1517
        def readtree(dir, node):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1518
            return self._manifestlog.get(dir, node).read()
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1519
        return self._revlog().add(self._treemanifest, transaction, link, p1, p2,
30368
ed45283a0ca7 manifest: remove dependency on manifestrevlog being able to create trees
Durham Goode <durham@fb.com>
parents: 30345
diff changeset
  1520
                                  added, removed, readtree=readtree)
30345
fa54f7ade491 manifest: remove manifest.add and add memmfctx.write
Durham Goode <durham@fb.com>
parents: 30343
diff changeset
  1521
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1522
class treemanifestctx(object):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1523
    def __init__(self, manifestlog, dir, node):
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1524
        self._manifestlog = manifestlog
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1525
        self._dir = dir
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1526
        self._data = None
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1527
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1528
        self._node = node
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1529
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1530
        # TODO: Load p1/p2/linkrev lazily. They need to be lazily loaded so that
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1531
        # we can instantiate treemanifestctx objects for directories we don't
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1532
        # have on disk.
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1533
        #self.p1, self.p2 = revlog.parents(node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1534
        #rev = revlog.rev(node)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1535
        #self.linkrev = revlog.linkrev(rev)
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1536
30221
f2c5b9d48b29 manifest: make treemanifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30220
diff changeset
  1537
    def _revlog(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1538
        return self._manifestlog._revlog.dirlog(self._dir)
30221
f2c5b9d48b29 manifest: make treemanifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30220
diff changeset
  1539
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1540
    def read(self):
31097
4a1486c73fdf manifest: check 'if x is None' instead of 'if not x'
Durham Goode <durham@fb.com>
parents: 30565
diff changeset
  1541
        if self._data is None:
30221
f2c5b9d48b29 manifest: make treemanifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30220
diff changeset
  1542
            rl = self._revlog()
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1543
            if self._node == revlog.nullid:
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1544
                self._data = treemanifest()
30221
f2c5b9d48b29 manifest: make treemanifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30220
diff changeset
  1545
            elif rl._treeondisk:
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1546
                m = treemanifest(dir=self._dir)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1547
                def gettext():
30221
f2c5b9d48b29 manifest: make treemanifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30220
diff changeset
  1548
                    return rl.revision(self._node)
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1549
                def readsubtree(dir, subm):
30404
a1beadaa4061 manifest: change treemanifestctx to construct subtrees from the manifestlog
Durham Goode <durham@fb.com>
parents: 30403
diff changeset
  1550
                    # Set verify to False since we need to be able to create
a1beadaa4061 manifest: change treemanifestctx to construct subtrees from the manifestlog
Durham Goode <durham@fb.com>
parents: 30403
diff changeset
  1551
                    # subtrees for trees that don't exist on disk.
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1552
                    return self._manifestlog.get(dir, subm, verify=False).read()
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1553
                m.read(gettext, readsubtree)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1554
                m.setnode(self._node)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1555
                self._data = m
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1556
            else:
30338
b0ca939414ea treemanifest: fix a "treeinmem" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 30331
diff changeset
  1557
                text = rl.revision(self._node)
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 31294
diff changeset
  1558
                arraytext = bytearray(text)
30221
f2c5b9d48b29 manifest: make treemanifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30220
diff changeset
  1559
                rl.fulltextcache[self._node] = arraytext
29926
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1560
                self._data = treemanifest(dir=self._dir, text=text)
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1561
be16091ac14d manifest: change manifestctx to not inherit from manifestdict
Durham Goode <durham@fb.com>
parents: 29916
diff changeset
  1562
        return self._data
29907
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1563
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1564
    def node(self):
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1565
        return self._node
4fb4fc331699 manifest: add treemanifestctx class
Durham Goode <durham@fb.com>
parents: 29888
diff changeset
  1566
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1567
    def new(self, dir=''):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1568
        return memtreemanifestctx(self._manifestlog, dir=dir)
30342
fe1ee393de78 manifest: introduce memmanifestctx and memtreemanifestctx
Durham Goode <durham@fb.com>
parents: 30341
diff changeset
  1569
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1570
    def copy(self):
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1571
        memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
30343
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1572
        memmf._treemanifest = self.read().copy()
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1573
        return memmf
952e1916ae56 manifest: add copy to mfctx classes
Durham Goode <durham@fb.com>
parents: 30342
diff changeset
  1574
30565
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1575
    @propertycache
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1576
    def parents(self):
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1577
        return self._revlog().parents(self._node)
7fbc8a742b4d manifest: expose the parents() method
Mateusz Kwapich <mitrandir@fb.com>
parents: 30443
diff changeset
  1578
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1579
    def readdelta(self, shallow=False):
30295
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1580
        '''Returns a manifest containing just the entries that are present
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1581
        in this manifest, but not in its p1 manifest. This is efficient to read
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1582
        if the revlog delta is already p1.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1583
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1584
        If `shallow` is True, this will read the delta for this directory,
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1585
        without recursively reading subdirectory manifests. Instead, any
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1586
        subdirectory entry will be reported as it appears in the manifest, i.e.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1587
        the subdirectory will be reported among files and distinguished only by
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1588
        its 't' flag.
f65faa4422c8 manifest: remove manifest.readshallowdelta
Durham Goode <durham@fb.com>
parents: 30294
diff changeset
  1589
        '''
30221
f2c5b9d48b29 manifest: make treemanifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30220
diff changeset
  1590
        revlog = self._revlog()
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1591
        if shallow and not revlog._usemanifestv2:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1592
            r = revlog.rev(self._node)
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1593
            d = mdiff.patchtext(revlog.revdiff(revlog.deltaparent(r), r))
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1594
            return manifestdict(d)
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1595
        else:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1596
            # Need to perform a slow delta
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1597
            r0 = revlog.deltaparent(revlog.rev(self._node))
31153
5cab44fd1257 manifest: remove _repo from manifestctx objects
Durham Goode <durham@fb.com>
parents: 31151
diff changeset
  1598
            m0 = self._manifestlog.get(self._dir, revlog.node(r0)).read()
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1599
            m1 = self.read()
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1600
            md = treemanifest(dir=self._dir)
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1601
            for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1602
                if n1:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1603
                    md[f] = n1
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1604
                    if fl1:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1605
                        md.setflag(f, fl1)
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1606
            return md
29938
a059b17352ef manifest: add manifestctx.readdelta()
Durham Goode <durham@fb.com>
parents: 29926
diff changeset
  1607
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1608
    def readfast(self, shallow=False):
30294
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1609
        '''Calls either readdelta or read, based on which would be less work.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1610
        readdelta is called if the delta is against the p1, and therefore can be
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1611
        read quickly.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1612
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1613
        If `shallow` is True, it only returns the entries from this manifest,
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1614
        and not any submanifests.
bce79dfcf5e4 manifest: get rid of manifest.readshallowfast
Durham Goode <durham@fb.com>
parents: 30293
diff changeset
  1615
        '''
30221
f2c5b9d48b29 manifest: make treemanifestctx store the repo
Durham Goode <durham@fb.com>
parents: 30220
diff changeset
  1616
        rl = self._revlog()
29939
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1617
        r = rl.rev(self._node)
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1618
        deltaparent = rl.deltaparent(r)
30293
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1619
        if (deltaparent != revlog.nullrev and
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1620
            deltaparent in rl.parentrevs(r)):
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1621
            return self.readdelta(shallow=shallow)
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1622
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1623
        if shallow:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1624
            return manifestdict(rl.revision(self._node))
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1625
        else:
78f3c7166f0d manifest: add shallow option to treemanifestctx.readdelta and readfast
Durham Goode <durham@fb.com>
parents: 30292
diff changeset
  1626
            return self.read()
29939
80be4436e4cc manifest: adds manifestctx.readfast
Durham Goode <durham@fb.com>
parents: 29938
diff changeset
  1627
30340
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1628
    def find(self, key):
608ba935e041 manifest: remove manifest.find
Durham Goode <durham@fb.com>
parents: 30338
diff changeset
  1629
        return self.read().find(key)