/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/weavefile.py

  • Committer: Robert Collins
  • Date: 2010-07-04 06:22:11 UTC
  • mto: This revision was merged to the branch mainline in revision 5332.
  • Revision ID: robertc@robertcollins.net-20100704062211-tk9hw6bnsn5x47fm
``bzrlib.lsprof.profile`` will no longer silently generate bad threaded
profiles when concurrent profile requests are made. Instead the profile
requests will be serialised. Reentrant requests will now deadlock.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
#
 
17
# Author: Martin Pool <mbp@canonical.com>
 
18
 
 
19
 
 
20
 
 
21
 
 
22
"""Store and retrieve weaves in files.
 
23
 
 
24
There is one format marker followed by a blank line, followed by a
 
25
series of version headers, followed by the weave itself.
 
26
 
 
27
Each version marker has
 
28
 
 
29
 'i'   parent version indexes
 
30
 '1'   SHA-1 of text
 
31
 'n'   name
 
32
 
 
33
The inclusions do not need to list versions included by a parent.
 
34
 
 
35
The weave is bracketed by 'w' and 'W' lines, and includes the '{}[]'
 
36
processing instructions.  Lines of text are prefixed by '.' if the
 
37
line contains a newline, or ',' if not.
 
38
"""
 
39
 
 
40
# TODO: When extracting a single version it'd be enough to just pass
 
41
# an iterator returning the weave lines...  We don't really need to
 
42
# deserialize it into memory.
 
43
 
 
44
FORMAT_1 = '# bzr weave file v5\n'
 
45
 
 
46
 
 
47
def write_weave(weave, f, format=None):
 
48
    if format is None or format == 1:
 
49
        return write_weave_v5(weave, f)
 
50
    else:
 
51
        raise ValueError("unknown weave format %r" % format)
 
52
 
 
53
 
 
54
def write_weave_v5(weave, f):
 
55
    """Write weave to file f."""
 
56
    f.write(FORMAT_1)
 
57
 
 
58
    for version, included in enumerate(weave._parents):
 
59
        if included:
 
60
            # mininc = weave.minimal_parents(version)
 
61
            mininc = included
 
62
            f.write('i ')
 
63
            f.write(' '.join(str(i) for i in mininc))
 
64
            f.write('\n')
 
65
        else:
 
66
            f.write('i\n')
 
67
        f.write('1 ' + weave._sha1s[version] + '\n')
 
68
        f.write('n ' + weave._names[version] + '\n')
 
69
        f.write('\n')
 
70
 
 
71
    f.write('w\n')
 
72
 
 
73
    for l in weave._weave:
 
74
        if isinstance(l, tuple):
 
75
            if l[0] == '}':
 
76
                f.write('}\n')
 
77
            else:
 
78
                f.write('%s %d\n' % l)
 
79
        else: # text line
 
80
            if not l:
 
81
                f.write(', \n')
 
82
            elif l[-1] == '\n':
 
83
                f.write('. ' + l)
 
84
            else:
 
85
                f.write(', ' + l + '\n')
 
86
 
 
87
    f.write('W\n')
 
88
 
 
89
 
 
90
 
 
91
def read_weave(f):
 
92
    # FIXME: detect the weave type and dispatch
 
93
    from bzrlib.trace import mutter
 
94
    from weave import Weave
 
95
    w = Weave(getattr(f, 'name', None))
 
96
    _read_weave_v5(f, w)
 
97
    return w
 
98
 
 
99
 
 
100
def _read_weave_v5(f, w):
 
101
    """Private helper routine to read a weave format 5 file into memory.
 
102
 
 
103
    This is only to be used by read_weave and WeaveFile.__init__.
 
104
    """
 
105
    #  200   0   2075.5080   1084.0360   bzrlib.weavefile:104(_read_weave_v5)
 
106
    # +60412 0    366.5900    366.5900   +<method 'readline' of 'file' objects>
 
107
    # +59982 0    320.5280    320.5280   +<method 'startswith' of 'str' objects>
 
108
    # +59363 0    297.8080    297.8080   +<method 'append' of 'list' objects>
 
109
    # replace readline call with iter over all lines ->
 
110
    # safe because we already suck on memory.
 
111
    #  200   0   1492.7170    802.6220   bzrlib.weavefile:104(_read_weave_v5)
 
112
    # +59982 0    329.9100    329.9100   +<method 'startswith' of 'str' objects>
 
113
    # +59363 0    320.2980    320.2980   +<method 'append' of 'list' objects>
 
114
    # replaced startswith with slice lookups:
 
115
    #  200   0    851.7250    501.1120   bzrlib.weavefile:104(_read_weave_v5)
 
116
    # +59363 0    311.8780    311.8780   +<method 'append' of 'list' objects>
 
117
    # +200   0     30.2500     30.2500   +<method 'readlines' of 'file' objects>
 
118
 
 
119
    from weave import WeaveFormatError
 
120
 
 
121
    try:
 
122
        lines = iter(f.readlines())
 
123
    finally:
 
124
        f.close()
 
125
 
 
126
    try:
 
127
        l = lines.next()
 
128
    except StopIteration:
 
129
        raise WeaveFormatError('invalid weave file: no header')
 
130
 
 
131
    if l != FORMAT_1:
 
132
        raise WeaveFormatError('invalid weave file header: %r' % l)
 
133
 
 
134
    ver = 0
 
135
    # read weave header.
 
136
    while True:
 
137
        l = lines.next()
 
138
        if l[0] == 'i':
 
139
            if len(l) > 2:
 
140
                w._parents.append(map(int, l[2:].split(' ')))
 
141
            else:
 
142
                w._parents.append([])
 
143
            l = lines.next()[:-1]
 
144
            w._sha1s.append(l[2:])
 
145
            l = lines.next()
 
146
            name = l[2:-1]
 
147
            w._names.append(name)
 
148
            w._name_map[name] = ver
 
149
            l = lines.next()
 
150
            ver += 1
 
151
        elif l == 'w\n':
 
152
            break
 
153
        else:
 
154
            raise WeaveFormatError('unexpected line %r' % l)
 
155
 
 
156
    # read weave body
 
157
    while True:
 
158
        l = lines.next()
 
159
        if l == 'W\n':
 
160
            break
 
161
        elif '. ' == l[0:2]:
 
162
            w._weave.append(l[2:])  # include newline
 
163
        elif ', ' == l[0:2]:
 
164
            w._weave.append(l[2:-1])        # exclude newline
 
165
        elif l == '}\n':
 
166
            w._weave.append(('}', None))
 
167
        else:
 
168
            w._weave.append((intern(l[0]), int(l[2:])))
 
169
    return w