~bzr-pqm/bzr/bzr.dev

0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
# Author: Martin Pool <mbp@canonical.com>
18
19
20
21
22
"""Store and retrieve weaves in files.
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
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
1083 by Martin Pool
- add space to store revision-id in weave files
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.
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
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.
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
38
"""
39
40
# TODO: When extracting a single version it'd be enough to just pass
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
41
# an iterator returning the weave lines...  We don't really need to
42
# deserialize it into memory.
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
43
1083 by Martin Pool
- add space to store revision-id in weave files
44
FORMAT_1 = '# bzr weave file v5\n'
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
45
46
0.1.74 by Martin Pool
Add format-hidden readwrite methods
47
def write_weave(weave, f, format=None):
48
    if format == None or format == 1:
1083 by Martin Pool
- add space to store revision-id in weave files
49
        return write_weave_v5(weave, f)
0.1.74 by Martin Pool
Add format-hidden readwrite methods
50
    else:
51
        raise ValueError("unknown weave format %r" % format)
52
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
53
1083 by Martin Pool
- add space to store revision-id in weave files
54
def write_weave_v5(weave, f):
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
55
    """Write weave to file f."""
0.1.73 by Martin Pool
Clean up assertions for weavefile
56
    print >>f, FORMAT_1,
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
57
944 by Martin Pool
- refactor member names in Weave code
58
    for version, included in enumerate(weave._parents):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
59
        if included:
892 by Martin Pool
- weave stores only direct parents, and calculates and memoizes expansion as needed
60
            # mininc = weave.minimal_parents(version)
61
            mininc = included
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
62
            print >>f, 'i',
0.1.79 by Martin Pool
In the weavefile, store only the minimum revisions added, not the full
63
            for i in mininc:
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
64
                print >>f, i,
65
            print >>f
66
        else:
67
            print >>f, 'i'
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
68
        print >>f, '1', weave._sha1s[version]
1083 by Martin Pool
- add space to store revision-id in weave files
69
        print >>f, 'n', weave._names[version]
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
70
        print >>f
71
72
    print >>f, 'w'
73
944 by Martin Pool
- refactor member names in Weave code
74
    for l in weave._weave:
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
75
        if isinstance(l, tuple):
76
            assert l[0] in '{}[]'
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
77
            if l[0] == '}':
78
                print >>f, '}'
79
            else:
80
                print >>f, '%s %d' % l
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
81
        else: # text line
82
            if not l:
83
                print >>f, ', '
84
            elif l[-1] == '\n':
0.1.73 by Martin Pool
Clean up assertions for weavefile
85
                assert l.find('\n', 0, -1) == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
86
                print >>f, '.', l,
87
            else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
88
                assert l.find('\n') == -1
0.1.72 by Martin Pool
Go back to weave lines normally having newlines at the end.
89
                print >>f, ',', l
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
90
91
    print >>f, 'W'
92
93
0.1.74 by Martin Pool
Add format-hidden readwrite methods
94
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
95
def read_weave(f):
1563.2.1 by Robert Collins
Merge in a variation of the versionedfile api from versioned-file.
96
    # FIXME: detect the weave type and dispatch
97
    from bzrlib.trace import mutter
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
98
    from weave import Weave
1209 by Martin Pool
- Add Weave._weave_name for debugging purposes
99
    w = Weave(getattr(f, 'name', None))
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
100
    _read_weave_v5(f, w)
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
101
    return w
102
103
1563.2.14 by Robert Collins
Prepare weave store to delegate copy details to the versioned file.
104
def _read_weave_v5(f, w):
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
105
    """Private helper routine to read a weave format 5 file into memory.
106
    
107
    This is only to be used by read_weave and WeaveFile.__init__.
108
    """
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
109
    #  200   0   2075.5080   1084.0360   bzrlib.weavefile:104(_read_weave_v5)
110
    # +60412 0    366.5900    366.5900   +<method 'readline' of 'file' objects>
111
    # +59982 0    320.5280    320.5280   +<method 'startswith' of 'str' objects>
112
    # +59363 0    297.8080    297.8080   +<method 'append' of 'list' objects>
113
    # replace readline call with iter over all lines ->
114
    # safe because we already suck on memory.
115
    #  200   0   1492.7170    802.6220   bzrlib.weavefile:104(_read_weave_v5)
116
    # +59982 0    329.9100    329.9100   +<method 'startswith' of 'str' objects>
117
    # +59363 0    320.2980    320.2980   +<method 'append' of 'list' objects>
118
    # replaced startswith with slice lookups:
119
    #  200   0    851.7250    501.1120   bzrlib.weavefile:104(_read_weave_v5)
120
    # +59363 0    311.8780    311.8780   +<method 'append' of 'list' objects>
121
    # +200   0     30.2500     30.2500   +<method 'readlines' of 'file' objects>
122
                  
1563.2.9 by Robert Collins
Update versionedfile api tests to ensure that data is available after every operation.
123
    from weave import WeaveFormatError
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
124
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
125
    lines = iter(f.readlines())
126
    
127
    l = lines.next()
0.1.73 by Martin Pool
Clean up assertions for weavefile
128
    if l != FORMAT_1:
129
        raise WeaveFormatError('invalid weave file header: %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
130
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
131
    ver = 0
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
132
    # read weave header.
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
133
    while True:
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
134
        l = lines.next()
0.1.90 by Martin Pool
Remove redundant 'v' lines from weave file
135
        if l[0] == 'i':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
136
            if len(l) > 2:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
137
                w._parents.append(map(int, l[2:].split(' ')))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
138
            else:
1079 by Martin Pool
- weavefile can just use lists for read-in ancestry, not frozensets
139
                w._parents.append([])
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
140
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
141
            l = lines.next()[:-1]
142
            assert '1 ' == l[0:2]
0.1.89 by Martin Pool
Store SHA1 in weave file for later verification
143
            w._sha1s.append(l[2:])
144
                
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
145
            l = lines.next()
146
            assert 'n ' == l[0:2]
1083 by Martin Pool
- add space to store revision-id in weave files
147
            name = l[2:-1]
148
            assert name not in w._name_map
149
            w._names.append(name)
150
            w._name_map[name] = ver
151
                
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
152
            l = lines.next()
0.1.93 by Martin Pool
Fix assertion with side effects
153
            assert l == '\n'
1083 by Martin Pool
- add space to store revision-id in weave files
154
155
            ver += 1
0.1.73 by Martin Pool
Clean up assertions for weavefile
156
        elif l == 'w\n':
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
157
            break
158
        else:
0.1.73 by Martin Pool
Clean up assertions for weavefile
159
            raise WeaveFormatError('unexpected line %r' % l)
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
160
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
161
    # read weave body
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
162
    while True:
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
163
        l = lines.next()
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
164
        if l == 'W\n':
165
            break
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
166
        elif '. ' == l[0:2]:
944 by Martin Pool
- refactor member names in Weave code
167
            w._weave.append(l[2:])  # include newline
1596.2.27 by Robert Collins
Note potential improvements in knit adds.
168
        elif ', ' == l[0:2]:
944 by Martin Pool
- refactor member names in Weave code
169
            w._weave.append(l[2:-1])        # exclude newline
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
170
        elif l == '}\n':
171
            w._weave.append(('}', None))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
172
        else:
1075 by Martin Pool
- don't store redundant version number at end of insert blocks
173
            assert l[0] in '{[]', l
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
174
            assert l[1] == ' ', l
944 by Martin Pool
- refactor member names in Weave code
175
            w._weave.append((intern(l[0]), int(l[2:])))
0.1.69 by Martin Pool
Simple text-based format for storing weaves, cleaner than
176
177
    return w
178