Rev 3364: Deprecate VersionedFile.join. in http://people.ubuntu.com/~robertc/baz2.0/versioned_files
Robert Collins
robertc at robertcollins.net
Tue Apr 29 06:27:13 BST 2008
At http://people.ubuntu.com/~robertc/baz2.0/versioned_files
------------------------------------------------------------
revno: 3364
revision-id: robertc at robertcollins.net-20080429052708-ep87a2mxn2d7i8lr
parent: robertc at robertcollins.net-20080429001045-a2zfomf1iy12eu3k
committer: Robert Collins <robertc at robertcollins.net>
branch nick: data_stream_revamp
timestamp: Tue 2008-04-29 15:27:08 +1000
message:
Deprecate VersionedFile.join.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/symbol_versioning.py symbol_versioning.py-20060105104851-9ecf8af605d15a80
bzrlib/tests/interversionedfile_implementations/test_join.py test_join.py-20060302012326-9b5e9b0f0a03fedc
bzrlib/tests/test_knit.py test_knit.py-20051212171302-95d4c00dd5f11f2b
bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
bzrlib/tests/test_weave.py testknit.py-20050627023648-9833cc5562ffb785
bzrlib/versionedfile.py versionedfile.py-20060222045106-5039c71ee3b65490
=== modified file 'NEWS'
--- a/NEWS 2008-04-28 05:54:46 +0000
+++ b/NEWS 2008-04-29 05:27:08 +0000
@@ -66,6 +66,12 @@
Repository.item_keys_introduced_by() no longer take read locks.
(Aaron Bentley)
+ * ``VersionedFile.join`` is deprecated. This method required local
+ instances of both versioned file objects and was thus hostile to being
+ used for streaming from a smart server. The new get_record_stream and
+ insert_record_stream are meant to efficiently replace this method.
+ (Robert Collins)
+
bzr 1.4rc2 2008-04-21
---------------------
=== modified file 'bzrlib/symbol_versioning.py'
--- a/bzrlib/symbol_versioning.py 2008-03-20 00:43:25 +0000
+++ b/bzrlib/symbol_versioning.py 2008-04-29 05:27:08 +0000
@@ -46,6 +46,7 @@
'one_two',
'one_three',
'one_four',
+ 'one_five',
]
from warnings import warn
@@ -73,6 +74,7 @@
one_two = "%s was deprecated in version 1.2."
one_three = "%s was deprecated in version 1.3."
one_four = "%s was deprecated in version 1.4."
+one_five = "%s was deprecated in version 1.5."
def set_warning_method(method):
"""Set the warning method to be used by this module.
=== modified file 'bzrlib/tests/interversionedfile_implementations/test_join.py'
--- a/bzrlib/tests/interversionedfile_implementations/test_join.py 2008-03-27 04:54:12 +0000
+++ b/bzrlib/tests/interversionedfile_implementations/test_join.py 2008-04-29 05:27:08 +0000
@@ -18,6 +18,7 @@
import bzrlib.errors as errors
+from bzrlib.symbol_versioning import one_five
from bzrlib.tests import TestCaseWithTransport
from bzrlib.transport import get_transport
import bzrlib.versionedfile as versionedfile
@@ -44,7 +45,7 @@
f1.add_lines('r0', [], ['a\n', 'b\n'])
f1.add_lines('r1', ['r0'], ['c\n', 'b\n'])
f2 = self.get_target()
- f2.join(f1, None)
+ self.applyDeprecated(one_five, f2.join, f1, None)
def verify_file(f):
self.assertTrue(f.has_version('r0'))
self.assertTrue(f.has_version('r1'))
@@ -52,7 +53,7 @@
verify_file(self.get_target())
self.assertRaises(errors.RevisionNotPresent,
- f2.join, f1, version_ids=['r3'])
+ self.applyDeprecated, one_five, f2.join, f1, version_ids=['r3'])
def test_gets_expected_inter_worker(self):
source = self.get_source()
@@ -72,7 +73,8 @@
source.add_lines('ancestorright', ['base'], [])
source.add_lines('namedleft', ['ancestorleft'], [])
source.add_lines('namedright', ['ancestorright'], [])
- target.join(source, version_ids=['namedleft', 'namedright'])
+ self.applyDeprecated(one_five, target.join, source,
+ version_ids=['namedleft', 'namedright'])
self.assertFalse(target.has_version('sibling'))
self.assertTrue(target.has_version('ancestorleft'))
self.assertTrue(target.has_version('ancestorright'))
@@ -88,7 +90,7 @@
w1.add_lines('v-3', ['v-1'], ['line 1\n'])
w2.add_lines('v-3', ['v-2'], ['line 1\n'])
try:
- w1.join(w2)
+ self.applyDeprecated(one_five, w1.join, w2)
except errors.WeaveParentMismatch:
# Acceptable behaviour:
return
@@ -115,7 +117,7 @@
"""Reweave adding empty weave"""
wb = self.get_target()
w1 = self.build_weave1()
- w1.join(wb)
+ self.applyDeprecated(one_five, w1.join, wb)
self.verify_weave1(w1)
def verify_weave1(self, w1):
@@ -136,7 +138,7 @@
t = self.get_target()
t.add_lines('base', [], [])
t.add_lines('text', ['base'], [])
- t.join(s)
+ self.applyDeprecated(one_five, t.join, s)
self.assertEqual({'text':('base',)}, t.get_parent_map(['text']))
def test_join_with_ghosts(self):
@@ -159,7 +161,7 @@
wb.add_lines('v1', [], ['hello\n'])
wb.add_lines('v2', ['v1', 'x1'], ['hello\n', 'world\n'])
try:
- w1.join(wb)
+ self.applyDeprecated(one_five, w1.join, wb)
except errors.WeaveParentMismatch:
# Acceptable behaviour:
return
@@ -176,7 +178,8 @@
wb.add_lines('x1', [], ['line from x1\n'])
wb.add_lines('v1', [], ['hello\n'])
wb.add_lines('v2', ['v1', 'x1'], ['hello\n', 'world\n'])
- w1.join(wb, version_ids=['x1', 'z1'], ignore_missing=True)
+ self.applyDeprecated(one_five, w1.join, wb, version_ids=['x1', 'z1'],
+ ignore_missing=True)
eq = self.assertEquals
eq(sorted(w1.versions()), ['v1', 'v2', 'v3', 'x1'])
eq(w1.get_text('x1'), 'line from x1\n')
@@ -213,7 +216,7 @@
# The target does not support ghosts; the test is irrelevant.
return
try:
- source.join(target)
+ self.applyDeprecated(one_five, source.join, target)
except errors.RevisionNotPresent:
return
# legacy apis should behave
@@ -228,7 +231,7 @@
# if we add something that is fills out what is a ghost, then
# when joining into a ghost aware join it should flesh out the ghosts.
source.add_lines('base', [], [])
- target.join(source, version_ids=['base'])
+ self.applyDeprecated(one_five, target.join, source, version_ids=['base'])
self.assertEqual(['base', 'notbase'], target.get_ancestry(['notbase']))
self.assertEqual({'base':(),
'notbase':('base', ),
@@ -251,7 +254,7 @@
source.add_lines('inherit_me', [], ['b\n'])
source.add_lines('select_me', ['inherit_me'], ['b\n'])
target = self.get_target()
- target.join(source, version_ids=['select_me'])
+ self.applyDeprecated(one_five, target.join, source, version_ids=['select_me'])
self.assertEqual(['inherit_me', 'select_me'], target.versions())
def test_join_odd_records(self):
@@ -267,7 +270,7 @@
source.add_lines('4', ['2'], ['1st\n'])
source.add_lines('5', ['3'], ['1st\n', '2nd\n', '3rd\n'])
target = self.get_target()
- target.join(source, version_ids=['1', '3', '5'])
+ self.applyDeprecated(one_five, target.join, source, version_ids=['1', '3', '5'])
target = self.get_target(create=False)
self.assertEqual(set(['1', '3', '5']), set(target.versions()))
self.assertEqual(3, len(target.versions()))
=== modified file 'bzrlib/tests/test_knit.py'
--- a/bzrlib/tests/test_knit.py 2008-04-29 00:10:45 +0000
+++ b/bzrlib/tests/test_knit.py 2008-04-29 05:27:08 +0000
@@ -1293,39 +1293,6 @@
self.assertEquals(origins[1], ('text-1', 'b\n'))
self.assertEquals(origins[2], ('text-1', 'c\n'))
- def _test_join_with_factories(self, k1_factory, k2_factory):
- k1 = make_file_knit('test1', get_transport('.'), factory=k1_factory, create=True)
- k1.add_lines('text-a', [], ['a1\n', 'a2\n', 'a3\n'])
- k1.add_lines('text-b', ['text-a'], ['a1\n', 'b2\n', 'a3\n'])
- k1.add_lines('text-c', [], ['c1\n', 'c2\n', 'c3\n'])
- k1.add_lines('text-d', ['text-c'], ['c1\n', 'd2\n', 'd3\n'])
- k1.add_lines('text-m', ['text-b', 'text-d'], ['a1\n', 'b2\n', 'd3\n'])
- k2 = make_file_knit('test2', get_transport('.'), factory=k2_factory, create=True)
- count = k2.join(k1, version_ids=['text-m'])
- self.assertEquals(count, 5)
- self.assertTrue(k2.has_version('text-a'))
- self.assertTrue(k2.has_version('text-c'))
- origins = k2.annotate('text-m')
- self.assertEquals(origins[0], ('text-a', 'a1\n'))
- self.assertEquals(origins[1], ('text-b', 'b2\n'))
- self.assertEquals(origins[2], ('text-d', 'd3\n'))
-
- def test_knit_join_plain_to_plain(self):
- """Test joining a plain knit with a plain knit."""
- self._test_join_with_factories(KnitPlainFactory(), KnitPlainFactory())
-
- def test_knit_join_anno_to_anno(self):
- """Test joining an annotated knit with an annotated knit."""
- self._test_join_with_factories(None, None)
-
- def test_knit_join_anno_to_plain(self):
- """Test joining an annotated knit with a plain knit."""
- self._test_join_with_factories(None, KnitPlainFactory())
-
- def test_knit_join_plain_to_anno(self):
- """Test joining a plain knit with an annotated knit."""
- self._test_join_with_factories(KnitPlainFactory(), None)
-
def test_reannotate(self):
k1 = make_file_knit('knit1', get_transport('.'),
factory=KnitAnnotateFactory(), create=True)
@@ -1336,7 +1303,8 @@
k2 = make_file_knit('test2', get_transport('.'),
factory=KnitAnnotateFactory(), create=True)
- k2.join(k1, version_ids=['text-b'])
+ k2.insert_record_stream(k1.get_record_stream(k1.versions(),
+ 'unordered', False))
# 2
k1.add_lines('text-X', ['text-b'], ['a\n', 'b\n'])
@@ -1346,7 +1314,8 @@
k2.add_lines('text-Y', ['text-b'], ['b\n', 'c\n'])
# test-c will have index 3
- k1.join(k2, version_ids=['text-c'])
+ k1.insert_record_stream(k2.get_record_stream(['text-c'],
+ 'unordered', False))
lines = k1.get_lines('text-c')
self.assertEquals(lines, ['z\n', 'c\n'])
@@ -2817,7 +2786,8 @@
target_knit = self.make_test_knit(name='annotated', annotate=True)
source_knit.add_lines("A", [], ["Foo\n"])
# Give the target A, so we can try to thunk across to it.
- target_knit.join(source_knit)
+ target_knit.insert_record_stream(source_knit.get_record_stream(['A'],
+ 'unordered', False))
index, access = self.get_index_access(target_knit,
source_knit.get_data_stream([]))
raw_data = list(access.get_raw_records([(True, "A", None, None)]))[0]
=== modified file 'bzrlib/tests/test_versionedfile.py'
--- a/bzrlib/tests/test_versionedfile.py 2008-04-24 07:28:18 +0000
+++ b/bzrlib/tests/test_versionedfile.py 2008-04-29 05:27:08 +0000
@@ -40,7 +40,7 @@
KnitAnnotateFactory,
KnitPlainFactory,
)
-from bzrlib.symbol_versioning import one_four
+from bzrlib.symbol_versioning import one_four, one_five
from bzrlib.tests import TestCaseWithMemoryTransport, TestSkipped
from bzrlib.tests.http_utils import TestCaseWithWebserver
from bzrlib.trace import mutter
@@ -226,6 +226,16 @@
set([('base',), ('left',), ('right',), ('merged',), ('or',)]),
seen)
+ def test_filter_absent_records(self):
+ """Requested missing records can be filter trivially."""
+ f, parents = get_diamond_vf(self.get_file())
+ entries = f.get_record_stream(['merged', 'left', 'right', 'extra', 'base'],
+ 'unordered', False)
+ seen = set()
+ self.capture_stream(f, versionedfile.filter_absent(entries), seen.add,
+ parents)
+ self.assertEqual(set([('base',), ('left',), ('right',), ('merged',)]),
+ seen)
def test_insert_record_stream_empty(self):
"""Inserting an empty record stream should work."""
@@ -591,7 +601,8 @@
self._transaction = 'after'
self.assertRaises(errors.OutSideTransaction, f.add_lines, '', [], [])
self.assertRaises(errors.OutSideTransaction, f.add_lines_with_ghosts, '', [], [])
- self.assertRaises(errors.OutSideTransaction, f.join, '')
+ self.assertRaises(errors.OutSideTransaction, self.applyDeprecated,
+ one_five, f.join, '')
def test_clone_text(self):
f = self.get_file()
@@ -926,7 +937,8 @@
'base',
[],
[])
- self.assertRaises(errors.ReadOnlyError, vf.join, 'base')
+ self.assertRaises(errors.ReadOnlyError, self.applyDeprecated, one_five,
+ vf.join, 'base')
def test_get_sha1s(self):
# check the sha1 data is available
=== modified file 'bzrlib/tests/test_weave.py'
--- a/bzrlib/tests/test_weave.py 2008-04-08 03:39:43 +0000
+++ b/bzrlib/tests/test_weave.py 2008-04-29 05:27:08 +0000
@@ -657,66 +657,6 @@
self.weave1.add_lines('v1', [], self.lines1)
self.weave1.add_lines('v2', ['v1'], ['hello\n', 'world\n'])
self.weave1.add_lines('v3', ['v2'], self.lines3)
-
- def test_join_empty(self):
- """Join two empty weaves."""
- eq = self.assertEqual
- w1 = Weave()
- w2 = Weave()
- w1.join(w2)
- eq(len(w1), 0)
-
- def test_join_empty_to_nonempty(self):
- """Join empty weave onto nonempty."""
- self.weave1.join(Weave())
- self.assertEqual(len(self.weave1), 3)
-
- def test_join_unrelated(self):
- """Join two weaves with no history in common."""
- wb = Weave()
- wb.add_lines('b1', [], ['line from b\n'])
- w1 = self.weave1
- w1.join(wb)
- eq = self.assertEqual
- eq(len(w1), 4)
- eq(sorted(w1.versions()),
- ['b1', 'v1', 'v2', 'v3'])
-
- def test_join_related(self):
- wa = self.weave1.copy()
- wb = self.weave1.copy()
- wa.add_lines('a1', ['v3'], ['hello\n', 'sweet\n', 'world\n'])
- wb.add_lines('b1', ['v3'], ['hello\n', 'pale blue\n', 'world\n'])
- eq = self.assertEquals
- eq(len(wa), 4)
- eq(len(wb), 4)
- wa.join(wb)
- eq(len(wa), 5)
- eq(wa.get_lines('b1'),
- ['hello\n', 'pale blue\n', 'world\n'])
-
- def test_join_text_disagreement(self):
- """Cannot join weaves with different texts for a version."""
- wa = Weave()
- wb = Weave()
- wa.add_lines('v1', [], ['hello\n'])
- wb.add_lines('v1', [], ['not\n', 'hello\n'])
- self.assertRaises(WeaveError,
- wa.join, wb)
-
- def test_join_unordered(self):
- """Join weaves where indexes differ.
-
- The source weave contains a different version at index 0."""
- wa = self.weave1.copy()
- wb = Weave()
- wb.add_lines('x1', [], ['line from x1\n'])
- wb.add_lines('v1', [], ['hello\n'])
- wb.add_lines('v2', ['v1'], ['hello\n', 'world\n'])
- wa.join(wb)
- eq = self.assertEquals
- eq(sorted(wa.versions()), ['v1', 'v2', 'v3', 'x1',])
- eq(wa.get_text('x1'), 'line from x1\n')
def test_written_detection(self):
# Test detection of weave file corruption.
@@ -779,57 +719,6 @@
return Weave._extract(self, versions)
-class JoinOptimization(TestCase):
- """Test that Weave.join() doesn't extract all texts, only what must be done."""
-
- def test_join(self):
- w1 = InstrumentedWeave()
- w2 = InstrumentedWeave()
-
- txt0 = ['a\n']
- txt1 = ['a\n', 'b\n']
- txt2 = ['a\n', 'c\n']
- txt3 = ['a\n', 'b\n', 'c\n']
-
- w1.add_lines('txt0', [], txt0) # extract 1a
- w2.add_lines('txt0', [], txt0) # extract 1b
- w1.add_lines('txt1', ['txt0'], txt1)# extract 2a
- w2.add_lines('txt2', ['txt0'], txt2)# extract 2b
- w1.join(w2) # extract 3a to add txt2
- w2.join(w1) # extract 3b to add txt1
-
- w1.add_lines('txt3', ['txt1', 'txt2'], txt3) # extract 4a
- w2.add_lines('txt3', ['txt2', 'txt1'], txt3) # extract 4b
- # These secretly have inverted parents
-
- # This should not have to do any extractions
- w1.join(w2) # NO extract, texts already present with same parents
- w2.join(w1) # NO extract, texts already present with same parents
-
- self.assertEqual(4, w1._extract_count)
- self.assertEqual(4, w2._extract_count)
-
- def test_double_parent(self):
- # It should not be considered illegal to add
- # a revision with the same parent twice
- w1 = InstrumentedWeave()
- w2 = InstrumentedWeave()
-
- txt0 = ['a\n']
- txt1 = ['a\n', 'b\n']
- txt2 = ['a\n', 'c\n']
- txt3 = ['a\n', 'b\n', 'c\n']
-
- w1.add_lines('txt0', [], txt0)
- w2.add_lines('txt0', [], txt0)
- w1.add_lines('txt1', ['txt0'], txt1)
- w2.add_lines('txt1', ['txt0', 'txt0'], txt1)
- # Same text, effectively the same, because the
- # parent is only repeated
- w1.join(w2) # extract 3a to add txt2
- w2.join(w1) # extract 3b to add txt1
-
-
class TestNeedsReweave(TestCase):
"""Internal corner cases for when reweave is needed."""
=== modified file 'bzrlib/versionedfile.py'
--- a/bzrlib/versionedfile.py 2008-04-24 07:28:18 +0000
+++ b/bzrlib/versionedfile.py 2008-04-29 05:27:08 +0000
@@ -98,6 +98,13 @@
self.parents = None
+def filter_absent(record_stream):
+ """Adapt a record stream to remove absent records."""
+ for record in record_stream:
+ if record.storage_kind != 'absent':
+ yield record
+
+
class VersionedFile(object):
"""Versioned text file storage.
@@ -517,6 +524,7 @@
"""
raise NotImplementedError(self.annotate)
+ @deprecated_method(one_five)
def join(self, other, pb=None, msg=None, version_ids=None,
ignore_missing=False):
"""Integrate versions from other into this versioned file.
More information about the bazaar-commits
mailing list