~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/versionedfile.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-03-26 03:06:52 UTC
  • mfrom: (3287.5.10 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20080326030652-vgwdkwda9mi8s200
Deprecate VersionedFile.get_parents. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
from cStringIO import StringIO
37
37
 
38
38
from bzrlib.inter import InterObject
 
39
from bzrlib.symbol_versioning import *
39
40
from bzrlib.textmerge import TextMerge
40
41
 
41
42
 
128
129
 
129
130
    def add_lines_with_ghosts(self, version_id, parents, lines,
130
131
        parent_texts=None, nostore_sha=None, random_id=False,
131
 
        check_content=True):
 
132
        check_content=True, left_matching_blocks=None):
132
133
        """Add lines to the versioned file, allowing ghosts to be present.
133
134
        
134
135
        This takes the same parameters as add_lines and returns the same.
135
136
        """
136
137
        self._check_write_ok()
137
138
        return self._add_lines_with_ghosts(version_id, parents, lines,
138
 
            parent_texts, nostore_sha, random_id, check_content)
 
139
            parent_texts, nostore_sha, random_id, check_content, left_matching_blocks)
139
140
 
140
141
    def _add_lines_with_ghosts(self, version_id, parents, lines, parent_texts,
141
 
        nostore_sha, random_id, check_content):
 
142
        nostore_sha, random_id, check_content, left_matching_blocks):
142
143
        """Helper to do class specific add_lines_with_ghosts."""
143
144
        raise NotImplementedError(self.add_lines_with_ghosts)
144
145
 
213
214
    def make_mpdiffs(self, version_ids):
214
215
        """Create multiparent diffs for specified versions."""
215
216
        knit_versions = set()
 
217
        knit_versions.update(version_ids)
 
218
        parent_map = self.get_parent_map(version_ids)
216
219
        for version_id in version_ids:
217
 
            knit_versions.add(version_id)
218
 
            knit_versions.update(self.get_parents(version_id))
 
220
            try:
 
221
                knit_versions.update(parent_map[version_id])
 
222
            except KeyError:
 
223
                raise RevisionNotPresent(version_id, self)
 
224
        # We need to filter out ghosts, because we can't diff against them.
 
225
        knit_versions = set(self.get_parent_map(knit_versions).keys())
219
226
        lines = dict(zip(knit_versions,
220
227
            self._get_lf_split_line_list(knit_versions)))
221
228
        diffs = []
222
229
        for version_id in version_ids:
223
230
            target = lines[version_id]
224
 
            parents = [lines[p] for p in self.get_parents(version_id)]
 
231
            try:
 
232
                parents = [lines[p] for p in parent_map[version_id] if p in
 
233
                    knit_versions]
 
234
            except KeyError:
 
235
                raise RevisionNotPresent(version_id, self)
225
236
            if len(parents) > 0:
226
237
                left_parent_blocks = self._extract_blocks(version_id,
227
238
                                                          parents[0], target)
251
262
        for version, parent_ids, expected_sha1, mpdiff in records:
252
263
            needed_parents.update(p for p in parent_ids
253
264
                                  if not mpvf.has_version(p))
254
 
        for parent_id, lines in zip(needed_parents,
255
 
                                 self._get_lf_split_line_list(needed_parents)):
 
265
        present_parents = set(self.get_parent_map(needed_parents).keys())
 
266
        for parent_id, lines in zip(present_parents,
 
267
                                 self._get_lf_split_line_list(present_parents)):
256
268
            mpvf.add_version(lines, parent_id, [])
257
269
        for (version, parent_ids, expected_sha1, mpdiff), lines in\
258
270
            zip(records, mpvf.get_line_list(versions)):
261
273
                    mpvf.get_diff(parent_ids[0]).num_lines()))
262
274
            else:
263
275
                left_matching_blocks = None
264
 
            _, _, version_text = self.add_lines(version, parent_ids, lines,
265
 
                vf_parents, left_matching_blocks=left_matching_blocks)
 
276
            try:
 
277
                _, _, version_text = self.add_lines_with_ghosts(version,
 
278
                    parent_ids, lines, vf_parents,
 
279
                    left_matching_blocks=left_matching_blocks)
 
280
            except NotImplementedError:
 
281
                # The vf can't handle ghosts, so add lines normally, which will
 
282
                # (reasonably) fail if there are ghosts in the data.
 
283
                _, _, version_text = self.add_lines(version,
 
284
                    parent_ids, lines, vf_parents,
 
285
                    left_matching_blocks=left_matching_blocks)
266
286
            vf_parents[version] = version_text
267
287
        for (version, parent_ids, expected_sha1, mpdiff), sha1 in\
268
288
             zip(records, self.get_sha1s(versions)):
371
391
        """
372
392
        raise NotImplementedError(self.get_graph_with_ghosts)
373
393
 
 
394
    def get_parent_map(self, version_ids):
 
395
        """Get a map of the parents of version_ids.
 
396
 
 
397
        :param version_ids: The version ids to look up parents for.
 
398
        :return: A mapping from version id to parents.
 
399
        """
 
400
        raise NotImplementedError(self.get_parent_map)
 
401
 
 
402
    @deprecated_method(one_four)
374
403
    def get_parents(self, version_id):
375
404
        """Return version names for parents of a version.
376
405
 
377
406
        Must raise RevisionNotPresent if version is not present in
378
407
        file history.
379
408
        """
380
 
        raise NotImplementedError(self.get_parents)
 
409
        try:
 
410
            all = self.get_parent_map([version_id])[version_id]
 
411
        except KeyError:
 
412
            raise errors.RevisionNotPresent(version_id, self)
 
413
        result = []
 
414
        parent_parents = self.get_parent_map(all)
 
415
        for version_id in all:
 
416
            if version_id in parent_parents:
 
417
                result.append(version_id)
 
418
        return result
381
419
 
382
420
    def get_parents_with_ghosts(self, version_id):
383
421
        """Return version names for parents of version_id.
388
426
        Ghosts that are known about will be included in the parent list,
389
427
        but are not explicitly marked.
390
428
        """
391
 
        raise NotImplementedError(self.get_parents_with_ghosts)
 
429
        try:
 
430
            return list(self.get_parent_map([version_id])[version_id])
 
431
        except KeyError:
 
432
            raise errors.RevisionNotPresent(version_id, self)
392
433
 
393
434
    def annotate_iter(self, version_id):
394
435
        """Yield list of (version-id, line) pairs for the specified
451
492
            The order is undefined, allowing for different optimisations in
452
493
            the underlying implementation.
453
494
        """
454
 
        for version_id in version_ids:
455
 
            try:
456
 
                yield version_id, tuple(self.get_parents(version_id))
457
 
            except errors.RevisionNotPresent:
458
 
                pass
 
495
        return self.get_parent_map(version_ids).iteritems()
459
496
 
460
497
    def transaction_finished(self):
461
498
        """The transaction that this file was opened in has finished.
547
584
            raise ValueError('Parents may not be None')
548
585
        if lines is None:
549
586
            raise ValueError('Lines may not be None')
550
 
        self._parents[version_id] = parents
 
587
        self._parents[version_id] = tuple(parents)
551
588
        self._lines[version_id] = lines
552
589
 
553
590
    def get_lines(self, version_id):
590
627
            ancestry.update(self.get_ancestry(parent, topo_sorted=False))
591
628
        return ancestry
592
629
 
593
 
    def get_parents(self, version_id):
594
 
        """See VersionedFile.get_parents"""
595
 
        parents = self._parents.get(version_id)
596
 
        if parents is not None:
597
 
            return parents
 
630
    def get_parent_map(self, version_ids):
 
631
        """See VersionedFile.get_parent_map"""
 
632
        result = {}
 
633
        pending = set(version_ids)
 
634
        for key in version_ids:
 
635
            try:
 
636
                result[key] = self._parents[key]
 
637
            except KeyError:
 
638
                pass
 
639
        pending = pending - set(result.keys())
598
640
        for versionedfile in self.fallback_versionedfiles:
599
 
            try:
600
 
                return versionedfile.get_parents(version_id)
601
 
            except errors.RevisionNotPresent:
602
 
                continue
603
 
        else:
604
 
            raise errors.RevisionNotPresent(version_id, self._file_id)
 
641
            parents = versionedfile.get_parent_map(pending)
 
642
            result.update(parents)
 
643
            pending = pending - set(parents.keys())
 
644
            if not pending:
 
645
                return result
 
646
        return result
605
647
 
606
648
    def _get_graph(self):
607
649
        from bzrlib.graph import (
752
794
            # memory pressure reduction. RBC 20060313
753
795
            # pb.update('Converting versioned data', 0, len(order))
754
796
            total = len(order)
 
797
            parent_map = self.source.get_parent_map(order)
755
798
            for index, version in enumerate(order):
756
799
                pb.update('Converting versioned data', index, total)
757
800
                _, _, parent_text = target.add_lines(version,
758
 
                                               self.source.get_parents(version),
 
801
                                               parent_map[version],
759
802
                                               self.source.get_lines(version),
760
803
                                               parent_texts=parent_texts)
761
804
                parent_texts[version] = parent_text