/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: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005-2010 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
"""Store and retrieve weaves in files.
 
20
 
 
21
There is one format marker followed by a blank line, followed by a
 
22
series of version headers, followed by the weave itself.
 
23
 
 
24
Each version marker has
 
25
 
 
26
 'i'   parent version indexes
 
27
 '1'   SHA-1 of text
 
28
 'n'   name
 
29
 
 
30
The inclusions do not need to list versions included by a parent.
 
31
 
 
32
The weave is bracketed by 'w' and 'W' lines, and includes the '{}[]'
 
33
processing instructions.  Lines of text are prefixed by '.' if the
 
34
line contains a newline, or ',' if not.
 
35
"""
 
36
 
 
37
from __future__ import absolute_import
 
38
 
 
39
# TODO: When extracting a single version it'd be enough to just pass
 
40
# an iterator returning the weave lines...  We don't really need to
 
41
# deserialize it into memory.
 
42
 
 
43
FORMAT_1 = '# bzr weave file v5\n'
 
44
 
 
45
 
 
46
def write_weave(weave, f, format=None):
 
47
    if format is None or format == 1:
 
48
        return write_weave_v5(weave, f)
 
49
    else:
 
50
        raise ValueError("unknown weave format %r" % format)
 
51
 
 
52
 
 
53
def write_weave_v5(weave, f):
 
54
    """Write weave to file f."""
 
55
    f.write(FORMAT_1)
 
56
 
 
57
    for version, included in enumerate(weave._parents):
 
58
        if included:
 
59
            # mininc = weave.minimal_parents(version)
 
60
            mininc = included
 
61
            f.write('i ')
 
62
            f.write(' '.join(str(i) for i in mininc))
 
63
            f.write('\n')
 
64
        else:
 
65
            f.write('i\n')
 
66
        f.write('1 ' + weave._sha1s[version] + '\n')
 
67
        f.write('n ' + weave._names[version] + '\n')
 
68
        f.write('\n')
 
69
 
 
70
    f.write('w\n')
 
71
 
 
72
    for l in weave._weave:
 
73
        if isinstance(l, tuple):
 
74
            if l[0] == '}':
 
75
                f.write('}\n')
 
76
            else:
 
77
                f.write('%s %d\n' % l)
 
78
        else: # text line
 
79
            if not l:
 
80
                f.write(', \n')
 
81
            elif l[-1] == '\n':
 
82
                f.write('. ' + l)
 
83
            else:
 
84
                f.write(', ' + l + '\n')
 
85
 
 
86
    f.write('W\n')
 
87
 
 
88
 
 
89
 
 
90
def read_weave(f):
 
91
    # FIXME: detect the weave type and dispatch
 
92
    from bzrlib.weave import Weave
 
93
    w = Weave(getattr(f, 'name', None))
 
94
    _read_weave_v5(f, w)
 
95
    return w
 
96
 
 
97
 
 
98
def _read_weave_v5(f, w):
 
99
    """Private helper routine to read a weave format 5 file into memory.
 
100
 
 
101
    This is only to be used by read_weave and WeaveFile.__init__.
 
102
    """
 
103
    #  200   0   2075.5080   1084.0360   bzrlib.weavefile:104(_read_weave_v5)
 
104
    # +60412 0    366.5900    366.5900   +<method 'readline' of 'file' objects>
 
105
    # +59982 0    320.5280    320.5280   +<method 'startswith' of 'str' objects>
 
106
    # +59363 0    297.8080    297.8080   +<method 'append' of 'list' objects>
 
107
    # replace readline call with iter over all lines ->
 
108
    # safe because we already suck on memory.
 
109
    #  200   0   1492.7170    802.6220   bzrlib.weavefile:104(_read_weave_v5)
 
110
    # +59982 0    329.9100    329.9100   +<method 'startswith' of 'str' objects>
 
111
    # +59363 0    320.2980    320.2980   +<method 'append' of 'list' objects>
 
112
    # replaced startswith with slice lookups:
 
113
    #  200   0    851.7250    501.1120   bzrlib.weavefile:104(_read_weave_v5)
 
114
    # +59363 0    311.8780    311.8780   +<method 'append' of 'list' objects>
 
115
    # +200   0     30.2500     30.2500   +<method 'readlines' of 'file' objects>
 
116
 
 
117
    from bzrlib.weave import WeaveFormatError
 
118
 
 
119
    try:
 
120
        lines = iter(f.readlines())
 
121
    finally:
 
122
        f.close()
 
123
 
 
124
    try:
 
125
        l = lines.next()
 
126
    except StopIteration:
 
127
        raise WeaveFormatError('invalid weave file: no header')
 
128
 
 
129
    if l != FORMAT_1:
 
130
        raise WeaveFormatError('invalid weave file header: %r' % l)
 
131
 
 
132
    ver = 0
 
133
    # read weave header.
 
134
    while True:
 
135
        l = lines.next()
 
136
        if l[0] == 'i':
 
137
            if len(l) > 2:
 
138
                w._parents.append(map(int, l[2:].split(' ')))
 
139
            else:
 
140
                w._parents.append([])
 
141
            l = lines.next()[:-1]
 
142
            w._sha1s.append(l[2:])
 
143
            l = lines.next()
 
144
            name = l[2:-1]
 
145
            w._names.append(name)
 
146
            w._name_map[name] = ver
 
147
            l = lines.next()
 
148
            ver += 1
 
149
        elif l == 'w\n':
 
150
            break
 
151
        else:
 
152
            raise WeaveFormatError('unexpected line %r' % l)
 
153
 
 
154
    # read weave body
 
155
    while True:
 
156
        l = lines.next()
 
157
        if l == 'W\n':
 
158
            break
 
159
        elif '. ' == l[0:2]:
 
160
            w._weave.append(l[2:])  # include newline
 
161
        elif ', ' == l[0:2]:
 
162
            w._weave.append(l[2:-1])        # exclude newline
 
163
        elif l == '}\n':
 
164
            w._weave.append(('}', None))
 
165
        else:
 
166
            w._weave.append((intern(l[0]), int(l[2:])))
 
167
    return w