~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/weave.py

  • Committer: Martin Pool
  • Date: 2005-09-05 09:11:03 UTC
  • Revision ID: mbp@sourcefrog.net-20050905091103-1e51e146be0f08b4
- add test for deserialization from a canned XML inventory

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
 
89
89
import sha
90
90
 
91
 
from cStringIO import StringIO
92
 
 
93
 
from bzrlib.osutils import sha_strings
94
91
 
95
92
 
96
93
class WeaveError(Exception):
184
181
 
185
182
    _name_map
186
183
        For each name, the version number.
187
 
 
188
 
    _weave_name
189
 
        Descriptive name of this weave; typically the filename if known.
190
 
        Set by read_weave.
191
184
    """
192
185
 
193
 
    __slots__ = ['_weave', '_parents', '_sha1s', '_names', '_name_map',
194
 
                 '_weave_name']
 
186
    __slots__ = ['_weave', '_parents', '_sha1s', '_names', '_name_map']
195
187
    
196
 
    def __init__(self, weave_name=None):
 
188
    def __init__(self):
197
189
        self._weave = []
198
190
        self._parents = []
199
191
        self._sha1s = []
200
192
        self._names = []
201
193
        self._name_map = {}
202
 
        self._weave_name = weave_name
203
194
 
204
195
 
205
196
    def __eq__(self, other):
214
205
        return not self.__eq__(other)
215
206
 
216
207
 
217
 
    def maybe_lookup(self, name_or_index):
218
 
        """Convert possible symbolic name to index, or pass through indexes."""
219
 
        if isinstance(name_or_index, (int, long)):
220
 
            return name_or_index
221
 
        else:
222
 
            return self.lookup(name_or_index)
223
 
 
224
 
        
225
208
    def lookup(self, name):
226
 
        """Convert symbolic version name to index."""
227
209
        try:
228
210
            return self._name_map[name]
229
211
        except KeyError:
230
 
            raise WeaveError("name %r not present in weave %r" %
231
 
                             (name, self._weave_name))
232
 
 
233
 
 
234
 
    def idx_to_name(self, version):
235
 
        return self._names[version]
236
 
 
237
 
 
238
 
    def _check_repeated_add(self, name, parents, text):
239
 
        """Check that a duplicated add is OK.
240
 
 
241
 
        If it is, return the (old) index; otherwise raise an exception.
242
 
        """
243
 
        idx = self.lookup(name)
244
 
        if sorted(self._parents[idx]) != sorted(parents):
245
 
            raise WeaveError("name \"%s\" already present in weave "
246
 
                             "with different parents" % name)
247
 
        new_sha1 = sha_strings(text)
248
 
        if new_sha1 != self._sha1s[idx]:
249
 
            raise WeaveError("name \"%s\" already present in weave "
250
 
                             "with different text" % name)            
251
 
        return idx
252
 
        
 
212
            raise WeaveError("name %s not present in weave" % name)
253
213
 
254
214
        
255
215
    def add(self, name, parents, text):
269
229
 
270
230
        assert isinstance(name, basestring)
271
231
        if name in self._name_map:
272
 
            return self._check_repeated_add(name, parents, text)
273
 
 
274
 
        parents = map(self.maybe_lookup, parents)
 
232
            raise WeaveError("name %r already present in weave" % name)
 
233
        
275
234
        self._check_versions(parents)
276
235
        ## self._check_lines(text)
277
236
        new_version = len(self._parents)
278
237
 
279
 
        sha1 = sha_strings(text)
 
238
        s = sha.new()
 
239
        map(s.update, text)
 
240
        sha1 = s.hexdigest()
 
241
        del s
280
242
 
281
243
        # if we abort after here the (in-memory) weave will be corrupt because only
282
244
        # some fields are updated
388
350
            raise ValueError("version %d not present in weave" % v)
389
351
 
390
352
 
391
 
    def parents(self, version):
392
 
        return self._parents[version]
393
 
 
394
 
 
395
353
    def minimal_parents(self, version):
396
354
        """Find the minimal set of parents for the version."""
397
355
        included = self._parents[version]
435
393
                raise IndexError("invalid version number %r" % i)
436
394
 
437
395
    
438
 
    def annotate(self, name_or_index):
439
 
        return list(self.annotate_iter(name_or_index))
440
 
 
441
 
 
442
 
    def annotate_iter(self, name_or_index):
 
396
    def annotate(self, index):
 
397
        return list(self.annotate_iter(index))
 
398
 
 
399
 
 
400
    def annotate_iter(self, version):
443
401
        """Yield list of (index-id, line) pairs for the specified version.
444
402
 
445
403
        The index indicates when the line originated in the weave."""
446
 
        incls = [self.maybe_lookup(name_or_index)]
447
 
        for origin, lineno, text in self._extract(incls):
 
404
        for origin, lineno, text in self._extract([version]):
448
405
            yield origin, text
449
406
 
450
407
 
494
451
 
495
452
        The set typically but not necessarily corresponds to a version.
496
453
        """
497
 
        for i in versions:
498
 
            if not isinstance(i, int):
499
 
                raise ValueError(i)
500
 
            
501
454
        included = self.inclusions(versions)
502
455
 
503
456
        istack = []
548
501
    
549
502
 
550
503
 
551
 
    def get_iter(self, name_or_index):
 
504
    def get_iter(self, version):
552
505
        """Yield lines for the specified version."""
553
 
        incls = [self.maybe_lookup(name_or_index)]
554
 
        for origin, lineno, line in self._extract(incls):
 
506
        for origin, lineno, line in self._extract([version]):
555
507
            yield line
556
508
 
557
509
 
558
 
    def get_text(self, version):
559
 
        assert isinstance(version, int)
560
 
        s = StringIO()
561
 
        s.writelines(self.get_iter(version))
562
 
        return s.getvalue()
563
 
 
564
 
 
565
 
    def get(self, name_or_index):
566
 
        return list(self.get_iter(name_or_index))
 
510
    def get(self, index):
 
511
        return list(self.get_iter(index))
567
512
 
568
513
 
569
514
    def mash_iter(self, included):