mercurial/filelog.py
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Thu, 08 Dec 2005 15:12:02 +0100
changeset 1677 11d12bd6e1dc
parent 1541 bf4e7ef08741
child 1678 b345cc4c22c0
permissions -rw-r--r--
cleanup of revlog.group when repository is local revlog.group cached every chunk from the revlog, the behaviour was needed to minimize the roundtrip with old-http. The patch export the information that the repository is local or not from the repository object down to the revlog. Then it uses the workaround for old-http only if the repository is non-local. The memory used server side when pulling goes down to less than 30Mo maximum whereas without the patch more than 160Mo was used when cloning the linux kernel repository. The time used by cloning is roughly the same (although some caching could be implemented if needed): before 110.25user 20.90system 2:52.00elapsed 76%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+708707minor)pagefaults 0swaps after 112.85user 22.98system 2:50.66elapsed 79%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+862862minor)pagefaults 0swaps
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
     1
# filelog.py - file history class for mercurial
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     2
#
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     3
# Copyright 2005 Matt Mackall <mpm@selenic.com>
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     4
#
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     7
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
     8
import os
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
     9
from revlog import *
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
    10
from demandload import *
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
    11
demandload(globals(), "bdiff")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    12
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    13
class filelog(revlog):
1677
11d12bd6e1dc cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1541
diff changeset
    14
    def __init__(self, opener, path, local=True):
144
ea9188538222 Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents: 140
diff changeset
    15
        revlog.__init__(self, opener,
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
    16
                        os.path.join("data", self.encodedir(path + ".i")),
1677
11d12bd6e1dc cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1541
diff changeset
    17
                        os.path.join("data", self.encodedir(path + ".d")),
11d12bd6e1dc cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1541
diff changeset
    18
                        local=local)
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
    19
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
    20
    # This avoids a collision between a file named foo and a dir named
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
    21
    # foo.i or foo.d
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
    22
    def encodedir(self, path):
856
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
    23
        return (path
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
    24
                .replace(".hg/", ".hg.hg/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
    25
                .replace(".i/", ".i.hg/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
    26
                .replace(".d/", ".d.hg/"))
786
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
    27
902b12d55751 Fix the directory and revlog collision problem
mpm@selenic.com
parents: 785
diff changeset
    28
    def decodedir(self, path):
856
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
    29
        return (path
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
    30
                .replace(".d.hg/", ".d/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
    31
                .replace(".i.hg/", ".i/")
fbe964ae7325 Fixed encoding of directories ending in .d or .i:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 839
diff changeset
    32
                .replace(".hg.hg/", ".hg/"))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    33
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    34
    def read(self, node):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    35
        t = self.revision(node)
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
    36
        if not t.startswith('\1\n'):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    37
            return t
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    38
        s = t.find('\1\n', 2)
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    39
        return t[s+2:]
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    40
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    41
    def readmeta(self, node):
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    42
        t = self.revision(node)
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
    43
        if not t.startswith('\1\n'):
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
    44
            return {}
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    45
        s = t.find('\1\n', 2)
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    46
        mt = t[2:s]
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
    47
        m = {}
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    48
        for l in mt.splitlines():
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    49
            k, v = l.split(": ", 1)
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    50
            m[k] = v
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    51
        return m
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    52
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    53
    def add(self, text, meta, transaction, link, p1=None, p2=None):
686
d7d68d27ebe5 Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents: 681
diff changeset
    54
        if meta or text.startswith('\1\n'):
360
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    55
            mt = ""
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    56
            if meta:
10519e4cbd02 filelog: add metadata support
mpm@selenic.com
parents: 358
diff changeset
    57
                mt = [ "%s: %s\n" % (k, v) for k,v in meta.items() ]
1540
8ca9f5b17257 minor optimization: save some string trash
twaldmann@thinkmo.de
parents: 1117
diff changeset
    58
            text = "\1\n%s\1\n%s" % ("".join(mt), text)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    59
        return self.addrevision(text, transaction, link, p1, p2)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    60
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
    61
    def renamed(self, node):
1541
bf4e7ef08741 fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents: 1540
diff changeset
    62
        if 0 and self.parents(node)[0] != nullid: # XXX
1116
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
    63
            return False
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
    64
        m = self.readmeta(node)
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
    65
        if m and m.has_key("copy"):
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
    66
            return (m["copy"], bin(m["copyrev"]))
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
    67
        return False
0cdd73b0767c Add some rename debugging support
mpm@selenic.com
parents: 1089
diff changeset
    68
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
    69
    def annotate(self, node):
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    70
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    71
        def decorate(text, rev):
436
6aeb4fee51f6 Optimize annotate a bit
mpm@selenic.com
parents: 434
diff changeset
    72
            return ([rev] * len(text.splitlines()), text)
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    73
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    74
        def pair(parent, child):
436
6aeb4fee51f6 Optimize annotate a bit
mpm@selenic.com
parents: 434
diff changeset
    75
            for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]):
471
4c7f687e4313 Minor annotate performance tweaks
mpm@selenic.com
parents: 454
diff changeset
    76
                child[0][b1:b2] = parent[0][a1:a2]
4c7f687e4313 Minor annotate performance tweaks
mpm@selenic.com
parents: 454
diff changeset
    77
            return child
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    78
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
    79
        # find all ancestors
216
201115f2859b hg annotate: actually annotate the given version
mpm@selenic.com
parents: 210
diff changeset
    80
        needed = {node:1}
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    81
        visit = [node]
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    82
        while visit:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    83
            n = visit.pop(0)
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    84
            for p in self.parents(n):
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    85
                if p not in needed:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    86
                    needed[p] = 1
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    87
                    visit.append(p)
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
    88
                else:
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
    89
                    # count how many times we'll use this
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
    90
                    needed[p] += 1
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    91
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
    92
        # sort by revision which is a topological order
471
4c7f687e4313 Minor annotate performance tweaks
mpm@selenic.com
parents: 454
diff changeset
    93
        visit = [ (self.rev(n), n) for n in needed.keys() ]
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    94
        visit.sort()
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    95
        hist = {}
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    96
471
4c7f687e4313 Minor annotate performance tweaks
mpm@selenic.com
parents: 454
diff changeset
    97
        for r,n in visit:
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    98
            curr = decorate(self.read(n), self.linkrev(n))
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
    99
            for p in self.parents(n):
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
   100
                if p != nullid:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
   101
                    curr = pair(hist[p], curr)
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
   102
                    # trim the history of unneeded revs
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
   103
                    needed[p] -= 1
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
   104
                    if not needed[p]:
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
   105
                        del hist[p]
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
   106
            hist[n] = curr
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
   107
436
6aeb4fee51f6 Optimize annotate a bit
mpm@selenic.com
parents: 434
diff changeset
   108
        return zip(hist[n][0], hist[n][1].splitlines(1))