Rev 2643: Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. in http://people.ubuntu.com/~robertc/baz2.0/repository
Robert Collins
robertc at robertcollins.net
Sat Jul 14 00:17:04 BST 2007
At http://people.ubuntu.com/~robertc/baz2.0/repository
------------------------------------------------------------
revno: 2643
revision-id: robertc at robertcollins.net-20070713231702-0frzavpyutb51qqb
parent: robertc at robertcollins.net-20070713203605-i1tiuy07vb29oa3y
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Sat 2007-07-14 09:17:02 +1000
message:
Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
modified:
bzrlib/knit.py knit.py-20051212171256-f056ac8f0fbe1bd9
bzrlib/tests/test_knit.py test_knit.py-20051212171302-95d4c00dd5f11f2b
=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py 2007-07-13 20:36:05 +0000
+++ b/bzrlib/knit.py 2007-07-13 23:17:02 +0000
@@ -1329,6 +1329,14 @@
self._graph_index = graph_index
self._deltas = deltas
+ def _get_entries(self, version_ids):
+ """Get the entries for version_ids."""
+ return self._graph_index.iter_entries(version_ids)
+
+ def _present_keys(self, version_ids):
+ return set([
+ node[0] for node in self._get_entries(version_ids)])
+
def get_ancestry(self, versions, topo_sorted=True):
"""See VersionedFile.get_ancestry."""
# XXX: This will do len(history) index calls - perhaps
@@ -1339,7 +1347,7 @@
while pending:
# get all pending nodes
this_iteration = pending
- new_nodes = self._graph_index.iter_entries(this_iteration)
+ new_nodes = self._get_entries(this_iteration)
pending = set()
for (key, node_refs, value) in new_nodes:
graph[key] = node_refs[0]
@@ -1364,7 +1372,7 @@
while pending:
# get all pending nodes
this_iteration = pending
- new_nodes = self._graph_index.iter_entries(this_iteration)
+ new_nodes = self._get_entries(this_iteration)
pending = set()
for (key, node_refs, value) in new_nodes:
graph[key] = node_refs[0]
@@ -1394,7 +1402,7 @@
def has_version(self, version_id):
"""True if the version is in the index."""
- return len(list(self._graph_index.iter_entries([version_id]))) == 1
+ return len(list(self._get_entries([version_id]))) == 1
def get_position(self, version_id):
"""Return data position and size of specified version."""
@@ -1415,7 +1423,7 @@
return 'fulltext'
def _get_node(self, version_id):
- return list(self._graph_index.iter_entries([version_id]))[0]
+ return list(self._get_entries([version_id]))[0]
def get_options(self, version_id):
"""Return a string represention options.
@@ -1437,10 +1445,6 @@
present_parents = self._present_keys(parents)
return [key for key in parents if key in present_parents]
- def _present_keys(self, version_ids):
- return set([
- node[0] for node in self._graph_index.iter_entries(version_ids)])
-
def get_parents_with_ghosts(self, version_id):
"""Return parents of specified version with ghosts."""
return self._get_node(version_id)[1][0]
@@ -1453,6 +1457,53 @@
if missing:
raise RevisionNotPresent(missing.pop, self)
+ def add_version(self, version_id, options, pos, size, parents):
+ """Add a version record to the index."""
+ return self.add_versions(((version_id, options, pos, size, parents),))
+
+ def add_versions(self, versions):
+ """Add multiple versions to the index.
+
+ This function does not insert data into the Immutable GraphIndex
+ backing the KnitGraphIndex, instead it prepares data for insertion by
+ the caller and checks that it is safe to insert.
+
+ :param versions: a list of tuples:
+ (version_id, options, pos, size, parents).
+ :return: A list of (key, node_refs, value) tuples for insertion
+ into a GraphIndex.
+ """
+ # we hope there are no repositories with inconsistent parentage
+ # anymore.
+ # check for dups
+
+ keys = {}
+ for (version_id, options, pos, size, parents) in versions:
+ if 'no-eol' in options:
+ value = 'N'
+ else:
+ value = ' '
+ value += "%d %d" % (pos, size)
+ if self._deltas:
+ if 'line-delta' in options:
+ node_refs = (tuple(parents), (parents[0],))
+ else:
+ node_refs = (tuple(parents), ())
+ else:
+ if 'line-delta' in options:
+ raise KnitCorrupt(self, "attempt to add line-delta in non-delta knit")
+ node_refs = (tuple(parents), )
+ keys[version_id] = (node_refs, value)
+ present_nodes = self._get_entries(keys)
+ for (key, node_refs, value) in present_nodes:
+ if (node_refs, value) != keys[key]:
+ raise KnitCorrupt(self, "inconsistent details in add_versions")
+ del keys[key]
+ result = []
+ for key, (node_refs, value) in keys.iteritems():
+ result.append((key, node_refs, value))
+ return result
+
class _KnitData(_KnitComponentFile):
"""Contents of the knit data file"""
=== modified file 'bzrlib/tests/test_knit.py'
--- a/bzrlib/tests/test_knit.py 2007-07-13 20:36:05 +0000
+++ b/bzrlib/tests/test_knit.py 2007-07-13 23:17:02 +0000
@@ -1671,6 +1671,96 @@
['tail', 'ghost'])
index.check_versions_present(['tail', 'separate'])
+ def test_add_version_smoke(self):
+ index = self.two_graph_index()
+ self.assertEqual([('new', (('separate',),), 'N50 60')],
+ index.add_version('new', 'fulltext,no-eol', 50, 60, ['separate']))
+
+ def test_add_version_delta_not_delta_index(self):
+ index = self.two_graph_index()
+ self.assertRaises(errors.KnitCorrupt, index.add_version,
+ 'new', 'no-eol,line-delta', 0, 100, ['parent'])
+
+ def test_add_version_same_dup(self):
+ index = self.two_graph_index()
+ # options can be spelt two different ways
+ self.assertEqual([], list(index.add_version(
+ 'tip', 'fulltext,no-eol', 0, 100, ['parent'])))
+ self.assertEqual([], list(index.add_version(
+ 'tip', 'no-eol,fulltext', 0, 100, ['parent'])))
+
+ def test_add_version_different_dup(self):
+ index = self.two_graph_index(deltas=True)
+ # change options
+ self.assertRaises(errors.KnitCorrupt, index.add_version,
+ 'tip', 'no-eol,line-delta', 0, 100, ['parent'])
+ self.assertRaises(errors.KnitCorrupt, index.add_version,
+ 'tip', 'line-delta,no-eol', 0, 100, ['parent'])
+ self.assertRaises(errors.KnitCorrupt, index.add_version,
+ 'tip', 'fulltext', 0, 100, ['parent'])
+ # position/length
+ self.assertRaises(errors.KnitCorrupt, index.add_version,
+ 'tip', 'fulltext,no-eol', 50, 100, ['parent'])
+ self.assertRaises(errors.KnitCorrupt, index.add_version,
+ 'tip', 'fulltext,no-eol', 0, 1000, ['parent'])
+ # parents
+ self.assertRaises(errors.KnitCorrupt, index.add_version,
+ 'tip', 'fulltext,no-eol', 0, 100, [])
+
+ def test_add_versions_nodeltas(self):
+ index = self.two_graph_index()
+ self.assertEqual([('new', (('separate',),), 'N50 60'),
+ ('new2', (('new',),), ' 0 6')],
+ sorted(index.add_versions([
+ ('new', 'fulltext,no-eol', 50, 60, ['separate']),
+ ('new2', 'fulltext', 0, 6, ['new']),
+ ])))
+
+ def test_add_versions_deltas(self):
+ index = self.two_graph_index(deltas=True)
+ self.assertEqual([('new', (('separate',), ()), 'N50 60'),
+ ('new2', (('new',), ('new',), ), ' 0 6')],
+ sorted(index.add_versions([
+ ('new', 'fulltext,no-eol', 50, 60, ['separate']),
+ ('new2', 'line-delta', 0, 6, ['new']),
+ ])))
+
+ def test_add_versions_delta_not_delta_index(self):
+ index = self.two_graph_index()
+ self.assertRaises(errors.KnitCorrupt, index.add_versions,
+ [('new', 'no-eol,line-delta', 0, 100, ['parent'])])
+
+ def test_add_versions_same_dup(self):
+ index = self.two_graph_index()
+ # options can be spelt two different ways
+ self.assertEqual([], list(index.add_versions([(
+ 'tip', 'fulltext,no-eol', 0, 100, ['parent'])])))
+ self.assertEqual([], list(index.add_versions([(
+ 'tip', 'no-eol,fulltext', 0, 100, ['parent'])])))
+
+ def test_add_versions_different_dup(self):
+ index = self.two_graph_index(deltas=True)
+ # change options
+ self.assertRaises(errors.KnitCorrupt, index.add_versions,
+ [('tip', 'no-eol,line-delta', 0, 100, ['parent'])])
+ self.assertRaises(errors.KnitCorrupt, index.add_versions,
+ [('tip', 'line-delta,no-eol', 0, 100, ['parent'])])
+ self.assertRaises(errors.KnitCorrupt, index.add_versions,
+ [('tip', 'fulltext', 0, 100, ['parent'])])
+ # position/length
+ self.assertRaises(errors.KnitCorrupt, index.add_versions,
+ [('tip', 'fulltext,no-eol', 50, 100, ['parent'])])
+ self.assertRaises(errors.KnitCorrupt, index.add_versions,
+ [('tip', 'fulltext,no-eol', 0, 1000, ['parent'])])
+ # parents
+ self.assertRaises(errors.KnitCorrupt, index.add_versions,
+ [('tip', 'fulltext,no-eol', 0, 100, [])])
+ # change options in the second record
+ self.assertRaises(errors.KnitCorrupt, index.add_versions,
+ [('tip', 'fulltext,no-eol', 0, 100, ['parent']),
+ ('tip', 'no-eol,line-delta', 0, 100, ['parent'])])
+
+
## --- mutating tests for later ---
#
# def test_add_version
More information about the bazaar-commits
mailing list