mercurial/revlog.py
author Matt Harbison <matt_harbison@yahoo.com>
Tue, 17 Mar 2015 22:21:09 -0400
changeset 24363 852801178a63
parent 24255 4bfe9f2d9761
child 24444 27e3ba73fbb1
permissions -rw-r--r--
test-commit-interactive-curses: #require 'tic' When run on Windows, this test aborts: @@ -20,7 +20,8 @@ > X > EOF $ hg commit -i -m "a" -d "0 0" - no changes to record + abort: No module named fcntl! + [255] $ hg tip changeset: -1:000000000000 tag: tip Maybe there's another way to get the screen size on Windows (it dies in crecord.gethw()), but for now, quiet the test noise by skipping it if terminal info compiler is unavailable.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     1
# revlog.py - storage back-end for mercurial
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     2
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     4
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
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: 10047
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
8227
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
     8
"""Storage back-end for Mercurial.
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
     9
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
    10
This provides efficient delta storage with O(1) retrieve and append
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
    11
and O(changes) merge between branches.
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
    12
"""
0a9542703300 turn some comments back into module docstrings
Martin Geisler <mg@lazybytes.net>
parents: 8226
diff changeset
    13
7873
4a4c7f6a5912 cleanup: drop unused imports
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7633
diff changeset
    14
# import stuff from node for others to import from revlog
14393
bdf44e63a94c revlog: stop exporting node.short
Matt Mackall <mpm@selenic.com>
parents: 14371
diff changeset
    15
from node import bin, hex, nullid, nullrev
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
    16
from i18n import _
19624
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
    17
import ancestor, mdiff, parsers, error, util, templatefilters
16834
cafd8a8fb713 util: subclass deque for Python 2.4 backwards compatibility
Bryan O'Sullivan <bryano@fb.com>
parents: 16803
diff changeset
    18
import struct, zlib, errno
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
    19
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    20
_pack = struct.pack
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    21
_unpack = struct.unpack
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    22
_compress = zlib.compress
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    23
_decompress = zlib.decompress
6470
ac0bcd951c2c python 2.6 compatibility: compatibility wrappers for hash functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6264
diff changeset
    24
_sha = util.sha1
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
    25
11746
46ac30b17978 revlog: add shallow header flag
Vishakh H <vsh426@gmail.com>
parents: 11745
diff changeset
    26
# revlog header flags
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
    27
REVLOGV0 = 0
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
    28
REVLOGNG = 1
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
    29
REVLOGNGINLINEDATA = (1 << 16)
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
    30
REVLOGGENERALDELTA = (1 << 17)
2222
c9e264b115e6 Use revlogng and inlined data files by default
mason@suse.com
parents: 2177
diff changeset
    31
REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA
c9e264b115e6 Use revlogng and inlined data files by default
mason@suse.com
parents: 2177
diff changeset
    32
REVLOG_DEFAULT_FORMAT = REVLOGNG
c9e264b115e6 Use revlogng and inlined data files by default
mason@suse.com
parents: 2177
diff changeset
    33
REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
    34
REVLOGNG_FLAGS = REVLOGNGINLINEDATA | REVLOGGENERALDELTA
11746
46ac30b17978 revlog: add shallow header flag
Vishakh H <vsh426@gmail.com>
parents: 11745
diff changeset
    35
46ac30b17978 revlog: add shallow header flag
Vishakh H <vsh426@gmail.com>
parents: 11745
diff changeset
    36
# revlog index flags
23855
4f23081c901e revlog: define censored flag for revlogng index
Mike Edgar <adgar@google.com>
parents: 23338
diff changeset
    37
REVIDX_ISCENSORED = (1 << 15) # revision has censor metadata, must be verified
4f23081c901e revlog: define censored flag for revlogng index
Mike Edgar <adgar@google.com>
parents: 23338
diff changeset
    38
REVIDX_DEFAULT_FLAGS = 0
4f23081c901e revlog: define censored flag for revlogng index
Mike Edgar <adgar@google.com>
parents: 23338
diff changeset
    39
REVIDX_KNOWN_FLAGS = REVIDX_ISCENSORED
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
    40
10916
9c84395a338e add documentation for revlog._prereadsize
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10914
diff changeset
    41
# max size of revlog with inline data
9c84395a338e add documentation for revlog._prereadsize
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10914
diff changeset
    42
_maxinline = 131072
13253
61c9bc3da402 revlog: remove lazy index
Matt Mackall <mpm@selenic.com>
parents: 13239
diff changeset
    43
_chunksize = 1048576
10913
f2ecc5733c89 revlog: factor out _maxinline global.
Greg Ward <greg-hg@gerg.ca>
parents: 10404
diff changeset
    44
7633
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7365
diff changeset
    45
RevlogError = error.RevlogError
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7365
diff changeset
    46
LookupError = error.LookupError
22934
8a096d4d0862 revlog: support importing censored file revision tombstones
Mike Edgar <adgar@google.com>
parents: 22785
diff changeset
    47
CensoredNodeError = error.CensoredNodeError
6703
bacfee67c1a9 LookupError should have same __str__ as RevlogError
Alexander Solovyov <piranha@piranha.org.ua>
parents: 6700
diff changeset
    48
4987
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    49
def getoffset(q):
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    50
    return int(q >> 16)
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    51
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    52
def gettype(q):
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    53
    return int(q & 0xFFFF)
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    54
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    55
def offset_type(offset, type):
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    56
    return long(long(offset) << 16 | type)
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
    57
22784
0f4e655136ef revlog: mark nullhash as module-private
Augie Fackler <raf@durin42.com>
parents: 22389
diff changeset
    58
_nullhash = _sha(nullid)
7883
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    59
1091
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    60
def hash(text, p1, p2):
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    61
    """generate a hash from the given text and its parent hashes
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    62
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    63
    This hash combines both the current file contents and its history
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    64
    in a manner that makes it easy to distinguish nodes with the same
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    65
    content in the revision graph.
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    66
    """
7883
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    67
    # As of now, if one of the parent node is null, p2 is null
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    68
    if p2 == nullid:
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    69
        # deep copy of a hash is faster than creating one
22784
0f4e655136ef revlog: mark nullhash as module-private
Augie Fackler <raf@durin42.com>
parents: 22389
diff changeset
    70
        s = _nullhash.copy()
7883
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    71
        s.update(p1)
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    72
    else:
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    73
        # none of the parent nodes are nullid
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    74
        l = [p1, p2]
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    75
        l.sort()
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    76
        s = _sha(l[0])
c63c30ae9e39 revlog: faster hash computation when one of the parent node is null
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7874
diff changeset
    77
        s.update(l[1])
1091
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    78
    s.update(text)
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    79
    return s.digest()
d62130f99a73 Move hash function back to revlog from node
mpm@selenic.com
parents: 1089
diff changeset
    80
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    81
def decompress(bin):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
    82
    """ decompress the given input """
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    83
    if not bin:
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    84
        return bin
112
aea6562add6c Make compression more intelligent:
mpm@selenic.com
parents: 98
diff changeset
    85
    t = bin[0]
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    86
    if t == '\0':
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    87
        return bin
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    88
    if t == 'x':
16883
5e3a1b96dbb0 revlog: zlib.error sent to the user (issue3424)
Brad Hall <bhall@fb.com>
parents: 16834
diff changeset
    89
        try:
5e3a1b96dbb0 revlog: zlib.error sent to the user (issue3424)
Brad Hall <bhall@fb.com>
parents: 16834
diff changeset
    90
            return _decompress(bin)
5e3a1b96dbb0 revlog: zlib.error sent to the user (issue3424)
Brad Hall <bhall@fb.com>
parents: 16834
diff changeset
    91
        except zlib.error, e:
5e3a1b96dbb0 revlog: zlib.error sent to the user (issue3424)
Brad Hall <bhall@fb.com>
parents: 16834
diff changeset
    92
            raise RevlogError(_("revlog decompress error: %s") % str(e))
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    93
    if t == 'u':
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
    94
        return bin[1:]
1853
5ac811b720de Fix some problems when working on broken repositories:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1784
diff changeset
    95
    raise RevlogError(_("unknown compression type %r") % t)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    96
18585
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
    97
# index v0:
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
    98
#  4 bytes: offset
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
    99
#  4 bytes: compressed length
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
   100
#  4 bytes: base rev
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
   101
#  4 bytes: link rev
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
   102
# 32 bytes: parent 1 nodeid
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
   103
# 32 bytes: parent 2 nodeid
b280f3bfc8a0 revlog: document v0 format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18090
diff changeset
   104
# 32 bytes: nodeid
4987
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   105
indexformatv0 = ">4l20s20s20s"
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   106
v0shaoffset = 56
4918
e017d3a82e1d revlog: raise offset/type helpers to global scope
Matt Mackall <mpm@selenic.com>
parents: 4746
diff changeset
   107
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   108
class revlogoldio(object):
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   109
    def __init__(self):
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   110
        self.size = struct.calcsize(indexformatv0)
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   111
13264
8439526fb407 revlog/parseindex: no need to pass the file around
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13259
diff changeset
   112
    def parseindex(self, data, inline):
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   113
        s = self.size
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   114
        index = []
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   115
        nodemap =  {nullid: nullrev}
4973
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   116
        n = off = 0
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   117
        l = len(data)
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   118
        while off + s <= l:
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   119
            cur = data[off:off + s]
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   120
            off += s
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
   121
            e = _unpack(indexformatv0, cur)
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   122
            # transform to revlogv1 format
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   123
            e2 = (offset_type(e[0], 0), e[1], -1, e[2], e[3],
5544
686899a7de5b revlog: make revlogv0 loading more robust against corruption
Matt Mackall <mpm@selenic.com>
parents: 5453
diff changeset
   124
                  nodemap.get(e[4], nullrev), nodemap.get(e[5], nullrev), e[6])
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   125
            index.append(e2)
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   126
            nodemap[e[6]] = n
4973
a386a6e4fe46 revlog: simplify the v0 parser
Matt Mackall <mpm@selenic.com>
parents: 4972
diff changeset
   127
            n += 1
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   128
13265
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   129
        # add the magic null revision at -1
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   130
        index.append((0, 0, 0, -1, -1, -1, -1, nullid))
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   131
4983
4dbcfc6e359e revlog: pull chunkcache back into revlog
Matt Mackall <mpm@selenic.com>
parents: 4982
diff changeset
   132
        return index, nodemap, None
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   133
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
   134
    def packentry(self, entry, node, version, rev):
10395
ea52a2d4f42c revlog: don't silently discard revlog flags on revlogv0
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10329
diff changeset
   135
        if gettype(entry[0]):
ea52a2d4f42c revlog: don't silently discard revlog flags on revlogv0
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10329
diff changeset
   136
            raise RevlogError(_("index entry flags need RevlogNG"))
4986
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   137
        e2 = (getoffset(entry[0]), entry[1], entry[3], entry[4],
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   138
              node(entry[5]), node(entry[6]), entry[7])
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
   139
        return _pack(indexformatv0, *e2)
4986
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   140
4987
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   141
# index ng:
11323
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   142
#  6 bytes: offset
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   143
#  2 bytes: flags
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   144
#  4 bytes: compressed length
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   145
#  4 bytes: uncompressed length
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   146
#  4 bytes: base rev
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   147
#  4 bytes: link rev
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   148
#  4 bytes: parent 1 rev
d65b74106113 revlog: fix inconsistent comment formatting
Martin Geisler <mg@aragost.com>
parents: 11155
diff changeset
   149
#  4 bytes: parent 2 rev
4987
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   150
# 32 bytes: nodeid
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   151
indexformatng = ">Qiiiiii20s12x"
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   152
ngshaoffset = 32
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   153
versionformat = ">I"
8d30004ada40 revlog: some basic code reordering
Matt Mackall <mpm@selenic.com>
parents: 4986
diff changeset
   154
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   155
class revlogio(object):
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   156
    def __init__(self):
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   157
        self.size = struct.calcsize(indexformatng)
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   158
13264
8439526fb407 revlog/parseindex: no need to pass the file around
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13259
diff changeset
   159
    def parseindex(self, data, inline):
7109
528b7fc1216c use the new parseindex implementation C in parsers
Bernhard Leiner <bleiner@gmail.com>
parents: 7089
diff changeset
   160
        # call the C implementation to parse the index data
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 13253
diff changeset
   161
        index, cache = parsers.parse_index2(data, inline)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   162
        return index, getattr(index, 'nodemap', None), cache
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   163
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
   164
    def packentry(self, entry, node, version, rev):
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
   165
        p = _pack(indexformatng, *entry)
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
   166
        if rev == 0:
5007
3addf4531643 revlog: localize some fastpath functions
Matt Mackall <mpm@selenic.com>
parents: 5006
diff changeset
   167
            p = _pack(versionformat, version) + p[4:]
4986
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   168
        return p
58cc017ec7e0 revlog: abstract out index entry packing
Matt Mackall <mpm@selenic.com>
parents: 4985
diff changeset
   169
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1551
diff changeset
   170
class revlog(object):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   171
    """
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   172
    the underlying revision storage object
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   173
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   174
    A revlog consists of two parts, an index and the revision data.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   175
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   176
    The index is a file with a fixed record size containing
6912
b92baef99ebf Fixed docstring typos
Martin Geisler <mg@daimi.au.dk>
parents: 6891
diff changeset
   177
    information on each revision, including its nodeid (hash), the
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   178
    nodeids of its parents, the position and offset of its data within
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   179
    the data file, and the revision it's based on. Finally, each entry
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   180
    contains a linkrev entry that can serve as a pointer to external
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   181
    data.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   182
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   183
    The revision data itself is a linear collection of data chunks.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   184
    Each chunk represents a revision and is usually represented as a
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   185
    delta against the previous chunk. To bound lookup time, runs of
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   186
    deltas are limited to about 2 times the length of the original
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   187
    version data. This makes retrieval of a version proportional to
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   188
    its size, or O(1) relative to the number of revisions.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   189
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   190
    Both pieces of the revlog are written to in an append-only
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   191
    fashion, which means we never need to rewrite a file to insert or
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   192
    remove data, and can use some simple techniques to avoid the need
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   193
    for locking while reading.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   194
    """
14251
258fbccf22f5 revlog: remove the last bits of punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14219
diff changeset
   195
    def __init__(self, opener, indexfile):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   196
        """
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   197
        create a revlog object
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   198
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   199
        opener is a function that abstracts the file opening operation
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   200
        and can be used to implement COW semantics or the like.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   201
        """
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   202
        self.indexfile = indexfile
4257
1b5c38e9d7aa revlog: don't pass datafile as an argument
Matt Mackall <mpm@selenic.com>
parents: 4224
diff changeset
   203
        self.datafile = indexfile[:-2] + ".d"
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   204
        self.opener = opener
4984
b4066fcbd6ba revlog: mark cache private
Matt Mackall <mpm@selenic.com>
parents: 4983
diff changeset
   205
        self._cache = None
19764
e92650e39f1c generaldelta: initialize basecache properly
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
   206
        self._basecache = None
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   207
        self._chunkcache = (0, '')
20180
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   208
        self._chunkcachesize = 65536
23255
76effa770ff9 revlog: add config variable for limiting delta-chain length
Mateusz Kwapich <mitrandir@fb.com>
parents: 23254
diff changeset
   209
        self._maxchainlen = None
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   210
        self.index = []
13258
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   211
        self._pcache = {}
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   212
        self._nodecache = {nullid: nullrev}
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   213
        self._nodepos = None
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   214
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   215
        v = REVLOG_DEFAULT_VERSION
14960
497819817307 revlog: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14549
diff changeset
   216
        opts = getattr(opener, 'options', None)
497819817307 revlog: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14549
diff changeset
   217
        if opts is not None:
497819817307 revlog: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14549
diff changeset
   218
            if 'revlogv1' in opts:
497819817307 revlog: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14549
diff changeset
   219
                if 'generaldelta' in opts:
14333
31a5973fcf96 revlog: get rid of defversion
Sune Foldager <cryo@cyanite.org>
parents: 14325
diff changeset
   220
                    v |= REVLOGGENERALDELTA
31a5973fcf96 revlog: get rid of defversion
Sune Foldager <cryo@cyanite.org>
parents: 14325
diff changeset
   221
            else:
31a5973fcf96 revlog: get rid of defversion
Sune Foldager <cryo@cyanite.org>
parents: 14325
diff changeset
   222
                v = 0
20180
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   223
            if 'chunkcachesize' in opts:
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   224
                self._chunkcachesize = opts['chunkcachesize']
23255
76effa770ff9 revlog: add config variable for limiting delta-chain length
Mateusz Kwapich <mitrandir@fb.com>
parents: 23254
diff changeset
   225
            if 'maxchainlen' in opts:
76effa770ff9 revlog: add config variable for limiting delta-chain length
Mateusz Kwapich <mitrandir@fb.com>
parents: 23254
diff changeset
   226
                self._maxchainlen = opts['maxchainlen']
20180
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   227
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   228
        if self._chunkcachesize <= 0:
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   229
            raise RevlogError(_('revlog chunk cache size %r is not greater '
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   230
                                'than 0') % self._chunkcachesize)
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   231
        elif self._chunkcachesize & (self._chunkcachesize - 1):
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   232
            raise RevlogError(_('revlog chunk cache size %r is not a power '
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   233
                                'of 2') % self._chunkcachesize)
11928
b69899dbad40 revlog: parentdelta flags for revlog index
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11759
diff changeset
   234
8314
57a41c08feab revlog: preread revlog .i file
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
   235
        i = ''
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14333
diff changeset
   236
        self._initempty = True
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   237
        try:
1784
2e0a288ca93e revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1749
diff changeset
   238
            f = self.opener(self.indexfile)
13253
61c9bc3da402 revlog: remove lazy index
Matt Mackall <mpm@selenic.com>
parents: 13239
diff changeset
   239
            i = f.read()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13284
diff changeset
   240
            f.close()
4918
e017d3a82e1d revlog: raise offset/type helpers to global scope
Matt Mackall <mpm@selenic.com>
parents: 4746
diff changeset
   241
            if len(i) > 0:
8314
57a41c08feab revlog: preread revlog .i file
Matt Mackall <mpm@selenic.com>
parents: 8312
diff changeset
   242
                v = struct.unpack(versionformat, i[:4])[0]
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14333
diff changeset
   243
                self._initempty = False
1322
b3d44e9b3092 Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1232
diff changeset
   244
        except IOError, inst:
b3d44e9b3092 Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1232
diff changeset
   245
            if inst.errno != errno.ENOENT:
b3d44e9b3092 Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1232
diff changeset
   246
                raise
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   247
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   248
        self.version = v
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   249
        self._inline = v & REVLOGNGINLINEDATA
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
   250
        self._generaldelta = v & REVLOGGENERALDELTA
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   251
        flags = v & ~0xFFFF
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
   252
        fmt = v & 0xFFFF
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   253
        if fmt == REVLOGV0 and flags:
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   254
            raise RevlogError(_("index %s unknown flags %#04x for format v0")
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   255
                              % (self.indexfile, flags >> 16))
11746
46ac30b17978 revlog: add shallow header flag
Vishakh H <vsh426@gmail.com>
parents: 11745
diff changeset
   256
        elif fmt == REVLOGNG and flags & ~REVLOGNG_FLAGS:
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   257
            raise RevlogError(_("index %s unknown flags %#04x for revlogng")
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   258
                              % (self.indexfile, flags >> 16))
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   259
        elif fmt > REVLOGNG:
3743
3a099154b110 Make revlog error slightly less scary
Matt Mackall <mpm@selenic.com>
parents: 3683
diff changeset
   260
            raise RevlogError(_("index %s unknown format %d")
3680
69cf255a55a1 Indentation cleanups for 2956948b81f3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3679
diff changeset
   261
                              % (self.indexfile, fmt))
4985
e6525e459157 revlog: simplify revlog.__init__
Matt Mackall <mpm@selenic.com>
parents: 4984
diff changeset
   262
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   263
        self._io = revlogio()
4971
3e6dae278c99 revlog: regroup parsing code
Matt Mackall <mpm@selenic.com>
parents: 4920
diff changeset
   264
        if self.version == REVLOGV0:
4972
8d0cf46e0dc6 revlog: add revlogio interface
Matt Mackall <mpm@selenic.com>
parents: 4971
diff changeset
   265
            self._io = revlogoldio()
13265
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   266
        try:
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   267
            d = self._io.parseindex(i, self._inline)
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   268
        except (ValueError, IndexError):
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   269
            raise RevlogError(_("index %s is corrupted") % (self.indexfile))
13268
fff12b3d953a revlog: explicit test and explicit variable names
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13267
diff changeset
   270
        self.index, nodemap, self._chunkcache = d
fff12b3d953a revlog: explicit test and explicit variable names
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13267
diff changeset
   271
        if nodemap is not None:
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   272
            self.nodemap = self._nodecache = nodemap
13265
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   273
        if not self._chunkcache:
04b302ce2781 revlog: always add the magic nullid/nullrev entry in parseindex
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13264
diff changeset
   274
            self._chunkclear()
23306
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   275
        # revnum -> (chain-length, sum-delta-length)
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   276
        self._chaininfocache = {}
116
e484cd5ec282 Only use lazy indexing for big indices and avoid the overhead of the
mpm@selenic.com
parents: 115
diff changeset
   277
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   278
    def tip(self):
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   279
        return self.node(len(self.index) - 2)
24030
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23857
diff changeset
   280
    def __contains__(self, rev):
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23857
diff changeset
   281
        return 0 <= rev < len(self)
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   282
    def __len__(self):
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   283
        return len(self.index) - 1
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   284
    def __iter__(self):
17951
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17674
diff changeset
   285
        return iter(xrange(len(self)))
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   286
    def revs(self, start=0, stop=None):
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   287
        """iterate over all rev in this revlog (from start to stop)"""
17975
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   288
        step = 1
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   289
        if stop is not None:
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   290
            if start > stop:
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   291
                step = -1
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   292
            stop += step
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   293
        else:
17975
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   294
            stop = len(self)
c56b5b65430d revlog: allow reverse iteration with revlog.revs
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17972
diff changeset
   295
        return xrange(start, stop, step)
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   296
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   297
    @util.propertycache
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   298
    def nodemap(self):
14064
e4bfb9c337f3 remove unused imports and variables
Alexander Solovyov <alexander@solovyov.net>
parents: 13831
diff changeset
   299
        self.rev(self.node(0))
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   300
        return self._nodecache
13259
3b616dfa4b17 revlog: do revlog node->rev mapping by scanning
Matt Mackall <mpm@selenic.com>
parents: 13258
diff changeset
   301
16374
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   302
    def hasnode(self, node):
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   303
        try:
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   304
            self.rev(node)
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   305
            return True
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   306
        except KeyError:
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   307
            return False
29c2ff719715 revlog: add hasnode helper method
Matt Mackall <mpm@selenic.com>
parents: 15890
diff changeset
   308
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   309
    def clearcaches(self):
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   310
        try:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   311
            self._nodecache.clearcaches()
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   312
        except AttributeError:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   313
            self._nodecache = {nullid: nullrev}
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   314
            self._nodepos = None
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   315
13259
3b616dfa4b17 revlog: do revlog node->rev mapping by scanning
Matt Mackall <mpm@selenic.com>
parents: 13258
diff changeset
   316
    def rev(self, node):
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   317
        try:
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   318
            return self._nodecache[node]
22282
4092d12ba18a repoview: fix 0L with pack/unpack for 2.4
Matt Mackall <mpm@selenic.com>
parents: 21752
diff changeset
   319
        except TypeError:
4092d12ba18a repoview: fix 0L with pack/unpack for 2.4
Matt Mackall <mpm@selenic.com>
parents: 21752
diff changeset
   320
            raise
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   321
        except RevlogError:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   322
            # parsers.c radix tree lookup failed
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   323
            raise LookupError(node, self.indexfile, _('no node'))
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   324
        except KeyError:
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16375
diff changeset
   325
            # pure python cache lookup failed
13275
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   326
            n = self._nodecache
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   327
            i = self.index
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   328
            p = self._nodepos
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   329
            if p is None:
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   330
                p = len(i) - 2
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   331
            for r in xrange(p, -1, -1):
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   332
                v = i[r][7]
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   333
                n[v] = r
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   334
                if v == node:
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   335
                    self._nodepos = r - 1
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   336
                    return r
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   337
            raise LookupError(node, self.indexfile, _('no node'))
68da048b4c88 revlog: incrementally build node cache with linear searches
Matt Mackall <mpm@selenic.com>
parents: 13268
diff changeset
   338
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   339
    def node(self, rev):
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   340
        return self.index[rev][7]
7361
9fe97eea5510 linkrev: take a revision number rather than a hash
Matt Mackall <mpm@selenic.com>
parents: 7233
diff changeset
   341
    def linkrev(self, rev):
9fe97eea5510 linkrev: take a revision number rather than a hash
Matt Mackall <mpm@selenic.com>
parents: 7233
diff changeset
   342
        return self.index[rev][4]
2
ecf3fd948051 Handle nullid better for ancestor
mpm@selenic.com
parents: 0
diff changeset
   343
    def parents(self, node):
7363
9d28ff207030 revlog: speed up parents()
Matt Mackall <mpm@selenic.com>
parents: 7362
diff changeset
   344
        i = self.index
9d28ff207030 revlog: speed up parents()
Matt Mackall <mpm@selenic.com>
parents: 7362
diff changeset
   345
        d = i[self.rev(node)]
9d28ff207030 revlog: speed up parents()
Matt Mackall <mpm@selenic.com>
parents: 7362
diff changeset
   346
        return i[d[5]][7], i[d[6]][7] # map revisions to nodes inline
2489
568e58eed096 Add revlog.parentrevs function.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2354
diff changeset
   347
    def parentrevs(self, rev):
4979
06abdaf78788 revlog: add a magic null revision to our index
Matt Mackall <mpm@selenic.com>
parents: 4978
diff changeset
   348
        return self.index[rev][5:7]
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
   349
    def start(self, rev):
5006
c2febf5420e9 revlog: minor chunk speed-up
Matt Mackall <mpm@selenic.com>
parents: 5005
diff changeset
   350
        return int(self.index[rev][0] >> 16)
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   351
    def end(self, rev):
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   352
        return self.start(rev) + self.length(rev)
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   353
    def length(self, rev):
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   354
        return self.index[rev][1]
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   355
    def chainbase(self, rev):
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   356
        index = self.index
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   357
        base = index[rev][3]
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   358
        while base != rev:
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   359
            rev = base
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   360
            base = index[rev][3]
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
   361
        return base
23254
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   362
    def chainlen(self, rev):
23286
40e0067899d4 revlog: compute length of compressed deltas along with chain length
Siddharth Agarwal <sid0@fb.com>
parents: 23285
diff changeset
   363
        return self._chaininfo(rev)[0]
23306
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   364
23286
40e0067899d4 revlog: compute length of compressed deltas along with chain length
Siddharth Agarwal <sid0@fb.com>
parents: 23285
diff changeset
   365
    def _chaininfo(self, rev):
23306
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   366
        chaininfocache = self._chaininfocache
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   367
        if rev in chaininfocache:
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   368
            return chaininfocache[rev]
23254
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   369
        index = self.index
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   370
        generaldelta = self._generaldelta
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   371
        iterrev = rev
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   372
        e = index[iterrev]
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   373
        clen = 0
23286
40e0067899d4 revlog: compute length of compressed deltas along with chain length
Siddharth Agarwal <sid0@fb.com>
parents: 23285
diff changeset
   374
        compresseddeltalen = 0
23254
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   375
        while iterrev != e[3]:
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   376
            clen += 1
23286
40e0067899d4 revlog: compute length of compressed deltas along with chain length
Siddharth Agarwal <sid0@fb.com>
parents: 23285
diff changeset
   377
            compresseddeltalen += e[1]
23254
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   378
            if generaldelta:
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   379
                iterrev = e[3]
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   380
            else:
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   381
                iterrev -= 1
23306
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   382
            if iterrev in chaininfocache:
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   383
                t = chaininfocache[iterrev]
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   384
                clen += t[0]
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   385
                compresseddeltalen += t[1]
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   386
                break
23254
d23834b871ac debugrevlog: fix computing chain length in debugrevlog -d
Mateusz Kwapich <mitrandir@fb.com>
parents: 22934
diff changeset
   387
            e = index[iterrev]
23306
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   388
        else:
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   389
            # Add text length of base since decompressing that also takes
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   390
            # work. For cache hits the length is already included.
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   391
            compresseddeltalen += e[1]
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   392
        r = (clen, compresseddeltalen)
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   393
        chaininfocache[rev] = r
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   394
        return r
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
   395
11693
ff33f937a7da revlog: add a flags method that returns revision flags
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11670
diff changeset
   396
    def flags(self, rev):
ff33f937a7da revlog: add a flags method that returns revision flags
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11670
diff changeset
   397
        return self.index[rev][0] & 0xFFFF
12024
56a7721ee3ec revlog: add rawsize(), identical to size() but not subclassed by filelog
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12023
diff changeset
   398
    def rawsize(self, rev):
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   399
        """return the length of the uncompressed text for a given revision"""
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
   400
        l = self.index[rev][2]
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   401
        if l >= 0:
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   402
            return l
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   403
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   404
        t = self.revision(self.node(rev))
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   405
        return len(t)
12024
56a7721ee3ec revlog: add rawsize(), identical to size() but not subclassed by filelog
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12023
diff changeset
   406
    size = rawsize
2078
441ea218414e Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents: 2077
diff changeset
   407
18081
f88c60e740a1 revlog.ancestors: add support for including revs
Siddharth Agarwal <sid0@fb.com>
parents: 17975
diff changeset
   408
    def ancestors(self, revs, stoprev=0, inclusive=False):
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   409
        """Generate the ancestors of 'revs' in reverse topological order.
16868
eb88ed4269c5 revlog: add optional stoprev arg to revlog.ancestors()
Joshua Redstone <joshua.redstone@fb.com>
parents: 16867
diff changeset
   410
        Does not generate revs lower than stoprev.
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   411
18090
9abc55ef85b5 revlog: move ancestor generation out to a new class
Siddharth Agarwal <sid0@fb.com>
parents: 18083
diff changeset
   412
        See the documentation for ancestor.lazyancestors for more details."""
18081
f88c60e740a1 revlog.ancestors: add support for including revs
Siddharth Agarwal <sid0@fb.com>
parents: 17975
diff changeset
   413
23328
3a7d9c0c57a5 ancestor.lazyancestors: take parentrevs function rather than changelog
Siddharth Agarwal <sid0@fb.com>
parents: 23306
diff changeset
   414
        return ancestor.lazyancestors(self.parentrevs, revs, stoprev=stoprev,
18090
9abc55ef85b5 revlog: move ancestor generation out to a new class
Siddharth Agarwal <sid0@fb.com>
parents: 18083
diff changeset
   415
                                      inclusive=inclusive)
6872
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   416
16867
1093ad1e8903 revlog: descendants(*revs) becomes descendants(revs) (API)
Bryan O'Sullivan <bryano@fb.com>
parents: 16866
diff changeset
   417
    def descendants(self, revs):
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   418
        """Generate the descendants of 'revs' in revision order.
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   419
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   420
        Yield a sequence of revision numbers starting with a child of
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   421
        some rev in revs, i.e., each revision is *not* considered a
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   422
        descendant of itself.  Results are ordered by revision number (a
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   423
        topological sort)."""
12950
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   424
        first = min(revs)
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   425
        if first == nullrev:
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   426
            for i in self:
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   427
                yield i
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   428
            return
2405b4a5964a revlog: fix descendants() if nullrev is in revs
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12949
diff changeset
   429
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8073
diff changeset
   430
        seen = set(revs)
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   431
        for i in self.revs(start=first + 1):
6872
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   432
            for x in self.parentrevs(i):
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   433
                if x != nullrev and x in seen:
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   434
                    seen.add(i)
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   435
                    yield i
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   436
                    break
c7cc40fd74f6 Add ancestors and descendants to revlog
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 6750
diff changeset
   437
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   438
    def findcommonmissing(self, common=None, heads=None):
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   439
        """Return a tuple of the ancestors of common and the ancestors of heads
15835
fa15869bf95c revlog: improve docstring for findcommonmissing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15827
diff changeset
   440
        that are not ancestors of common. In revset terminology, we return the
fa15869bf95c revlog: improve docstring for findcommonmissing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15827
diff changeset
   441
        tuple:
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   442
15835
fa15869bf95c revlog: improve docstring for findcommonmissing
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15827
diff changeset
   443
          ::common, (::heads) - (::common)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   444
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   445
        The list is sorted by revision number, meaning it is
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   446
        topologically sorted.
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   447
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   448
        'heads' and 'common' are both lists of node IDs.  If heads is
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   449
        not supplied, uses all of the revlog's heads.  If common is not
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   450
        supplied, uses nullid."""
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   451
        if common is None:
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   452
            common = [nullid]
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   453
        if heads is None:
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   454
            heads = self.heads()
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   455
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   456
        common = [self.rev(n) for n in common]
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   457
        heads = [self.rev(n) for n in heads]
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   458
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   459
        # we want the ancestors, but inclusive
20073
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   460
        class lazyset(object):
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   461
            def __init__(self, lazyvalues):
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   462
                self.addedvalues = set()
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   463
                self.lazyvalues = lazyvalues
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   464
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   465
            def __contains__(self, value):
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   466
                return value in self.addedvalues or value in self.lazyvalues
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   467
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   468
            def __iter__(self):
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   469
                added = self.addedvalues
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   470
                for r in added:
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   471
                    yield r
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   472
                for r in self.lazyvalues:
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   473
                    if not r in added:
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   474
                        yield r
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   475
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   476
            def add(self, value):
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   477
                self.addedvalues.add(value)
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   478
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   479
            def update(self, values):
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   480
                self.addedvalues.update(values)
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   481
eeba4eaf0716 revlog: return lazy set from findcommonmissing
Durham Goode <durham@fb.com>
parents: 19776
diff changeset
   482
        has = lazyset(self.ancestors(common))
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   483
        has.add(nullrev)
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   484
        has.update(common)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   485
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   486
        # take all ancestors from heads that aren't in has
8453
d1ca637b0773 revlog.missing(): use sets instead of a dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8391
diff changeset
   487
        missing = set()
16834
cafd8a8fb713 util: subclass deque for Python 2.4 backwards compatibility
Bryan O'Sullivan <bryano@fb.com>
parents: 16803
diff changeset
   488
        visit = util.deque(r for r in heads if r not in has)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   489
        while visit:
16803
107a3270a24a cleanup: use the deque type where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
   490
            r = visit.popleft()
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   491
            if r in missing:
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   492
                continue
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   493
            else:
8453
d1ca637b0773 revlog.missing(): use sets instead of a dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8391
diff changeset
   494
                missing.add(r)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   495
                for p in self.parentrevs(r):
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   496
                    if p not in has:
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   497
                        visit.append(p)
8453
d1ca637b0773 revlog.missing(): use sets instead of a dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8391
diff changeset
   498
        missing = list(missing)
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   499
        missing.sort()
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   500
        return has, [self.node(r) for r in missing]
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   501
23337
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   502
    def incrementalmissingrevs(self, common=None):
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   503
        """Return an object that can be used to incrementally compute the
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   504
        revision numbers of the ancestors of arbitrary sets that are not
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   505
        ancestors of common. This is an ancestor.incrementalmissingancestors
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   506
        object.
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   507
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   508
        'common' is a list of revision numbers. If common is not supplied, uses
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   509
        nullrev.
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   510
        """
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   511
        if common is None:
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   512
            common = [nullrev]
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   513
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   514
        return ancestor.incrementalmissingancestors(self.parentrevs, common)
3a8a763f4197 revlog: add a method to get missing revs incrementally
Siddharth Agarwal <sid0@fb.com>
parents: 23328
diff changeset
   515
17972
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   516
    def findmissingrevs(self, common=None, heads=None):
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   517
        """Return the revision numbers of the ancestors of heads that
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   518
        are not ancestors of common.
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   519
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   520
        More specifically, return a list of revision numbers corresponding to
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   521
        nodes N such that every N satisfies the following constraints:
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   522
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   523
          1. N is an ancestor of some node in 'heads'
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   524
          2. N is not an ancestor of any node in 'common'
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   525
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   526
        The list is sorted by revision number, meaning it is
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   527
        topologically sorted.
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   528
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   529
        'heads' and 'common' are both lists of revision numbers.  If heads is
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   530
        not supplied, uses all of the revlog's heads.  If common is not
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   531
        supplied, uses nullid."""
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   532
        if common is None:
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   533
            common = [nullrev]
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   534
        if heads is None:
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   535
            heads = self.headrevs()
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   536
23338
d8f5b2f50f41 revlog: switch findmissing* methods to incrementalmissingrevs
Siddharth Agarwal <sid0@fb.com>
parents: 23337
diff changeset
   537
        inc = self.incrementalmissingrevs(common=common)
d8f5b2f50f41 revlog: switch findmissing* methods to incrementalmissingrevs
Siddharth Agarwal <sid0@fb.com>
parents: 23337
diff changeset
   538
        return inc.missingancestors(heads)
17972
7ef00d09ef35 revlog: add rev-specific variant of findmissing
Siddharth Agarwal <sid0@fb.com>
parents: 17971
diff changeset
   539
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   540
    def findmissing(self, common=None, heads=None):
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   541
        """Return the ancestors of heads that are not ancestors of common.
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   542
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   543
        More specifically, return a list of nodes N such that every N
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   544
        satisfies the following constraints:
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   545
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   546
          1. N is an ancestor of some node in 'heads'
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   547
          2. N is not an ancestor of any node in 'common'
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   548
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   549
        The list is sorted by revision number, meaning it is
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   550
        topologically sorted.
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   551
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   552
        'heads' and 'common' are both lists of node IDs.  If heads is
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   553
        not supplied, uses all of the revlog's heads.  If common is not
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13400
diff changeset
   554
        supplied, uses nullid."""
17971
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   555
        if common is None:
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   556
            common = [nullid]
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   557
        if heads is None:
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   558
            heads = self.heads()
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   559
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   560
        common = [self.rev(n) for n in common]
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   561
        heads = [self.rev(n) for n in heads]
e1b9a78a7aed revlog: switch findmissing to use ancestor.missingancestors
Siddharth Agarwal <sid0@fb.com>
parents: 17951
diff changeset
   562
23338
d8f5b2f50f41 revlog: switch findmissing* methods to incrementalmissingrevs
Siddharth Agarwal <sid0@fb.com>
parents: 23337
diff changeset
   563
        inc = self.incrementalmissingrevs(common=common)
d8f5b2f50f41 revlog: switch findmissing* methods to incrementalmissingrevs
Siddharth Agarwal <sid0@fb.com>
parents: 23337
diff changeset
   564
        return [self.node(r) for r in inc.missingancestors(heads)]
7233
9f0e52e1df77 fix pull racing with push/commit (issue1320)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7109
diff changeset
   565
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   566
    def nodesbetween(self, roots=None, heads=None):
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   567
        """Return a topological path from 'roots' to 'heads'.
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   568
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   569
        Return a tuple (nodes, outroots, outheads) where 'nodes' is a
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   570
        topologically sorted list of all nodes N that satisfy both of
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   571
        these constraints:
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   572
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   573
          1. N is a descendant of some node in 'roots'
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   574
          2. N is an ancestor of some node in 'heads'
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   575
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   576
        Every node is considered to be both a descendant and an ancestor
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   577
        of itself, so every reachable node in 'roots' and 'heads' will be
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   578
        included in 'nodes'.
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   579
10047
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   580
        'outroots' is the list of reachable nodes in 'roots', i.e., the
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   581
        subset of 'roots' that is returned in 'nodes'.  Likewise,
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   582
        'outheads' is the subset of 'heads' that is also in 'nodes'.
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   583
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   584
        'roots' and 'heads' are both lists of node IDs.  If 'roots' is
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   585
        unspecified, uses nullid as the only root.  If 'heads' is
27267b1f68b4 revlog: rewrite several method docstrings
Greg Ward <greg-hg@gerg.ca>
parents: 9679
diff changeset
   586
        unspecified, uses list of all of the revlog's heads."""
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   587
        nonodes = ([], [], [])
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   588
        if roots is not None:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   589
            roots = list(roots)
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   590
            if not roots:
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   591
                return nonodes
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   592
            lowestrev = min([self.rev(n) for n in roots])
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   593
        else:
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   594
            roots = [nullid] # Everybody's a descendant of nullid
3578
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3508
diff changeset
   595
            lowestrev = nullrev
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3508
diff changeset
   596
        if (lowestrev == nullrev) and (heads is None):
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   597
            # We want _all_ the nodes!
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   598
            return ([self.node(r) for r in self], [nullid], list(self.heads()))
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   599
        if heads is None:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   600
            # All nodes are ancestors, so the latest ancestor is the last
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   601
            # node.
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   602
            highestrev = len(self) - 1
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   603
            # Set ancestors to None to signal that every node is an ancestor.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   604
            ancestors = None
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   605
            # Set heads to an empty dictionary for later discovery of heads
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   606
            heads = {}
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   607
        else:
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   608
            heads = list(heads)
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   609
            if not heads:
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   610
                return nonodes
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   611
            ancestors = set()
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   612
            # Turn heads into a dictionary so we can remove 'fake' heads.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   613
            # Also, later we will be using it to filter out the heads we can't
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   614
            # find from roots.
14219
c33427080671 revlog: use real Booleans instead of 0/1 in nodesbetween
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   615
            heads = dict.fromkeys(heads, False)
3360
ef8307585b41 nodesbetween: fix a bug with duplicate heads
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3335
diff changeset
   616
            # Start at the top and keep marking parents until we're done.
8163
62d7287fe6b0 rebase, revlog: use set(x) instead of set(x.keys())
Martin Geisler <mg@lazybytes.net>
parents: 8153
diff changeset
   617
            nodestotag = set(heads)
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   618
            # Remember where the top was so we can use it as a limit later.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   619
            highestrev = max([self.rev(n) for n in nodestotag])
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   620
            while nodestotag:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   621
                # grab a node to tag
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   622
                n = nodestotag.pop()
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   623
                # Never tag nullid
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   624
                if n == nullid:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   625
                    continue
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   626
                # A node's revision number represents its place in a
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   627
                # topologically sorted list of nodes.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   628
                r = self.rev(n)
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   629
                if r >= lowestrev:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   630
                    if n not in ancestors:
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   631
                        # If we are possibly a descendant of one of the roots
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   632
                        # and we haven't already been marked as an ancestor
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   633
                        ancestors.add(n) # Mark as ancestor
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   634
                        # Add non-nullid parents to list of nodes to tag.
8153
616f20e1004a revlog: let nodestotag be a set instead of a list
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
   635
                        nodestotag.update([p for p in self.parents(n) if
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   636
                                           p != nullid])
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   637
                    elif n in heads: # We've seen it before, is it a fake head?
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   638
                        # So it is, real heads should not be the ancestors of
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   639
                        # any other heads.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   640
                        heads.pop(n)
1459
106fdec8e1fb Fix small bug in nodesbetween if heads is [nullid].
Eric Hopper <hopper@omnifarious.org>
parents: 1458
diff changeset
   641
            if not ancestors:
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   642
                return nonodes
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   643
            # Now that we have our set of ancestors, we want to remove any
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   644
            # roots that are not ancestors.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   645
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   646
            # If one of the roots was nullid, everything is included anyway.
3578
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3508
diff changeset
   647
            if lowestrev > nullrev:
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   648
                # But, since we weren't, let's recompute the lowest rev to not
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   649
                # include roots that aren't ancestors.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   650
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   651
                # Filter out roots that aren't ancestors of heads
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   652
                roots = [n for n in roots if n in ancestors]
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   653
                # Recompute the lowest revision
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   654
                if roots:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   655
                    lowestrev = min([self.rev(n) for n in roots])
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   656
                else:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   657
                    # No more roots?  Return empty list
1463
26e73acc0cdf Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents: 1459
diff changeset
   658
                    return nonodes
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   659
            else:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   660
                # We are descending from nullid, and don't need to care about
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   661
                # any other roots.
3578
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3508
diff changeset
   662
                lowestrev = nullrev
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   663
                roots = [nullid]
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   664
        # Transform our roots list into a set.
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   665
        descendants = set(roots)
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   666
        # Also, keep the original roots so we can filter out roots that aren't
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   667
        # 'real' roots (i.e. are descended from other roots).
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   668
        roots = descendants.copy()
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   669
        # Our topologically sorted list of output nodes.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   670
        orderedout = []
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   671
        # Don't start at nullid since we don't want nullid in our output list,
17483
fe3b26048140 spelling: descendants
timeless@mozdev.org
parents: 17150
diff changeset
   672
        # and if nullid shows up in descendants, empty parents will look like
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   673
        # they're descendants.
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   674
        for r in self.revs(start=max(lowestrev, 0), stop=highestrev + 1):
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   675
            n = self.node(r)
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   676
            isdescendant = False
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   677
            if lowestrev == nullrev:  # Everybody is a descendant of nullid
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   678
                isdescendant = True
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   679
            elif n in descendants:
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   680
                # n is already a descendant
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   681
                isdescendant = True
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   682
                # This check only needs to be done here because all the roots
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   683
                # will start being marked is descendants before the loop.
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   684
                if n in roots:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   685
                    # If n was a root, check if it's a 'real' root.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   686
                    p = tuple(self.parents(n))
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   687
                    # If any of its parents are descendants, it's not a root.
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   688
                    if (p[0] in descendants) or (p[1] in descendants):
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   689
                        roots.remove(n)
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   690
            else:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   691
                p = tuple(self.parents(n))
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   692
                # A node is a descendant if either of its parents are
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   693
                # descendants.  (We seeded the dependents list with the roots
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   694
                # up there, remember?)
14549
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   695
                if (p[0] in descendants) or (p[1] in descendants):
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   696
                    descendants.add(n)
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   697
                    isdescendant = True
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   698
            if isdescendant and ((ancestors is None) or (n in ancestors)):
48ec0763afbb check-code: catch misspellings of descendant
Matt Mackall <mpm@selenic.com>
parents: 14523
diff changeset
   699
                # Only include nodes that are both descendants and ancestors.
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   700
                orderedout.append(n)
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   701
                if (ancestors is not None) and (n in heads):
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   702
                    # We're trying to figure out which heads are reachable
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   703
                    # from roots.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   704
                    # Mark this head as having been reached
14219
c33427080671 revlog: use real Booleans instead of 0/1 in nodesbetween
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   705
                    heads[n] = True
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   706
                elif ancestors is None:
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   707
                    # Otherwise, we're trying to discover the heads.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   708
                    # Assume this is a head because if it isn't, the next step
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   709
                    # will eventually remove it.
14219
c33427080671 revlog: use real Booleans instead of 0/1 in nodesbetween
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   710
                    heads[n] = True
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   711
                    # But, obviously its parents aren't.
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   712
                    for p in self.parents(n):
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   713
                        heads.pop(p, None)
14219
c33427080671 revlog: use real Booleans instead of 0/1 in nodesbetween
Martin Geisler <mg@aragost.com>
parents: 14208
diff changeset
   714
        heads = [n for n, flag in heads.iteritems() if flag]
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   715
        roots = list(roots)
1457
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   716
        assert orderedout
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   717
        assert roots
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   718
        assert heads
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   719
        return (orderedout, roots, heads)
518da3c3b6ce This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents: 1351
diff changeset
   720
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   721
    def headrevs(self):
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16762
diff changeset
   722
        try:
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16762
diff changeset
   723
            return self.index.headrevs()
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16762
diff changeset
   724
        except AttributeError:
17674
e69274f8d444 clfilter: split `revlog.headrevs` C call from python code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17673
diff changeset
   725
            return self._headrevs()
e69274f8d444 clfilter: split `revlog.headrevs` C call from python code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17673
diff changeset
   726
e69274f8d444 clfilter: split `revlog.headrevs` C call from python code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17673
diff changeset
   727
    def _headrevs(self):
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   728
        count = len(self)
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   729
        if not count:
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   730
            return [nullrev]
17673
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   731
        # we won't iter over filtered rev so nobody is a head at start
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   732
        ishead = [0] * (count + 1)
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   733
        index = self.index
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   734
        for r in self:
17673
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   735
            ishead[r] = 1  # I may be an head
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   736
            e = index[r]
17673
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   737
            ishead[e[5]] = ishead[e[6]] = 0  # my parent are not
d686c6876ef6 clfilter: handle non contiguous iteration in `revlov.headrevs`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17672
diff changeset
   738
        return [r for r, val in enumerate(ishead) if val]
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   739
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   740
    def heads(self, start=None, stop=None):
1550
ccb9b62de892 add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1535
diff changeset
   741
        """return the list of all nodes that have no children
1551
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   742
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   743
        if start is specified, only heads that are descendants of
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   744
        start will be returned
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   745
        if stop is specified, it will consider all the revs from stop
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   746
        as if they had no children
1551
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   747
        """
4991
9c8c42bcf17a revlog: implement a fast path for heads
Matt Mackall <mpm@selenic.com>
parents: 4990
diff changeset
   748
        if start is None and stop is None:
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   749
            if not len(self):
4991
9c8c42bcf17a revlog: implement a fast path for heads
Matt Mackall <mpm@selenic.com>
parents: 4990
diff changeset
   750
                return [nullid]
14164
cb98fed52495 discovery: add new set-based discovery
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14144
diff changeset
   751
            return [self.node(r) for r in self.headrevs()]
4991
9c8c42bcf17a revlog: implement a fast path for heads
Matt Mackall <mpm@selenic.com>
parents: 4990
diff changeset
   752
1551
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   753
        if start is None:
e793cbc8be00 Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1550
diff changeset
   754
            start = nullid
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   755
        if stop is None:
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   756
            stop = []
8152
08e1baf924ca replace set-like dictionaries with real sets
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   757
        stoprevs = set([self.rev(n) for n in stop])
1550
ccb9b62de892 add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1535
diff changeset
   758
        startrev = self.rev(start)
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   759
        reachable = set((startrev,))
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   760
        heads = set((startrev,))
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   761
2490
6ff82ec1f4b8 Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2489
diff changeset
   762
        parentrevs = self.parentrevs
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   763
        for r in self.revs(start=startrev + 1):
2490
6ff82ec1f4b8 Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2489
diff changeset
   764
            for p in parentrevs(r):
6ff82ec1f4b8 Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2489
diff changeset
   765
                if p in reachable:
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   766
                    if r not in stoprevs:
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   767
                        reachable.add(r)
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   768
                    heads.add(r)
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   769
                if p in heads and p not in stoprevs:
8464
7af92e70bb25 revlog: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8453
diff changeset
   770
                    heads.remove(p)
3923
27230c29bfec fix calculation of new heads added during push with -r
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3755
diff changeset
   771
2490
6ff82ec1f4b8 Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2489
diff changeset
   772
        return [self.node(r) for r in heads]
370
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   773
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   774
    def children(self, node):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
   775
        """find the children of a given node"""
370
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   776
        c = []
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   777
        p = self.rev(node)
17672
474047947b8f clfilter: make the revlog class responsible of all its iteration
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17537
diff changeset
   778
        for r in self.revs(start=p + 1):
4746
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   779
            prevs = [pr for pr in self.parentrevs(r) if pr != nullrev]
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   780
            if prevs:
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   781
                for pr in prevs:
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   782
                    if pr == p:
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   783
                        c.append(self.node(r))
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   784
            elif p == nullrev:
62c56d8f368b Fix revlog.children so the real children of the null revision can be calculated.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4635
diff changeset
   785
                c.append(self.node(r))
370
c90385d82aec revlog: add a children function
mpm@selenic.com
parents: 330
diff changeset
   786
        return c
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 484
diff changeset
   787
10897
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   788
    def descendant(self, start, end):
12949
6878eaa5a40d revlog: if start is nullrev, end is always a descendant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12890
diff changeset
   789
        if start == nullrev:
6878eaa5a40d revlog: if start is nullrev, end is always a descendant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12890
diff changeset
   790
            return True
16867
1093ad1e8903 revlog: descendants(*revs) becomes descendants(revs) (API)
Bryan O'Sullivan <bryano@fb.com>
parents: 16866
diff changeset
   791
        for i in self.descendants([start]):
10897
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   792
            if i == end:
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   793
                return True
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   794
            elif i > end:
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   795
                break
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   796
        return False
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   797
21104
40ace21cb3a1 revlog: introduce commonancestorsheads method
Mads Kiilerich <madski@unity3d.com>
parents: 20965
diff changeset
   798
    def commonancestorsheads(self, a, b):
40ace21cb3a1 revlog: introduce commonancestorsheads method
Mads Kiilerich <madski@unity3d.com>
parents: 20965
diff changeset
   799
        """calculate all the heads of the common ancestors of nodes a and b"""
40ace21cb3a1 revlog: introduce commonancestorsheads method
Mads Kiilerich <madski@unity3d.com>
parents: 20965
diff changeset
   800
        a, b = self.rev(a), self.rev(b)
40ace21cb3a1 revlog: introduce commonancestorsheads method
Mads Kiilerich <madski@unity3d.com>
parents: 20965
diff changeset
   801
        try:
40ace21cb3a1 revlog: introduce commonancestorsheads method
Mads Kiilerich <madski@unity3d.com>
parents: 20965
diff changeset
   802
            ancs = self.index.commonancestorsheads(a, b)
40ace21cb3a1 revlog: introduce commonancestorsheads method
Mads Kiilerich <madski@unity3d.com>
parents: 20965
diff changeset
   803
        except (AttributeError, OverflowError): # C implementation failed
40ace21cb3a1 revlog: introduce commonancestorsheads method
Mads Kiilerich <madski@unity3d.com>
parents: 20965
diff changeset
   804
            ancs = ancestor.commonancestorsheads(self.parentrevs, a, b)
40ace21cb3a1 revlog: introduce commonancestorsheads method
Mads Kiilerich <madski@unity3d.com>
parents: 20965
diff changeset
   805
        return map(self.node, ancs)
40ace21cb3a1 revlog: introduce commonancestorsheads method
Mads Kiilerich <madski@unity3d.com>
parents: 20965
diff changeset
   806
22381
392ae5cb8d62 revlog: introduce isancestor method for efficiently determining node lineage
Mads Kiilerich <madski@unity3d.com>
parents: 22282
diff changeset
   807
    def isancestor(self, a, b):
392ae5cb8d62 revlog: introduce isancestor method for efficiently determining node lineage
Mads Kiilerich <madski@unity3d.com>
parents: 22282
diff changeset
   808
        """return True if node a is an ancestor of node b
392ae5cb8d62 revlog: introduce isancestor method for efficiently determining node lineage
Mads Kiilerich <madski@unity3d.com>
parents: 22282
diff changeset
   809
392ae5cb8d62 revlog: introduce isancestor method for efficiently determining node lineage
Mads Kiilerich <madski@unity3d.com>
parents: 22282
diff changeset
   810
        The implementation of this is trivial but the use of
392ae5cb8d62 revlog: introduce isancestor method for efficiently determining node lineage
Mads Kiilerich <madski@unity3d.com>
parents: 22282
diff changeset
   811
        commonancestorsheads is not."""
392ae5cb8d62 revlog: introduce isancestor method for efficiently determining node lineage
Mads Kiilerich <madski@unity3d.com>
parents: 22282
diff changeset
   812
        return a in self.commonancestorsheads(a, b)
392ae5cb8d62 revlog: introduce isancestor method for efficiently determining node lineage
Mads Kiilerich <madski@unity3d.com>
parents: 22282
diff changeset
   813
21107
4a6c8b6b10d3 revlog: backout 514d32de6646 - commonancestors
Mads Kiilerich <madski@unity3d.com>
parents: 21104
diff changeset
   814
    def ancestor(self, a, b):
22389
94f77624dbb5 comments: describe ancestor consistently - avoid 'least common ancestor'
Mads Kiilerich <madski@unity3d.com>
parents: 22381
diff changeset
   815
        """calculate the "best" common ancestor of nodes a and b"""
21107
4a6c8b6b10d3 revlog: backout 514d32de6646 - commonancestors
Mads Kiilerich <madski@unity3d.com>
parents: 21104
diff changeset
   816
10897
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   817
        a, b = self.rev(a), self.rev(b)
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18987
diff changeset
   818
        try:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18987
diff changeset
   819
            ancs = self.index.ancestors(a, b)
21107
4a6c8b6b10d3 revlog: backout 514d32de6646 - commonancestors
Mads Kiilerich <madski@unity3d.com>
parents: 21104
diff changeset
   820
        except (AttributeError, OverflowError):
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18987
diff changeset
   821
            ancs = ancestor.ancestors(self.parentrevs, a, b)
18987
3605d4e7e618 revlog: choose a consistent ancestor when there's a tie
Bryan O'Sullivan <bryano@fb.com>
parents: 18986
diff changeset
   822
        if ancs:
3605d4e7e618 revlog: choose a consistent ancestor when there's a tie
Bryan O'Sullivan <bryano@fb.com>
parents: 18986
diff changeset
   823
            # choose a consistent winner when there's a tie
21107
4a6c8b6b10d3 revlog: backout 514d32de6646 - commonancestors
Mads Kiilerich <madski@unity3d.com>
parents: 21104
diff changeset
   824
            return min(map(self.node, ancs))
18987
3605d4e7e618 revlog: choose a consistent ancestor when there's a tie
Bryan O'Sullivan <bryano@fb.com>
parents: 18986
diff changeset
   825
        return nullid
10897
adb6a291bbdb revlog: put graph related functions together
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10404
diff changeset
   826
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   827
    def _match(self, id):
16762
93f8b9565257 revlog: don't handle long for revision matching
Matt Mackall <mpm@selenic.com>
parents: 16686
diff changeset
   828
        if isinstance(id, int):
3156
d01e4cb2f5f2 cleanups in revlog.lookup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3139
diff changeset
   829
            # rev
2641
156fb1feab62 lookup should allow -1 to represent nullid (if passed an int as arg)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2600
diff changeset
   830
            return self.node(id)
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   831
        if len(id) == 20:
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   832
            # possibly a binary node
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   833
            # odds of a binary node being all hex in ASCII are 1 in 10**25
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   834
            try:
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   835
                node = id
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7873
diff changeset
   836
                self.rev(node) # quick search the index
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   837
                return node
3930
01d98d68d697 Add revlog.LookupError exception, and use it instead of RevlogError.
Brendan Cully <brendan@kublai.com>
parents: 3928
diff changeset
   838
            except LookupError:
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   839
                pass # may be partial hex id
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
   840
        try:
3156
d01e4cb2f5f2 cleanups in revlog.lookup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3139
diff changeset
   841
            # str(rev)
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
   842
            rev = int(id)
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   843
            if str(rev) != id:
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   844
                raise ValueError
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   845
            if rev < 0:
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   846
                rev = len(self) + rev
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
   847
            if rev < 0 or rev >= len(self):
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
   848
                raise ValueError
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
   849
            return self.node(rev)
469
e205194ca7ef Various node id lookup tweaks
mpm@selenic.com
parents: 451
diff changeset
   850
        except (ValueError, OverflowError):
3156
d01e4cb2f5f2 cleanups in revlog.lookup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3139
diff changeset
   851
            pass
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   852
        if len(id) == 40:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   853
            try:
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   854
                # a full hex nodeid?
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   855
                node = bin(id)
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7873
diff changeset
   856
                self.rev(node)
3157
4fe41a9e4591 optimize revlog.lookup when passed hex(node)[:...]
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3156
diff changeset
   857
                return node
7062
efc579fdaf69 provide nicer feedback when an unknown node id is passed to a command
Sune Foldager <cryo@cyanite.org>
parents: 6912
diff changeset
   858
            except (TypeError, LookupError):
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   859
                pass
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   860
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   861
    def _partialmatch(self, id):
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   862
        try:
19471
fd1bb7c1be78 revlog: handle hidden revs in _partialmatch (issue3979)
Matt Mackall <mpm@selenic.com>
parents: 19326
diff changeset
   863
            n = self.index.partialmatch(id)
fd1bb7c1be78 revlog: handle hidden revs in _partialmatch (issue3979)
Matt Mackall <mpm@selenic.com>
parents: 19326
diff changeset
   864
            if n and self.hasnode(n):
fd1bb7c1be78 revlog: handle hidden revs in _partialmatch (issue3979)
Matt Mackall <mpm@selenic.com>
parents: 19326
diff changeset
   865
                return n
fd1bb7c1be78 revlog: handle hidden revs in _partialmatch (issue3979)
Matt Mackall <mpm@selenic.com>
parents: 19326
diff changeset
   866
            return None
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   867
        except RevlogError:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   868
            # parsers.c radix tree lookup gave multiple matches
19471
fd1bb7c1be78 revlog: handle hidden revs in _partialmatch (issue3979)
Matt Mackall <mpm@selenic.com>
parents: 19326
diff changeset
   869
            # fall through to slow path that filters hidden revisions
fd1bb7c1be78 revlog: handle hidden revs in _partialmatch (issue3979)
Matt Mackall <mpm@selenic.com>
parents: 19326
diff changeset
   870
            pass
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   871
        except (AttributeError, ValueError):
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   872
            # we are pure python, or key was too short to search radix tree
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   873
            pass
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16533
diff changeset
   874
13258
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   875
        if id in self._pcache:
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   876
            return self._pcache[id]
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   877
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   878
        if len(id) < 40:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   879
            try:
3438
b17f9d3eda74 revlog.lookup tweaks
Matt Mackall <mpm@selenic.com>
parents: 3390
diff changeset
   880
                # hex(node)[:...]
9029
0001e49f1c11 compat: use // for integer division
Alejandro Santos <alejolp@alejolp.com>
parents: 8658
diff changeset
   881
                l = len(id) // 2  # grab an even number of digits
13259
3b616dfa4b17 revlog: do revlog node->rev mapping by scanning
Matt Mackall <mpm@selenic.com>
parents: 13258
diff changeset
   882
                prefix = bin(id[:l * 2])
3b616dfa4b17 revlog: do revlog node->rev mapping by scanning
Matt Mackall <mpm@selenic.com>
parents: 13258
diff changeset
   883
                nl = [e[7] for e in self.index if e[7].startswith(prefix)]
19471
fd1bb7c1be78 revlog: handle hidden revs in _partialmatch (issue3979)
Matt Mackall <mpm@selenic.com>
parents: 19326
diff changeset
   884
                nl = [n for n in nl if hex(n).startswith(id) and
fd1bb7c1be78 revlog: handle hidden revs in _partialmatch (issue3979)
Matt Mackall <mpm@selenic.com>
parents: 19326
diff changeset
   885
                      self.hasnode(n)]
7365
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   886
                if len(nl) > 0:
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   887
                    if len(nl) == 1:
13258
c2661863f16f revlog: introduce a cache for partial lookups
Matt Mackall <mpm@selenic.com>
parents: 13254
diff changeset
   888
                        self._pcache[id] = nl[0]
7365
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   889
                        return nl[0]
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   890
                    raise LookupError(id, self.indexfile,
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   891
                                      _('ambiguous identifier'))
ec3aafa84d44 lookup: speed up partial lookup
Matt Mackall <mpm@selenic.com>
parents: 7363
diff changeset
   892
                return None
3453
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   893
            except TypeError:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   894
                pass
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   895
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   896
    def lookup(self, id):
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   897
        """locate a node based on:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   898
            - revision number or str(revision number)
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   899
            - nodeid or subset of hex nodeid
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   900
        """
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   901
        n = self._match(id)
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   902
        if n is not None:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   903
            return n
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   904
        n = self._partialmatch(id)
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   905
        if n:
dba3cadef789 Only look up tags and branches as a last resort
Matt Mackall <mpm@selenic.com>
parents: 3438
diff changeset
   906
            return n
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 484
diff changeset
   907
6228
c0c4c7b1e8d3 revlog: report node and file when lookup fails
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
   908
        raise LookupError(id, self.indexfile, _('no match found'))
36
da28286bf6b7 Add smart node lookup by substring or by rev number
mpm@selenic.com
parents: 26
diff changeset
   909
2890
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
   910
    def cmp(self, node, text):
11539
a463e3c50212 cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11323
diff changeset
   911
        """compare text with a given file revision
a463e3c50212 cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11323
diff changeset
   912
a463e3c50212 cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11323
diff changeset
   913
        returns True if text is different than what is stored.
a463e3c50212 cmp: document the fact that we return True if content is different
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11323
diff changeset
   914
        """
2890
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
   915
        p1, p2 = self.parents(node)
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
   916
        return hash(text, p1, p2) != node
5df3e5cf16bc Move cmp bits from filelog to revlog
Matt Mackall <mpm@selenic.com>
parents: 2859
diff changeset
   917
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   918
    def _addchunk(self, offset, data):
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   919
        o, d = self._chunkcache
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   920
        # try to add to existing cache
13253
61c9bc3da402 revlog: remove lazy index
Matt Mackall <mpm@selenic.com>
parents: 13239
diff changeset
   921
        if o + len(d) == offset and len(d) + len(data) < _chunksize:
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   922
            self._chunkcache = o, d + data
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   923
        else:
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   924
            self._chunkcache = offset, data
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   925
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   926
    def _loadchunk(self, offset, length):
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   927
        if self._inline:
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   928
            df = self.opener(self.indexfile)
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   929
        else:
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   930
            df = self.opener(self.datafile)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   931
20179
5bb3826bdac4 revlog: read/cache chunks in fixed windows of 64 KB
Brodie Rao <brodie@sf.io>
parents: 20074
diff changeset
   932
        # Cache data both forward and backward around the requested
5bb3826bdac4 revlog: read/cache chunks in fixed windows of 64 KB
Brodie Rao <brodie@sf.io>
parents: 20074
diff changeset
   933
        # data, in a fixed size window. This helps speed up operations
5bb3826bdac4 revlog: read/cache chunks in fixed windows of 64 KB
Brodie Rao <brodie@sf.io>
parents: 20074
diff changeset
   934
        # involving reading the revlog backwards.
20180
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   935
        cachesize = self._chunkcachesize
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   936
        realoffset = offset & ~(cachesize - 1)
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   937
        reallength = (((offset + length + cachesize) & ~(cachesize - 1))
969148b49fc6 revlog: allow tuning of the chunk cache size (via format.chunkcachesize)
Brodie Rao <brodie@sf.io>
parents: 20179
diff changeset
   938
                      - realoffset)
20179
5bb3826bdac4 revlog: read/cache chunks in fixed windows of 64 KB
Brodie Rao <brodie@sf.io>
parents: 20074
diff changeset
   939
        df.seek(realoffset)
5bb3826bdac4 revlog: read/cache chunks in fixed windows of 64 KB
Brodie Rao <brodie@sf.io>
parents: 20074
diff changeset
   940
        d = df.read(reallength)
15407
ee112eb69d2a misc: adding missing file close() calls
Matt Mackall <mpm@selenic.com>
parents: 15057
diff changeset
   941
        df.close()
20179
5bb3826bdac4 revlog: read/cache chunks in fixed windows of 64 KB
Brodie Rao <brodie@sf.io>
parents: 20074
diff changeset
   942
        self._addchunk(realoffset, d)
5bb3826bdac4 revlog: read/cache chunks in fixed windows of 64 KB
Brodie Rao <brodie@sf.io>
parents: 20074
diff changeset
   943
        if offset != realoffset or reallength != length:
5bb3826bdac4 revlog: read/cache chunks in fixed windows of 64 KB
Brodie Rao <brodie@sf.io>
parents: 20074
diff changeset
   944
            return util.buffer(d, offset - realoffset, length)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   945
        return d
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   946
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   947
    def _getchunk(self, offset, length):
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   948
        o, d = self._chunkcache
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   949
        l = len(d)
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   950
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   951
        # is it in the cache?
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   952
        cachestart = offset - o
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   953
        cacheend = cachestart + length
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   954
        if cachestart >= 0 and cacheend <= l:
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   955
            if cachestart == 0 and cacheend == l:
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   956
                return d # avoid a copy
16423
a150923b49ba revlog: avoid an expensive string copy
Bryan O'Sullivan <bryano@fb.com>
parents: 16418
diff changeset
   957
            return util.buffer(d, cachestart, cacheend - cachestart)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   958
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   959
        return self._loadchunk(offset, length)
8316
d593922cf480 revlog: clean up the chunk caching code
Matt Mackall <mpm@selenic.com>
parents: 8315
diff changeset
   960
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   961
    def _chunkraw(self, startrev, endrev):
8318
6b8513f8274a revlog: add cache priming for reconstructing delta chains
Matt Mackall <mpm@selenic.com>
parents: 8317
diff changeset
   962
        start = self.start(startrev)
19714
0e07c0b5fb1c revlog.revision: fix cache preload for inline revlogs
Siddharth Agarwal <sid0@fb.com>
parents: 19713
diff changeset
   963
        end = self.end(endrev)
8318
6b8513f8274a revlog: add cache priming for reconstructing delta chains
Matt Mackall <mpm@selenic.com>
parents: 8317
diff changeset
   964
        if self._inline:
6b8513f8274a revlog: add cache priming for reconstructing delta chains
Matt Mackall <mpm@selenic.com>
parents: 8317
diff changeset
   965
            start += (startrev + 1) * self._io.size
19714
0e07c0b5fb1c revlog.revision: fix cache preload for inline revlogs
Siddharth Agarwal <sid0@fb.com>
parents: 19713
diff changeset
   966
            end += (endrev + 1) * self._io.size
0e07c0b5fb1c revlog.revision: fix cache preload for inline revlogs
Siddharth Agarwal <sid0@fb.com>
parents: 19713
diff changeset
   967
        length = end - start
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   968
        return self._getchunk(start, length)
8318
6b8513f8274a revlog: add cache priming for reconstructing delta chains
Matt Mackall <mpm@selenic.com>
parents: 8317
diff changeset
   969
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   970
    def _chunk(self, rev):
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   971
        return decompress(self._chunkraw(rev, rev))
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
   972
19713
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   973
    def _chunks(self, revs):
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   974
        '''faster version of [self._chunk(rev) for rev in revs]
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   975
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   976
        Assumes that revs is in ascending order.'''
19716
e17976978ee4 revlog: move chunk cache preload from revision to _chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19715
diff changeset
   977
        if not revs:
e17976978ee4 revlog: move chunk cache preload from revision to _chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19715
diff changeset
   978
            return []
19713
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   979
        start = self.start
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   980
        length = self.length
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   981
        inline = self._inline
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   982
        iosize = self._io.size
19715
1aab406be57c revlog._chunks: inline getchunk
Siddharth Agarwal <sid0@fb.com>
parents: 19714
diff changeset
   983
        buffer = util.buffer
19713
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   984
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   985
        l = []
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   986
        ladd = l.append
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
   987
19716
e17976978ee4 revlog: move chunk cache preload from revision to _chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19715
diff changeset
   988
        # preload the cache
20957
469d949a7cb8 revlog: deal with chunk ranges over 2G on Windows (issue4215)
Matt Mackall <mpm@selenic.com>
parents: 20217
diff changeset
   989
        try:
21752
e250a482478e revlog: fix check-code error
Matt Mackall <mpm@selenic.com>
parents: 21750
diff changeset
   990
            while True:
21749
f13728d59c0e revlog: make _chunkcache access atomic
Matt Mackall <mpm@selenic.com>
parents: 21107
diff changeset
   991
                # ensure that the cache doesn't change out from under us
f13728d59c0e revlog: make _chunkcache access atomic
Matt Mackall <mpm@selenic.com>
parents: 21107
diff changeset
   992
                _cache = self._chunkcache
f13728d59c0e revlog: make _chunkcache access atomic
Matt Mackall <mpm@selenic.com>
parents: 21107
diff changeset
   993
                self._chunkraw(revs[0], revs[-1])
f13728d59c0e revlog: make _chunkcache access atomic
Matt Mackall <mpm@selenic.com>
parents: 21107
diff changeset
   994
                if _cache == self._chunkcache:
f13728d59c0e revlog: make _chunkcache access atomic
Matt Mackall <mpm@selenic.com>
parents: 21107
diff changeset
   995
                    break
f13728d59c0e revlog: make _chunkcache access atomic
Matt Mackall <mpm@selenic.com>
parents: 21107
diff changeset
   996
            offset, data = _cache
20957
469d949a7cb8 revlog: deal with chunk ranges over 2G on Windows (issue4215)
Matt Mackall <mpm@selenic.com>
parents: 20217
diff changeset
   997
        except OverflowError:
469d949a7cb8 revlog: deal with chunk ranges over 2G on Windows (issue4215)
Matt Mackall <mpm@selenic.com>
parents: 20217
diff changeset
   998
            # issue4215 - we can't cache a run of chunks greater than
469d949a7cb8 revlog: deal with chunk ranges over 2G on Windows (issue4215)
Matt Mackall <mpm@selenic.com>
parents: 20217
diff changeset
   999
            # 2G on Windows
469d949a7cb8 revlog: deal with chunk ranges over 2G on Windows (issue4215)
Matt Mackall <mpm@selenic.com>
parents: 20217
diff changeset
  1000
            return [self._chunk(rev) for rev in revs]
19715
1aab406be57c revlog._chunks: inline getchunk
Siddharth Agarwal <sid0@fb.com>
parents: 19714
diff changeset
  1001
19713
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
  1002
        for rev in revs:
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
  1003
            chunkstart = start(rev)
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
  1004
            if inline:
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
  1005
                chunkstart += (rev + 1) * iosize
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
  1006
            chunklength = length(rev)
19715
1aab406be57c revlog._chunks: inline getchunk
Siddharth Agarwal <sid0@fb.com>
parents: 19714
diff changeset
  1007
            ladd(decompress(buffer(data, chunkstart - offset, chunklength)))
19713
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
  1008
c2e27e57d250 revlog: add a fast method for getting a list of chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19625
diff changeset
  1009
        return l
14075
bc101902a68d revlog: introduce _chunkbase to allow filelog to override
Sune Foldager <cryo@cyanite.org>
parents: 14064
diff changeset
  1010
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
  1011
    def _chunkclear(self):
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
  1012
        self._chunkcache = (0, '')
1598
14d1f1868bf6 cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
  1013
11929
1839a7518b0d revlog: deltachain() returns chain of revs need to construct a revision
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11928
diff changeset
  1014
    def deltaparent(self, rev):
14195
0013d3eeb826 revlog: remove support for parentdelta
Sune Foldager <cryo@cyanite.org>
parents: 14164
diff changeset
  1015
        """return deltaparent of the given revision"""
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
  1016
        base = self.index[rev][3]
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
  1017
        if base == rev:
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 14196
diff changeset
  1018
            return nullrev
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
  1019
        elif self._generaldelta:
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
  1020
            return base
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 14196
diff changeset
  1021
        else:
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 14196
diff changeset
  1022
            return rev - 1
11929
1839a7518b0d revlog: deltachain() returns chain of revs need to construct a revision
Pradeepkumar Gayam <in3xes@gmail.com>
parents: 11928
diff changeset
  1023
1941
7518823709a2 revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1853
diff changeset
  1024
    def revdiff(self, rev1, rev2):
7518823709a2 revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1853
diff changeset
  1025
        """return or calculate a delta between two revisions"""
14208
d62d597b8974 revlog: compute correct deltaparent in the deltaparent function
Sune Foldager <cryo@cyanite.org>
parents: 14196
diff changeset
  1026
        if rev1 != nullrev and self.deltaparent(rev2) == rev1:
16423
a150923b49ba revlog: avoid an expensive string copy
Bryan O'Sullivan <bryano@fb.com>
parents: 16418
diff changeset
  1027
            return str(self._chunk(rev2))
5005
72082bfced9a revlog: minor revdiff reorganization
Matt Mackall <mpm@selenic.com>
parents: 5004
diff changeset
  1028
16424
ff63d71ac8ab revlog: drop some unneeded rev.node calls in revdiff
Matt Mackall <mpm@selenic.com>
parents: 16423
diff changeset
  1029
        return mdiff.textdiff(self.revision(rev1),
ff63d71ac8ab revlog: drop some unneeded rev.node calls in revdiff
Matt Mackall <mpm@selenic.com>
parents: 16423
diff changeset
  1030
                              self.revision(rev2))
119
c7a66f9752a4 Add code to retrieve or construct a revlog delta
mpm@selenic.com
parents: 117
diff changeset
  1031
16375
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1032
    def revision(self, nodeorrev):
16435
df347129305d revlog: fix partial revision() docstring (from d7d64b89a65c)
Patrick Mezard <patrick@mezard.eu>
parents: 16424
diff changeset
  1033
        """return an uncompressed revision of a given node or revision
df347129305d revlog: fix partial revision() docstring (from d7d64b89a65c)
Patrick Mezard <patrick@mezard.eu>
parents: 16424
diff changeset
  1034
        number.
df347129305d revlog: fix partial revision() docstring (from d7d64b89a65c)
Patrick Mezard <patrick@mezard.eu>
parents: 16424
diff changeset
  1035
        """
16375
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1036
        if isinstance(nodeorrev, int):
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1037
            rev = nodeorrev
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1038
            node = self.node(rev)
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1039
        else:
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1040
            node = nodeorrev
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1041
            rev = None
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1042
21750
4ab287c2d337 revlog: hold a private reference to self._cache
Matt Mackall <mpm@selenic.com>
parents: 21749
diff changeset
  1043
        _cache = self._cache # grab local copy of cache to avoid thread race
11996
3195cf01dfb9 revlog.revision(): don't use nullrev as the default value for the cache
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11995
diff changeset
  1044
        cachedrev = None
4980
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
  1045
        if node == nullid:
fc44c8df9d99 revlog: some codingstyle cleanups
Matt Mackall <mpm@selenic.com>
parents: 4979
diff changeset
  1046
            return ""
21750
4ab287c2d337 revlog: hold a private reference to self._cache
Matt Mackall <mpm@selenic.com>
parents: 21749
diff changeset
  1047
        if _cache:
4ab287c2d337 revlog: hold a private reference to self._cache
Matt Mackall <mpm@selenic.com>
parents: 21749
diff changeset
  1048
            if _cache[0] == node:
4ab287c2d337 revlog: hold a private reference to self._cache
Matt Mackall <mpm@selenic.com>
parents: 21749
diff changeset
  1049
                return _cache[2]
4ab287c2d337 revlog: hold a private reference to self._cache
Matt Mackall <mpm@selenic.com>
parents: 21749
diff changeset
  1050
            cachedrev = _cache[1]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1051
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1052
        # look up what we need to read
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1053
        text = None
16375
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1054
        if rev is None:
d7d64b89a65c revlog: allow retrieving contents by revision number
Matt Mackall <mpm@selenic.com>
parents: 16374
diff changeset
  1055
            rev = self.rev(node)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1056
5004
825516d16b25 revlog: move flag checking out of the offset fastpath
Matt Mackall <mpm@selenic.com>
parents: 4996
diff changeset
  1057
        # check rev flags
11745
138c055ec57d revlog: add punched revision flag
Vishakh H <vsh426@gmail.com>
parents: 11693
diff changeset
  1058
        if self.flags(rev) & ~REVIDX_KNOWN_FLAGS:
5312
fb070713ff36 revlog: more robust for damaged indexes
Matt Mackall <mpm@selenic.com>
parents: 5007
diff changeset
  1059
            raise RevlogError(_('incompatible revision flag %x') %
11745
138c055ec57d revlog: add punched revision flag
Vishakh H <vsh426@gmail.com>
parents: 11693
diff changeset
  1060
                              (self.flags(rev) & ~REVIDX_KNOWN_FLAGS))
5004
825516d16b25 revlog: move flag checking out of the offset fastpath
Matt Mackall <mpm@selenic.com>
parents: 4996
diff changeset
  1061
11995
ff84cd2bdfaf revlog.revision(): minor cleanup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11963
diff changeset
  1062
        # build delta chain
11998
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
  1063
        chain = []
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
  1064
        index = self.index # for performance
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
  1065
        generaldelta = self._generaldelta
11998
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
  1066
        iterrev = rev
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
  1067
        e = index[iterrev]
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
  1068
        while iterrev != e[3] and iterrev != cachedrev:
11998
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
  1069
            chain.append(iterrev)
14253
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
  1070
            if generaldelta:
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
  1071
                iterrev = e[3]
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
  1072
            else:
c28d5200374c revlog: support reading generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14252
diff changeset
  1073
                iterrev -= 1
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
  1074
            e = index[iterrev]
11995
ff84cd2bdfaf revlog.revision(): minor cleanup
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11963
diff changeset
  1075
11998
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
  1076
        if iterrev == cachedrev:
e789a811c21d revlog.revision(): inline deltachain computation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11997
diff changeset
  1077
            # cache hit
21750
4ab287c2d337 revlog: hold a private reference to self._cache
Matt Mackall <mpm@selenic.com>
parents: 21749
diff changeset
  1078
            text = _cache[2]
19716
e17976978ee4 revlog: move chunk cache preload from revision to _chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19715
diff changeset
  1079
        else:
e17976978ee4 revlog: move chunk cache preload from revision to _chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19715
diff changeset
  1080
            chain.append(iterrev)
e17976978ee4 revlog: move chunk cache preload from revision to _chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19715
diff changeset
  1081
        chain.reverse()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1082
11754
6ccd130eab0e revlog: drop cache after use to save memory footprint
Matt Mackall <mpm@selenic.com>
parents: 11539
diff changeset
  1083
        # drop cache to save memory
6ccd130eab0e revlog: drop cache after use to save memory footprint
Matt Mackall <mpm@selenic.com>
parents: 11539
diff changeset
  1084
        self._cache = None
6ccd130eab0e revlog: drop cache after use to save memory footprint
Matt Mackall <mpm@selenic.com>
parents: 11539
diff changeset
  1085
19716
e17976978ee4 revlog: move chunk cache preload from revision to _chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19715
diff changeset
  1086
        bins = self._chunks(chain)
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
  1087
        if text is None:
19716
e17976978ee4 revlog: move chunk cache preload from revision to _chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19715
diff changeset
  1088
            text = str(bins[0])
e17976978ee4 revlog: move chunk cache preload from revision to _chunks
Siddharth Agarwal <sid0@fb.com>
parents: 19715
diff changeset
  1089
            bins = bins[1:]
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
  1090
4989
1aaed3d69772 revlog: eliminate diff and patches functions
Matt Mackall <mpm@selenic.com>
parents: 4988
diff changeset
  1091
        text = mdiff.patches(text, bins)
13239
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1092
13276
ba6a63339f7c revlog: pass rev to _checkhash
Matt Mackall <mpm@selenic.com>
parents: 13275
diff changeset
  1093
        text = self._checkhash(text, node, rev)
13239
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1094
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1095
        self._cache = (node, rev, text)
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1096
        return text
12ed25f39d0b revlog: break hash checking into subfunction
Matt Mackall <mpm@selenic.com>
parents: 13031
diff changeset
  1097
22785
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1098
    def hash(self, text, p1, p2):
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1099
        """Compute a node hash.
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1100
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1101
        Available as a function so that subclasses can replace the hash
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1102
        as needed.
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1103
        """
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1104
        return hash(text, p1, p2)
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1105
13276
ba6a63339f7c revlog: pass rev to _checkhash
Matt Mackall <mpm@selenic.com>
parents: 13275
diff changeset
  1106
    def _checkhash(self, text, node, rev):
1598
14d1f1868bf6 cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
  1107
        p1, p2 = self.parents(node)
19624
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1108
        self.checkhash(text, p1, p2, node, rev)
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1109
        return text
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1110
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1111
    def checkhash(self, text, p1, p2, node, rev=None):
22785
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1112
        if node != self.hash(text, p1, p2):
19624
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1113
            revornode = rev
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1114
            if revornode is None:
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1115
                revornode = templatefilters.short(hex(node))
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1116
            raise RevlogError(_("integrity check failed on %s:%s")
55749cb14d24 revlog: extract 'checkhash' method
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1117
                % (self.indexfile, revornode))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1118
2075
343aeefb553b Make the appendfile class inline-data index friendly
mason@suse.com
parents: 2073
diff changeset
  1119
    def checkinlinesize(self, tr, fp=None):
10913
f2ecc5733c89 revlog: factor out _maxinline global.
Greg Ward <greg-hg@gerg.ca>
parents: 10404
diff changeset
  1120
        if not self._inline or (self.start(-2) + self.length(-2)) < _maxinline:
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1121
            return
8315
c8493310ad9b revlog: use index to find index size
Matt Mackall <mpm@selenic.com>
parents: 8314
diff changeset
  1122
2084
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
  1123
        trinfo = tr.find(self.indexfile)
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8464
diff changeset
  1124
        if trinfo is None:
3680
69cf255a55a1 Indentation cleanups for 2956948b81f3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3679
diff changeset
  1125
            raise RevlogError(_("%s not found in the transaction")
69cf255a55a1 Indentation cleanups for 2956948b81f3.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3679
diff changeset
  1126
                              % self.indexfile)
2084
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
  1127
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
  1128
        trindex = trinfo[2]
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
  1129
        dataoff = self.start(trindex)
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
  1130
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
  1131
        tr.add(self.datafile, dataoff)
8315
c8493310ad9b revlog: use index to find index size
Matt Mackall <mpm@selenic.com>
parents: 8314
diff changeset
  1132
8317
5cdf4067857a revlog: use chunk cache to avoid rereading when splitting inline files
Matt Mackall <mpm@selenic.com>
parents: 8316
diff changeset
  1133
        if fp:
5cdf4067857a revlog: use chunk cache to avoid rereading when splitting inline files
Matt Mackall <mpm@selenic.com>
parents: 8316
diff changeset
  1134
            fp.flush()
5cdf4067857a revlog: use chunk cache to avoid rereading when splitting inline files
Matt Mackall <mpm@selenic.com>
parents: 8316
diff changeset
  1135
            fp.close()
8315
c8493310ad9b revlog: use index to find index size
Matt Mackall <mpm@selenic.com>
parents: 8314
diff changeset
  1136
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1137
        df = self.opener(self.datafile, 'w')
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1138
        try:
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1139
            for r in self:
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
  1140
                df.write(self._chunkraw(r, r))
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1141
        finally:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1142
            df.close()
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1143
2076
d007df6daf8e Create an atomic opener that does not automatically rename on close
mason@suse.com
parents: 2075
diff changeset
  1144
        fp = self.opener(self.indexfile, 'w', atomictemp=True)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1145
        self.version &= ~(REVLOGNGINLINEDATA)
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1146
        self._inline = False
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1147
        for i in self:
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
  1148
            e = self._io.packentry(self.index[i], self.node, self.version, i)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1149
            fp.write(e)
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1150
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14960
diff changeset
  1151
        # if we don't call close, the temp file will never replace the
2076
d007df6daf8e Create an atomic opener that does not automatically rename on close
mason@suse.com
parents: 2075
diff changeset
  1152
        # real index
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14960
diff changeset
  1153
        fp.close()
2084
Chris Mason <mason@suse.com>
parents: 2082
diff changeset
  1154
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
  1155
        tr.replace(self.indexfile, trindex * self._io.size)
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
  1156
        self._chunkclear()
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1157
19625
6a411a06cb1f revlog: pass node as an argument of addrevision
Wojciech Lopata <lopek@fb.com>
parents: 19624
diff changeset
  1158
    def addrevision(self, text, transaction, link, p1, p2, cachedelta=None,
6a411a06cb1f revlog: pass node as an argument of addrevision
Wojciech Lopata <lopek@fb.com>
parents: 19624
diff changeset
  1159
                    node=None):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1160
        """add a revision to the log
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1161
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1162
        text - the revision data to add
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1163
        transaction - the transaction object used for rollback
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1164
        link - the linkrev data to add
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1165
        p1, p2 - the parent nodeids of the revision
12012
bade7a9c5c07 revlog: fix docstring
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12011
diff changeset
  1166
        cachedelta - an optional precomputed delta
19625
6a411a06cb1f revlog: pass node as an argument of addrevision
Wojciech Lopata <lopek@fb.com>
parents: 19624
diff changeset
  1167
        node - nodeid of revision; typically node is not specified, and it is
6a411a06cb1f revlog: pass node as an argument of addrevision
Wojciech Lopata <lopek@fb.com>
parents: 19624
diff changeset
  1168
            computed by default as hash(text, p1, p2), however subclasses might
6a411a06cb1f revlog: pass node as an argument of addrevision
Wojciech Lopata <lopek@fb.com>
parents: 19624
diff changeset
  1169
            use different hashing method (and override checkhash() in such case)
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1170
        """
19326
7014526d67a8 revlog: add exception when linkrev == nullrev
Durham Goode <durham@fb.com>
parents: 19200
diff changeset
  1171
        if link == nullrev:
7014526d67a8 revlog: add exception when linkrev == nullrev
Durham Goode <durham@fb.com>
parents: 19200
diff changeset
  1172
            raise RevlogError(_("attempted to add linkrev -1 to %s")
7014526d67a8 revlog: add exception when linkrev == nullrev
Durham Goode <durham@fb.com>
parents: 19200
diff changeset
  1173
                              % self.indexfile)
22785
abc44fcc9c57 revlog: move references to revlog.hash to inside the revlog class
Augie Fackler <raf@durin42.com>
parents: 22784
diff changeset
  1174
        node = node or self.hash(text, p1, p2)
14196
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
  1175
        if node in self.nodemap:
12023
44c22dc193a4 revlog.addrevision(): move computation of nodeid in addrevision()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12012
diff changeset
  1176
            return node
44c22dc193a4 revlog.addrevision(): move computation of nodeid in addrevision()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12012
diff changeset
  1177
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1178
        dfh = None
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1179
        if not self._inline:
3390
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1180
            dfh = self.opener(self.datafile, "a")
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1181
        ifh = self.opener(self.indexfile, "a+")
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1182
        try:
12023
44c22dc193a4 revlog.addrevision(): move computation of nodeid in addrevision()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12012
diff changeset
  1183
            return self._addrevision(node, text, transaction, link, p1, p2,
23856
062c3ad86651 revlog: add flags argument to _addrevision, update callers use default flags
Mike Edgar <adgar@google.com>
parents: 23855
diff changeset
  1184
                                     REVIDX_DEFAULT_FLAGS, cachedelta, ifh, dfh)
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1185
        finally:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1186
            if dfh:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1187
                dfh.close()
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1188
            ifh.close()
3390
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1189
17128
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1190
    def compress(self, text):
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1191
        """ generate a possibly-compressed representation of text """
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1192
        if not text:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1193
            return ("", text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1194
        l = len(text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1195
        bin = None
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1196
        if l < 44:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1197
            pass
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1198
        elif l > 1000000:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1199
            # zlib makes an internal copy, thus doubling memory usage for
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1200
            # large files, so lets do this in pieces
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1201
            z = zlib.compressobj()
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1202
            p = []
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1203
            pos = 0
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1204
            while pos < l:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1205
                pos2 = pos + 2**20
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1206
                p.append(z.compress(text[pos:pos2]))
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1207
                pos = pos2
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1208
            p.append(z.flush())
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1209
            if sum(map(len, p)) < l:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1210
                bin = "".join(p)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1211
        else:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1212
            bin = _compress(text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1213
        if bin is None or len(bin) > l:
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1214
            if text[0] == '\0':
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1215
                return ("", text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1216
            return ('u', text)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1217
        return ("", bin)
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1218
23856
062c3ad86651 revlog: add flags argument to _addrevision, update callers use default flags
Mike Edgar <adgar@google.com>
parents: 23855
diff changeset
  1219
    def _addrevision(self, node, text, transaction, link, p1, p2, flags,
11962
5f7ee3db3dd8 revlog._addrevision(): make the parent of the cached delta explicit
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11935
diff changeset
  1220
                     cachedelta, ifh, dfh):
14292
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1221
        """internal function to add revisions to the log
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1222
14292
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1223
        see addrevision for argument descriptions.
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1224
        invariants:
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1225
        - text is optional (can be None); if not set, cachedelta must be set.
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17150
diff changeset
  1226
          if both are set, they must correspond to each other.
14292
c97d8485b5fa revlog: add docstring to _addrevision
Sune Foldager <cryo@cyanite.org>
parents: 14270
diff changeset
  1227
        """
12886
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1228
        btext = [text]
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1229
        def buildtext():
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1230
            if btext[0] is not None:
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1231
                return btext[0]
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1232
            # flush any pending writes here so we can read it in revision
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1233
            if dfh:
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1234
                dfh.flush()
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1235
            ifh.flush()
24122
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1236
            baserev = cachedelta[0]
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1237
            delta = cachedelta[1]
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1238
            # special case deltas which replace entire base; no need to decode
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1239
            # base revision. this neatly avoids censored bases, which throw when
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1240
            # they're decoded.
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1241
            hlen = struct.calcsize(">lll")
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1242
            if delta[:hlen] == mdiff.replacediffheader(self.rawsize(baserev),
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1243
                                                       len(delta) - hlen):
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1244
                btext[0] = delta[hlen:]
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1245
            else:
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1246
                basetext = self.revision(self.node(baserev))
da14b8eba806 revlog: special case expanding full-replacement deltas received by exchange
Mike Edgar <adgar@google.com>
parents: 24120
diff changeset
  1247
                btext[0] = mdiff.patch(basetext, delta)
22934
8a096d4d0862 revlog: support importing censored file revision tombstones
Mike Edgar <adgar@google.com>
parents: 22785
diff changeset
  1248
            try:
8a096d4d0862 revlog: support importing censored file revision tombstones
Mike Edgar <adgar@google.com>
parents: 22785
diff changeset
  1249
                self.checkhash(btext[0], p1, p2, node)
23857
8a3c132f93d2 revlog: verify censored flag when hashing added revision fulltext
Mike Edgar <adgar@google.com>
parents: 23856
diff changeset
  1250
                if flags & REVIDX_ISCENSORED:
8a3c132f93d2 revlog: verify censored flag when hashing added revision fulltext
Mike Edgar <adgar@google.com>
parents: 23856
diff changeset
  1251
                    raise RevlogError(_('node %s is not censored') % node)
22934
8a096d4d0862 revlog: support importing censored file revision tombstones
Mike Edgar <adgar@google.com>
parents: 22785
diff changeset
  1252
            except CensoredNodeError:
23857
8a3c132f93d2 revlog: verify censored flag when hashing added revision fulltext
Mike Edgar <adgar@google.com>
parents: 23856
diff changeset
  1253
                # must pass the censored index flag to add censored revisions
8a3c132f93d2 revlog: verify censored flag when hashing added revision fulltext
Mike Edgar <adgar@google.com>
parents: 23856
diff changeset
  1254
                if not flags & REVIDX_ISCENSORED:
8a3c132f93d2 revlog: verify censored flag when hashing added revision fulltext
Mike Edgar <adgar@google.com>
parents: 23856
diff changeset
  1255
                    raise
12886
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1256
            return btext[0]
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1257
12888
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1258
        def builddelta(rev):
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1259
            # can we use the cached delta?
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1260
            if cachedelta and cachedelta[0] == rev:
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1261
                delta = cachedelta[1]
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1262
            else:
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1263
                t = buildtext()
24123
eb2d41c6ec37 revlog: _addrevision creates full-replace deltas based on censored revisions
Mike Edgar <adgar@google.com>
parents: 24122
diff changeset
  1264
                if self.iscensored(rev):
eb2d41c6ec37 revlog: _addrevision creates full-replace deltas based on censored revisions
Mike Edgar <adgar@google.com>
parents: 24122
diff changeset
  1265
                    # deltas based on a censored revision must replace the
eb2d41c6ec37 revlog: _addrevision creates full-replace deltas based on censored revisions
Mike Edgar <adgar@google.com>
parents: 24122
diff changeset
  1266
                    # full content in one patch, so delta works everywhere
eb2d41c6ec37 revlog: _addrevision creates full-replace deltas based on censored revisions
Mike Edgar <adgar@google.com>
parents: 24122
diff changeset
  1267
                    header = mdiff.replacediffheader(self.rawsize(rev), len(t))
eb2d41c6ec37 revlog: _addrevision creates full-replace deltas based on censored revisions
Mike Edgar <adgar@google.com>
parents: 24122
diff changeset
  1268
                    delta = header + t
eb2d41c6ec37 revlog: _addrevision creates full-replace deltas based on censored revisions
Mike Edgar <adgar@google.com>
parents: 24122
diff changeset
  1269
                else:
eb2d41c6ec37 revlog: _addrevision creates full-replace deltas based on censored revisions
Mike Edgar <adgar@google.com>
parents: 24122
diff changeset
  1270
                    ptext = self.revision(self.node(rev))
eb2d41c6ec37 revlog: _addrevision creates full-replace deltas based on censored revisions
Mike Edgar <adgar@google.com>
parents: 24122
diff changeset
  1271
                    delta = mdiff.textdiff(ptext, t)
17128
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1272
            data = self.compress(delta)
12888
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1273
            l = len(data[1]) + len(data[0])
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1274
            if basecache[0] == rev:
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1275
                chainbase = basecache[1]
14252
19067884c5f5 revlog: calculate base revisions iteratively
Sune Foldager <cryo@cyanite.org>
parents: 14251
diff changeset
  1276
            else:
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1277
                chainbase = self.chainbase(rev)
17150
3ac9592b7ab4 backout e7167007c083
Matt Mackall <mpm@selenic.com>
parents: 17139
diff changeset
  1278
            dist = l + offset - self.start(chainbase)
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1279
            if self._generaldelta:
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1280
                base = rev
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1281
            else:
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1282
                base = chainbase
23287
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1283
            chainlen, compresseddeltalen = self._chaininfo(rev)
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1284
            chainlen += 1
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1285
            compresseddeltalen += l
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1286
            return dist, l, data, base, chainbase, chainlen, compresseddeltalen
12888
ad01fe38afe6 revlog: extract delta building to a subfunction
Matt Mackall <mpm@selenic.com>
parents: 12887
diff changeset
  1287
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1288
        curr = len(self)
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1289
        prev = curr - 1
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1290
        base = chainbase = curr
23255
76effa770ff9 revlog: add config variable for limiting delta-chain length
Mateusz Kwapich <mitrandir@fb.com>
parents: 23254
diff changeset
  1291
        chainlen = None
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1292
        offset = self.end(prev)
11962
5f7ee3db3dd8 revlog._addrevision(): make the parent of the cached delta explicit
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11935
diff changeset
  1293
        d = None
19764
e92650e39f1c generaldelta: initialize basecache properly
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1294
        if self._basecache is None:
e92650e39f1c generaldelta: initialize basecache properly
Wojciech Lopata <lopek@fb.com>
parents: 19471
diff changeset
  1295
            self._basecache = (prev, self.chainbase(prev))
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1296
        basecache = self._basecache
12889
5482c6b826f4 revlog: precalculate p1 and p2 revisions
Matt Mackall <mpm@selenic.com>
parents: 12888
diff changeset
  1297
        p1r, p2r = self.rev(p1), self.rev(p2)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1298
11963
7c3aa579d98a parendelta: fix computation of base rev (fixes issue2337)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11962
diff changeset
  1299
        # should we try to build a delta?
12890
b1c839659140 revlog: choose best delta for parentdelta (issue2466)
Matt Mackall <mpm@selenic.com>
parents: 12889
diff changeset
  1300
        if prev != nullrev:
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1301
            if self._generaldelta:
14301
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1302
                if p1r >= basecache[1]:
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1303
                    d = builddelta(p1r)
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1304
                elif p2r >= basecache[1]:
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1305
                    d = builddelta(p2r)
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1306
                else:
f94993769c87 revlog: improve delta generation heuristics for generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14296
diff changeset
  1307
                    d = builddelta(prev)
14270
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1308
            else:
d6907a5674a2 revlog: support writing generaldelta revlogs
Sune Foldager <cryo@cyanite.org>
parents: 14253
diff changeset
  1309
                d = builddelta(prev)
23287
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1310
            dist, l, data, base, chainbase, chainlen, compresseddeltalen = d
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1311
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1312
        # full versions are inserted when the needed deltas
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1313
        # become comparable to the uncompressed text
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1314
        if text is None:
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1315
            textlen = mdiff.patchedsize(self.rawsize(cachedelta[0]),
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1316
                                        cachedelta[1])
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1317
        else:
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1318
            textlen = len(text)
23287
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1319
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1320
        # - 'dist' is the distance from the base revision -- bounding it limits
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1321
        #   the amount of I/O we need to do.
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1322
        # - 'compresseddeltalen' is the sum of the total size of deltas we need
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1323
        #   to apply -- bounding it limits the amount of CPU we consume.
23288
2b9bc7963504 revlog: increase I/O bound to 4x the amount of data consumed
Siddharth Agarwal <sid0@fb.com>
parents: 23287
diff changeset
  1324
        if (d is None or dist > textlen * 4 or l > textlen or
23287
426d7f901789 revlog: bound based on the length of the compressed deltas
Siddharth Agarwal <sid0@fb.com>
parents: 23286
diff changeset
  1325
            compresseddeltalen > textlen * 2 or
23284
8d47c212b0dd revlog: make a predicate clearer with parens
Siddharth Agarwal <sid0@fb.com>
parents: 23255
diff changeset
  1326
            (self._maxchainlen and chainlen > self._maxchainlen)):
12886
c25945a148c1 revlog: fix buildtext local scope
Matt Mackall <mpm@selenic.com>
parents: 12624
diff changeset
  1327
            text = buildtext()
17128
1028a1c9077a revlog: make compress a method
Bryan O'Sullivan <bryano@fb.com>
parents: 17009
diff changeset
  1328
            data = self.compress(text)
1533
3d11f81c9145 Reduce string duplication in compression code
mason@suse.com
parents: 1509
diff changeset
  1329
            l = len(data[1]) + len(data[0])
14296
62e25c63fb3a revlog: fix bug in chainbase cache
Sune Foldager <cryo@cyanite.org>
parents: 14292
diff changeset
  1330
            base = chainbase = curr
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
  1331
12623
8f97b50a8d10 revlog._addrevision(): allow text argument to be None, build it lazily
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12336
diff changeset
  1332
        e = (offset_type(offset, flags), l, textlen,
12889
5482c6b826f4 revlog: precalculate p1 and p2 revisions
Matt Mackall <mpm@selenic.com>
parents: 12888
diff changeset
  1333
             base, link, p1r, p2r, node)
4979
06abdaf78788 revlog: add a magic null revision to our index
Matt Mackall <mpm@selenic.com>
parents: 4978
diff changeset
  1334
        self.index.insert(-1, e)
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1335
        self.nodemap[node] = curr
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
  1336
5338
f87685355c9c revlog: fix revlogio.packentry corner case
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5325
diff changeset
  1337
        entry = self._io.packentry(e, self.node, self.version, curr)
20217
33394f2e331e revlog: move file writing to a separate function
Durham Goode <durham@fb.com>
parents: 20180
diff changeset
  1338
        self._writeentry(transaction, ifh, dfh, entry, data, link, offset)
33394f2e331e revlog: move file writing to a separate function
Durham Goode <durham@fb.com>
parents: 20180
diff changeset
  1339
33394f2e331e revlog: move file writing to a separate function
Durham Goode <durham@fb.com>
parents: 20180
diff changeset
  1340
        if type(text) == str: # only accept immutable objects
33394f2e331e revlog: move file writing to a separate function
Durham Goode <durham@fb.com>
parents: 20180
diff changeset
  1341
            self._cache = (node, curr, text)
33394f2e331e revlog: move file writing to a separate function
Durham Goode <durham@fb.com>
parents: 20180
diff changeset
  1342
        self._basecache = (curr, chainbase)
33394f2e331e revlog: move file writing to a separate function
Durham Goode <durham@fb.com>
parents: 20180
diff changeset
  1343
        return node
33394f2e331e revlog: move file writing to a separate function
Durham Goode <durham@fb.com>
parents: 20180
diff changeset
  1344
33394f2e331e revlog: move file writing to a separate function
Durham Goode <durham@fb.com>
parents: 20180
diff changeset
  1345
    def _writeentry(self, transaction, ifh, dfh, entry, data, link, offset):
33394f2e331e revlog: move file writing to a separate function
Durham Goode <durham@fb.com>
parents: 20180
diff changeset
  1346
        curr = len(self) - 1
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1347
        if not self._inline:
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1348
            transaction.add(self.datafile, offset)
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1349
            transaction.add(self.indexfile, curr * len(entry))
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1350
            if data[0]:
3390
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1351
                dfh.write(data[0])
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1352
            dfh.write(data[1])
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1353
            dfh.flush()
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1354
            ifh.write(entry)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1355
        else:
4996
a0d37976cd5b revlog: avoid some unnecessary seek/tell syscalls
Matt Mackall <mpm@selenic.com>
parents: 4994
diff changeset
  1356
            offset += curr * self._io.size
5324
8409a2e3a78d revlog: fix inlined revision transaction extra data (issue 749)
Patrick Mezard <pmezard@gmail.com>
parents: 5007
diff changeset
  1357
            transaction.add(self.indexfile, offset, curr)
4981
e7131935fbb3 revlog: simplify addrevision
Matt Mackall <mpm@selenic.com>
parents: 4980
diff changeset
  1358
            ifh.write(entry)
3390
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1359
            ifh.write(data[0])
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1360
            ifh.write(data[1])
a74addddd092 make revlog.addgroup pass its file handles to addrevision
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3360
diff changeset
  1361
            self.checkinlinesize(transaction, ifh)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1362
12335
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12025
diff changeset
  1363
    def addgroup(self, bundle, linkmapper, transaction):
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1364
        """
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1365
        add a delta group
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1366
1083
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1367
        given a set of deltas, add them to the revision log. the
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1368
        first delta is against its parent, which should be in our
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1369
        log, the rest are against the previous delta.
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1370
        """
30974cf73435 Add some docstrings to revlog.py
mpm@selenic.com
parents: 1074
diff changeset
  1371
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1372
        # track the base of the current delta log
15890
e234eda20984 revlog: make addgroup returns a list of node contained in the added source
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15835
diff changeset
  1373
        content = []
2002
4aab906517c6 Calling revlog.addgroup with an empty changegroup now raises RevlogError.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1981
diff changeset
  1374
        node = None
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 484
diff changeset
  1375
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1376
        r = len(self)
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1377
        end = 0
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1378
        if r:
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1379
            end = self.end(r - 1)
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
  1380
        ifh = self.opener(self.indexfile, "a+")
4996
a0d37976cd5b revlog: avoid some unnecessary seek/tell syscalls
Matt Mackall <mpm@selenic.com>
parents: 4994
diff changeset
  1381
        isize = r * self._io.size
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1382
        if self._inline:
4996
a0d37976cd5b revlog: avoid some unnecessary seek/tell syscalls
Matt Mackall <mpm@selenic.com>
parents: 4994
diff changeset
  1383
            transaction.add(self.indexfile, end + isize, r)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1384
            dfh = None
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1385
        else:
4996
a0d37976cd5b revlog: avoid some unnecessary seek/tell syscalls
Matt Mackall <mpm@selenic.com>
parents: 4994
diff changeset
  1386
            transaction.add(self.indexfile, isize, r)
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1387
            transaction.add(self.datafile, end)
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1388
            dfh = self.opener(self.datafile, "a")
24255
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1389
        def flush():
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1390
            if dfh:
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1391
                dfh.flush()
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1392
            ifh.flush()
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1393
        try:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1394
            # loop through our set of deltas
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1395
            chain = None
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 14393
diff changeset
  1396
            while True:
14144
3c3c53d8343a unbundler: separate delta and header parsing
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14143
diff changeset
  1397
                chunkdata = bundle.deltachunk(chain)
12336
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1398
                if not chunkdata:
12335
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12025
diff changeset
  1399
                    break
12336
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1400
                node = chunkdata['node']
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1401
                p1 = chunkdata['p1']
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1402
                p2 = chunkdata['p2']
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1403
                cs = chunkdata['cs']
14141
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1404
                deltabase = chunkdata['deltabase']
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1405
                delta = chunkdata['delta']
12336
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
  1406
15890
e234eda20984 revlog: make addgroup returns a list of node contained in the added source
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15835
diff changeset
  1407
                content.append(node)
e234eda20984 revlog: make addgroup returns a list of node contained in the added source
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15835
diff changeset
  1408
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1409
                link = linkmapper(cs)
14196
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
  1410
                if node in self.nodemap:
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1411
                    # this can happen if two branches make the same change
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1412
                    chain = node
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1413
                    continue
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 155
diff changeset
  1414
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1415
                for p in (p1, p2):
16686
67964cda8701 cleanup: "not x in y" -> "x not in y"
Brodie Rao <brodie@sf.io>
parents: 16665
diff changeset
  1416
                    if p not in self.nodemap:
14196
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
  1417
                        raise LookupError(p, self.indexfile,
e7483ec3c374 revlog: remove support for punched/shallow
Sune Foldager <cryo@cyanite.org>
parents: 14195
diff changeset
  1418
                                          _('unknown parent'))
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1419
14141
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1420
                if deltabase not in self.nodemap:
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1421
                    raise LookupError(deltabase, self.indexfile,
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1422
                                      _('unknown delta base'))
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1423
14141
bd1cbfe5db5c bundler: make parsechunk return the base revision of the delta
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14075
diff changeset
  1424
                baserev = self.rev(deltabase)
24120
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1425
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1426
                if baserev != nullrev and self.iscensored(baserev):
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1427
                    # if base is censored, delta must be full replacement in a
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1428
                    # single patch operation
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1429
                    hlen = struct.calcsize(">lll")
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1430
                    oldlen = self.rawsize(baserev)
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1431
                    newlen = len(delta) - hlen
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1432
                    if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1433
                        raise error.CensoredBaseError(self.indexfile,
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1434
                                                      self.node(baserev))
a450e0a2ba0a revlog: in addgroup, reject ill-formed deltas based on censored nodes
Mike Edgar <adgar@google.com>
parents: 24118
diff changeset
  1435
24255
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1436
                flags = REVIDX_DEFAULT_FLAGS
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1437
                if self._peek_iscensored(baserev, delta, flush):
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1438
                    flags |= REVIDX_ISCENSORED
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1439
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1440
                chain = self._addrevision(node, None, transaction, link,
24255
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1441
                                          p1, p2, flags, (baserev, delta),
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1442
                                          ifh, dfh)
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1443
                if not dfh and not self._inline:
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1444
                    # addrevision switched from inline to conventional
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1445
                    # reopen the index
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13284
diff changeset
  1446
                    ifh.close()
12624
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1447
                    dfh = self.opener(self.datafile, "a")
557988c691d1 revlog.addgroup(): always use _addrevision() to add new revlog entries
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12623
diff changeset
  1448
                    ifh = self.opener(self.indexfile, "a")
6261
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1449
        finally:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1450
            if dfh:
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1451
                dfh.close()
7c8101b5ceb1 revlog: make sure the files are closed after an exception happens
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6228
diff changeset
  1452
            ifh.close()
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 45
diff changeset
  1453
15890
e234eda20984 revlog: make addgroup returns a list of node contained in the added source
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15835
diff changeset
  1454
        return content
1493
1a216cb4ee64 verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents: 1469
diff changeset
  1455
24118
76f6ae06ddf5 revlog: add "iscensored()" to revlog public API
Mike Edgar <adgar@google.com>
parents: 24030
diff changeset
  1456
    def iscensored(self, rev):
76f6ae06ddf5 revlog: add "iscensored()" to revlog public API
Mike Edgar <adgar@google.com>
parents: 24030
diff changeset
  1457
        """Check if a file revision is censored."""
76f6ae06ddf5 revlog: add "iscensored()" to revlog public API
Mike Edgar <adgar@google.com>
parents: 24030
diff changeset
  1458
        return False
76f6ae06ddf5 revlog: add "iscensored()" to revlog public API
Mike Edgar <adgar@google.com>
parents: 24030
diff changeset
  1459
24255
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1460
    def _peek_iscensored(self, baserev, delta, flush):
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1461
        """Quickly check if a delta produces a censored revision."""
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1462
        return False
4bfe9f2d9761 revlog: addgroup checks if incoming deltas add censored revs, sets flag bit
Mike Edgar <adgar@google.com>
parents: 24123
diff changeset
  1463
20074
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1464
    def getstrippoint(self, minlink):
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1465
        """find the minimum rev that must be stripped to strip the linkrev
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1466
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1467
        Returns a tuple containing the minimum rev and a set of all revs that
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1468
        have linkrevs that will be broken by this strip.
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1469
        """
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1470
        brokenrevs = set()
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1471
        strippoint = len(self)
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1472
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1473
        heads = {}
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1474
        futurelargelinkrevs = set()
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1475
        for head in self.headrevs():
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1476
            headlinkrev = self.linkrev(head)
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1477
            heads[head] = headlinkrev
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1478
            if headlinkrev >= minlink:
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1479
                futurelargelinkrevs.add(headlinkrev)
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1480
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1481
        # This algorithm involves walking down the rev graph, starting at the
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1482
        # heads. Since the revs are topologically sorted according to linkrev,
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1483
        # once all head linkrevs are below the minlink, we know there are
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1484
        # no more revs that could have a linkrev greater than minlink.
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1485
        # So we can stop walking.
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1486
        while futurelargelinkrevs:
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1487
            strippoint -= 1
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1488
            linkrev = heads.pop(strippoint)
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1489
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1490
            if linkrev < minlink:
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1491
                brokenrevs.add(strippoint)
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1492
            else:
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1493
                futurelargelinkrevs.remove(linkrev)
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1494
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1495
            for p in self.parentrevs(strippoint):
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1496
                if p != nullrev:
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1497
                    plinkrev = self.linkrev(p)
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1498
                    heads[p] = plinkrev
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1499
                    if plinkrev >= minlink:
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1500
                        futurelargelinkrevs.add(plinkrev)
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1501
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1502
        return strippoint, brokenrevs
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1503
8073
e8a28556a0a8 strip: make repair.strip transactional to avoid repository corruption
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8017
diff changeset
  1504
    def strip(self, minlink, transaction):
5910
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1505
        """truncate the revlog on the first revision with a linkrev >= minlink
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1506
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1507
        This function is called when we're stripping revision minlink and
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1508
        its descendants from the repository.
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1509
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1510
        We have to remove all revisions with linkrev >= minlink, because
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1511
        the equivalent changelog revisions will be renumbered after the
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1512
        strip.
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1513
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1514
        So we truncate the revlog on the first of these revisions, and
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1515
        trust that the caller has saved the revisions that shouldn't be
15827
1dacf7672556 revlog: clarify strip docstring "readd" -> "re-add"
Steven Brown <StevenGBrown@gmail.com>
parents: 15407
diff changeset
  1516
        removed and that it'll re-add them after this truncation.
5910
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
  1517
        """
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1518
        if len(self) == 0:
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1519
            return
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1520
20074
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1521
        rev, _ = self.getstrippoint(minlink)
5fc2ae1c631b strip: add faster revlog strip computation
Durham Goode <durham@fb.com>
parents: 20073
diff changeset
  1522
        if rev == len(self):
5909
f45f7390c1c5 strip: calculate list of extra nodes to save and pass it to changegroupsubset
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5659
diff changeset
  1523
            return
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1524
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1525
        # first truncate the files on disk
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1526
        end = self.start(rev)
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1527
        if not self._inline:
8073
e8a28556a0a8 strip: make repair.strip transactional to avoid repository corruption
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8017
diff changeset
  1528
            transaction.add(self.datafile, end)
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
  1529
            end = rev * self._io.size
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1530
        else:
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
  1531
            end += rev * self._io.size
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
  1532
8073
e8a28556a0a8 strip: make repair.strip transactional to avoid repository corruption
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8017
diff changeset
  1533
        transaction.add(self.indexfile, end)
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1534
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1535
        # then reset internal state in memory to forget those revisions
4984
b4066fcbd6ba revlog: mark cache private
Matt Mackall <mpm@selenic.com>
parents: 4983
diff changeset
  1536
        self._cache = None
23306
f7a42f8e82bd revlog: cache chain info after calculating it for a rev (issue4452)
Siddharth Agarwal <sid0@fb.com>
parents: 23288
diff changeset
  1537
        self._chaininfocache = {}
8650
ef393d6ec030 revlog: refactor chunk cache interface again
Matt Mackall <mpm@selenic.com>
parents: 8643
diff changeset
  1538
        self._chunkclear()
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1539
        for x in xrange(rev, len(self)):
2072
74d3f5336b66 Implement revlogng.
mason@suse.com
parents: 2002
diff changeset
  1540
            del self.nodemap[self.node(x)]
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1541
4979
06abdaf78788 revlog: add a magic null revision to our index
Matt Mackall <mpm@selenic.com>
parents: 4978
diff changeset
  1542
        del self.index[rev:-1]
1535
7ae0ce7a3dc4 Add revlog.strip to truncate away revisions.
mason@suse.com
parents: 1533
diff changeset
  1543
1493
1a216cb4ee64 verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents: 1469
diff changeset
  1544
    def checksize(self):
1a216cb4ee64 verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents: 1469
diff changeset
  1545
        expected = 0
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1546
        if len(self):
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1547
            expected = max(0, self.end(len(self) - 1))
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1548
1494
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1549
        try:
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1550
            f = self.opener(self.datafile)
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1551
            f.seek(0, 2)
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1552
            actual = f.tell()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13284
diff changeset
  1553
            f.close()
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1554
            dd = actual - expected
1494
249ca10d37f4 Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents: 1493
diff changeset
  1555
        except IOError, inst:
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1556
            if inst.errno != errno.ENOENT:
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1557
                raise
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1558
            dd = 0
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1559
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1560
        try:
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1561
            f = self.opener(self.indexfile)
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1562
            f.seek(0, 2)
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1563
            actual = f.tell()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13284
diff changeset
  1564
            f.close()
4977
6cb30bc4ca32 revlog: parse revlogv0 indexes into v1 internally
Matt Mackall <mpm@selenic.com>
parents: 4976
diff changeset
  1565
            s = self._io.size
9029
0001e49f1c11 compat: use // for integer division
Alejandro Santos <alejolp@alejolp.com>
parents: 8658
diff changeset
  1566
            i = max(0, actual // s)
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1567
            di = actual - (i * s)
4982
9672e3c42b0c revlog: change _inline from a function to a variable
Matt Mackall <mpm@selenic.com>
parents: 4981
diff changeset
  1568
            if self._inline:
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1569
                databytes = 0
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1570
                for r in self:
5312
fb070713ff36 revlog: more robust for damaged indexes
Matt Mackall <mpm@selenic.com>
parents: 5007
diff changeset
  1571
                    databytes += max(0, self.length(r))
2073
1e6745f78989 Implement data inlined with the index file
mason@suse.com
parents: 2072
diff changeset
  1572
                dd = 0
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6703
diff changeset
  1573
                di = actual - len(self) * s - databytes
1667
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1574
        except IOError, inst:
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1575
            if inst.errno != errno.ENOENT:
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1576
                raise
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1577
            di = 0
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1578
daff3ef0de8d verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents: 1660
diff changeset
  1579
        return (dd, di)
6891
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1580
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1581
    def files(self):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1582
        res = [self.indexfile]
6891
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1583
        if not self._inline:
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1584
            res.append(self.datafile)
22cb82433842 revlog: add files method
Adrian Buehlmann <adrian@cadifra.com>
parents: 6872
diff changeset
  1585
        return res