Rev 2671: Pull in pre-requisite index changes. in http://people.ubuntu.com/~robertc/baz2.0/knits
Robert Collins
robertc at robertcollins.net
Fri Aug 3 00:06:11 BST 2007
At http://people.ubuntu.com/~robertc/baz2.0/knits
------------------------------------------------------------
revno: 2671
revision-id: robertc at robertcollins.net-20070802230604-pbpbsl4y1wyr1dvm
parent: pqm at pqm.ubuntu.com-20070802221338-9333q05a8caaciwo
parent: robertc at robertcollins.net-20070801075314-2maihdqr02hah1t3
committer: Robert Collins <robertc at robertcollins.net>
branch nick: knits
timestamp: Fri 2007-08-03 09:06:04 +1000
message:
Pull in pre-requisite index changes.
modified:
bzrlib/index.py index.py-20070712131115-lolkarso50vjr64s-1
bzrlib/knit.py knit.py-20051212171256-f056ac8f0fbe1bd9
bzrlib/tests/test_index.py test_index.py-20070712131115-lolkarso50vjr64s-2
bzrlib/tests/test_knit.py test_knit.py-20051212171302-95d4c00dd5f11f2b
------------------------------------------------------------
revno: 2624.2.14
revision-id: robertc at robertcollins.net-20070801075314-2maihdqr02hah1t3
parent: robertc at robertcollins.net-20070730041421-1jt0kd6ggvlm0jdn
committer: Robert Collins <robertc at robertcollins.net>
branch nick: index
timestamp: Wed 2007-08-01 17:53:14 +1000
message:
Add source index to the index iteration API to allow mapping back to the origin of retrieved data.
modified:
bzrlib/index.py index.py-20070712131115-lolkarso50vjr64s-1
bzrlib/knit.py knit.py-20051212171256-f056ac8f0fbe1bd9
bzrlib/tests/test_index.py test_index.py-20070712131115-lolkarso50vjr64s-2
bzrlib/tests/test_knit.py test_knit.py-20051212171302-95d4c00dd5f11f2b
------------------------------------------------------------
revno: 2624.2.13
revision-id: robertc at robertcollins.net-20070730041421-1jt0kd6ggvlm0jdn
parent: robertc at robertcollins.net-20070729233741-tp1d2j06b7zde9j3
committer: Robert Collins <robertc at robertcollins.net>
branch nick: index
timestamp: Mon 2007-07-30 14:14:21 +1000
message:
Implement add_node/add_nodes to the GraphIndexPrefixAdapter.
modified:
bzrlib/index.py index.py-20070712131115-lolkarso50vjr64s-1
bzrlib/tests/test_index.py test_index.py-20070712131115-lolkarso50vjr64s-2
------------------------------------------------------------
revno: 2624.2.12
revision-id: robertc at robertcollins.net-20070729233741-tp1d2j06b7zde9j3
parent: robertc at robertcollins.net-20070728013353-qk7394wehmg2iiph
committer: Robert Collins <robertc at robertcollins.net>
branch nick: index
timestamp: Mon 2007-07-30 09:37:41 +1000
message:
Create an adapter between indices with differing key lengths.
modified:
bzrlib/index.py index.py-20070712131115-lolkarso50vjr64s-1
bzrlib/tests/test_index.py test_index.py-20070712131115-lolkarso50vjr64s-2
=== modified file 'bzrlib/index.py'
--- a/bzrlib/index.py 2007-07-28 01:33:53 +0000
+++ b/bzrlib/index.py 2007-08-01 07:53:14 +0000
@@ -20,6 +20,7 @@
'CombinedGraphIndex',
'GraphIndex',
'GraphIndexBuilder',
+ 'GraphIndexPrefixAdapter',
'InMemoryGraphIndex',
]
@@ -313,10 +314,10 @@
self._buffer_all()
if self.node_ref_lists:
for key, (value, node_ref_lists) in self._nodes.iteritems():
- yield key, value, node_ref_lists
+ yield self, key, value, node_ref_lists
else:
for key, value in self._nodes.iteritems():
- yield key, value
+ yield self, key, value
def _read_prefix(self, stream):
signature = stream.read(len(self._signature()))
@@ -354,10 +355,10 @@
if self.node_ref_lists:
for key in keys:
value, node_refs = self._nodes[key]
- yield key, value, node_refs
+ yield self, key, value, node_refs
else:
for key in keys:
- yield key, self._nodes[key]
+ yield self, key, self._nodes[key]
def iter_entries_prefix(self, keys):
"""Iterate over keys within the index using prefix matching.
@@ -391,9 +392,9 @@
raise errors.BadIndexKey(key)
if self.node_ref_lists:
value, node_refs = self._nodes[key]
- yield key, value, node_refs
+ yield self, key, value, node_refs
else:
- yield key, self._nodes[key]
+ yield self, key, self._nodes[key]
return
for key in keys:
# sanity check
@@ -426,10 +427,10 @@
for value in key_dict.itervalues():
# each value is the key:value:node refs tuple
# ready to yield.
- yield value
+ yield (self, ) + value
else:
# the last thing looked up was a terminal element
- yield key_dict
+ yield (self, ) + key_dict
def _signature(self):
"""The file signature for this index type."""
@@ -483,9 +484,9 @@
seen_keys = set()
for index in self._indices:
for node in index.iter_all_entries():
- if node[0] not in seen_keys:
+ if node[1] not in seen_keys:
yield node
- seen_keys.add(node[0])
+ seen_keys.add(node[1])
def iter_entries(self, keys):
"""Iterate over keys within the index.
@@ -503,7 +504,7 @@
if not keys:
return
for node in index.iter_entries(keys):
- keys.remove(node[0])
+ keys.remove(node[1])
yield node
def iter_entries_prefix(self, keys):
@@ -532,9 +533,9 @@
seen_keys = set()
for index in self._indices:
for node in index.iter_entries_prefix(keys):
- if node[0] in seen_keys:
+ if node[1] in seen_keys:
continue
- seen_keys.add(node[0])
+ seen_keys.add(node[1])
yield node
def validate(self):
@@ -573,11 +574,11 @@
if self.reference_lists:
for key, (absent, references, value) in self._nodes.iteritems():
if not absent:
- yield key, value, references
+ yield self, key, value, references
else:
for key, (absent, references, value) in self._nodes.iteritems():
if not absent:
- yield key, value
+ yield self, key, value
def iter_entries(self, keys):
"""Iterate over keys within the index.
@@ -592,12 +593,12 @@
for key in keys.intersection(self._nodes):
node = self._nodes[key]
if not node[0]:
- yield key, node[2], node[1]
+ yield self, key, node[2], node[1]
else:
for key in keys.intersection(self._nodes):
node = self._nodes[key]
if not node[0]:
- yield key, node[2]
+ yield self, key, node[2]
def iter_entries_prefix(self, keys):
"""Iterate over keys within the index using prefix matching.
@@ -632,9 +633,9 @@
if node[0]:
continue
if self.reference_lists:
- yield key, node[2], node[1]
+ yield self, key, node[2], node[1]
else:
- yield key, node[2]
+ yield self ,key, node[2]
return
for key in keys:
# sanity check
@@ -665,9 +666,125 @@
else:
# yield keys
for value in key_dict.itervalues():
- yield value
+ yield (self, ) + value
else:
- yield key_dict
+ yield (self, ) + key_dict
def validate(self):
"""In memory index's have no known corruption at the moment."""
+
+
+class GraphIndexPrefixAdapter(object):
+ """An adapter between GraphIndex with different key lengths.
+
+ Queries against this will emit queries against the adapted Graph with the
+ prefix added, queries for all items use iter_entries_prefix. The returned
+ nodes will have their keys and node references adjusted to remove the
+ prefix. Finally, an add_nodes_callback can be supplied - when called the
+ nodes and references being added will have prefix prepended.
+ """
+
+ def __init__(self, adapted, prefix, missing_key_length, add_nodes_callback=None):
+ """Construct an adapter against adapted with prefix."""
+ self.adapted = adapted
+ self.prefix = prefix + (None,)*missing_key_length
+ self.prefix_key = prefix
+ self.prefix_len = len(prefix)
+ self.add_nodes_callback = add_nodes_callback
+
+ def add_nodes(self, nodes):
+ """Add nodes to the index.
+
+ :param nodes: An iterable of (key, node_refs, value) entries to add.
+ """
+ # save nodes in case its an iterator
+ nodes = tuple(nodes)
+ translated_nodes = []
+ try:
+ for (key, value, node_refs) in nodes:
+ adjusted_references = (
+ tuple(tuple(self.prefix_key + ref_node for ref_node in ref_list)
+ for ref_list in node_refs))
+ translated_nodes.append((self.prefix_key + key, value,
+ adjusted_references))
+ except ValueError:
+ # XXX: TODO add an explicit interface for getting the reference list
+ # status, to handle this bit of user-friendliness in the API more
+ # explicitly.
+ for (key, value) in nodes:
+ translated_nodes.append((self.prefix_key + key, value))
+ self.add_nodes_callback(translated_nodes)
+
+ def add_node(self, key, value, references=()):
+ """Add a node to the index.
+
+ :param key: The key. keys are non-empty tuples containing
+ as many whitespace-free utf8 bytestrings as the key length
+ defined for this index.
+ :param references: An iterable of iterables of keys. Each is a
+ reference to another key.
+ :param value: The value to associate with the key. It may be any
+ bytes as long as it does not contain \0 or \n.
+ """
+ self.add_nodes(((key, value, references), ))
+
+ def _strip_prefix(self, an_iter):
+ """Strip prefix data from nodes and return it."""
+ for node in an_iter:
+ # cross checks
+ if node[1][:self.prefix_len] != self.prefix_key:
+ raise errors.BadIndexData(self)
+ for ref_list in node[3]:
+ for ref_node in ref_list:
+ if ref_node[:self.prefix_len] != self.prefix_key:
+ raise errors.BadIndexData(self)
+ yield node[0], node[1][self.prefix_len:], node[2], (
+ tuple(tuple(ref_node[self.prefix_len:] for ref_node in ref_list)
+ for ref_list in node[3]))
+
+ def iter_all_entries(self):
+ """Iterate over all keys within the index
+
+ iter_all_entries is implemented against the adapted index using
+ iter_entries_prefix.
+
+ :return: An iterable of (key, reference_lists, value). There is no
+ defined order for the result iteration - it will be in the most
+ efficient order for the index (in this case dictionary hash order).
+ """
+ return self._strip_prefix(self.adapted.iter_entries_prefix([self.prefix]))
+
+ def iter_entries(self, keys):
+ """Iterate over keys within the index.
+
+ :param keys: An iterable providing the keys to be retrieved.
+ :return: An iterable of (key, reference_lists, value). There is no
+ defined order for the result iteration - it will be in the most
+ efficient order for the index (keys iteration order in this case).
+ """
+ return self._strip_prefix(self.adapted.iter_entries(
+ self.prefix_key + key for key in keys))
+
+ def iter_entries_prefix(self, keys):
+ """Iterate over keys within the index using prefix matching.
+
+ Prefix matching is applied within the tuple of a key, not to within
+ the bytestring of each key element. e.g. if you have the keys ('foo',
+ 'bar'), ('foobar', 'gam') and do a prefix search for ('foo', None) then
+ only the former key is returned.
+
+ :param keys: An iterable providing the key prefixes to be retrieved.
+ Each key prefix takes the form of a tuple the length of a key, but
+ with the last N elements 'None' rather than a regular bytestring.
+ The first element cannot be 'None'.
+ :return: An iterable as per iter_all_entries, but restricted to the
+ keys with a matching prefix to those supplied. No additional keys
+ will be returned, and every match that is in the index will be
+ returned.
+ """
+ return self._strip_prefix(self.adapted.iter_entries_prefix(
+ self.prefix_key + key for key in keys))
+
+ def validate(self):
+ """Call the adapted's validate."""
+ self.adapted.validate()
=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py 2007-07-30 05:02:10 +0000
+++ b/bzrlib/knit.py 2007-08-02 23:06:04 +0000
@@ -1386,12 +1386,12 @@
if self._parents:
for node in self._graph_index.iter_entries(keys):
yield node
- found_keys.add(node[0])
+ found_keys.add(node[1])
else:
# adapt parentless index to the rest of the code.
for node in self._graph_index.iter_entries(keys):
- yield node[0], node[1], ()
- found_keys.add(node[0])
+ yield node[0], node[1], node[2], ()
+ found_keys.add(node[1])
if check_present:
missing_keys = keys.difference(found_keys)
if missing_keys:
@@ -1399,7 +1399,7 @@
def _present_keys(self, version_ids):
return set([
- node[0] for node in self._get_entries(version_ids)])
+ node[1] for node in self._get_entries(version_ids)])
def _parentless_ancestry(self, versions):
"""Honour the get_ancestry API for parentless knit indices."""
@@ -1427,7 +1427,7 @@
new_nodes = self._get_entries(this_iteration)
found = set()
pending = set()
- for (key, value, node_refs) in new_nodes:
+ for (index, key, value, node_refs) in new_nodes:
# dont ask for ghosties - otherwise
# we we can end up looping with pending
# being entirely ghosted.
@@ -1464,7 +1464,7 @@
this_iteration = pending
new_nodes = self._get_entries(this_iteration)
pending = set()
- for (key, value, node_refs) in new_nodes:
+ for (index, key, value, node_refs) in new_nodes:
graph[key] = node_refs[0]
# queue parents
for parent in graph[key]:
@@ -1488,7 +1488,7 @@
if not self._parents:
return [(key, ()) for key in self.get_versions()]
result = []
- for key, value, refs in self._graph_index.iter_all_entries():
+ for index, key, value, refs in self._graph_index.iter_all_entries():
result.append((key[0], tuple([ref[0] for ref in refs[0]])))
return result
@@ -1506,20 +1506,20 @@
all_parents = set()
present_parents = set()
for node in all_nodes:
- all_parents.update(node[2][0])
+ all_parents.update(node[3][0])
# any node we are querying must be present
- present_parents.add(node[0])
+ present_parents.add(node[1])
unknown_parents = all_parents.difference(present_parents)
present_parents.update(self._present_keys(unknown_parents))
for node in all_nodes:
parents = []
- for parent in node[2][0]:
+ for parent in node[3][0]:
if parent in present_parents:
parents.append(parent[0])
- yield node[0][0], tuple(parents)
+ yield node[1][0], tuple(parents)
else:
for node in self._get_entries(self._version_ids_to_keys(version_ids)):
- yield node[0][0], ()
+ yield node[1][0], ()
def num_versions(self):
return len(list(self._graph_index.iter_all_entries()))
@@ -1528,7 +1528,7 @@
def get_versions(self):
"""Get all the versions in the file. not topologically sorted."""
- return [node[0][0] for node in self._graph_index.iter_all_entries()]
+ return [node[1][0] for node in self._graph_index.iter_all_entries()]
def has_version(self, version_id):
"""True if the version is in the index."""
@@ -1539,14 +1539,14 @@
def get_position(self, version_id):
"""Return data position and size of specified version."""
- bits = self._get_node(version_id)[1][1:].split(' ')
+ bits = self._get_node(version_id)[2][1:].split(' ')
return int(bits[0]), int(bits[1])
def get_method(self, version_id):
"""Return compression method of specified version."""
if not self._deltas:
return 'fulltext'
- return self._parent_compression(self._get_node(version_id)[2][1])
+ return self._parent_compression(self._get_node(version_id)[3][1])
def _parent_compression(self, reference_list):
# use the second reference list to decide if this is delta'd or not.
@@ -1567,8 +1567,8 @@
if not self._deltas:
options = ['fulltext']
else:
- options = [self._parent_compression(node[2][1])]
- if node[1][0] == 'N':
+ options = [self._parent_compression(node[3][1])]
+ if node[2][0] == 'N':
options.append('no-eol')
return options
@@ -1586,7 +1586,7 @@
check_present=True))
if not self._parents:
return ()
- return self._keys_to_version_ids(nodes[0][2][0])
+ return self._keys_to_version_ids(nodes[0][3][0])
def check_versions_present(self, version_ids):
"""Check that all specified versions are present."""
@@ -1645,7 +1645,7 @@
node_refs = ()
keys[key] = (value, node_refs)
present_nodes = self._get_entries(keys)
- for (key, value, node_refs) in present_nodes:
+ for (index, key, value, node_refs) in present_nodes:
if (value, node_refs) != keys[key]:
raise KnitCorrupt(self, "inconsistent details in add_versions"
": %s %s" % ((value, node_refs), keys[key]))
=== modified file 'bzrlib/tests/test_index.py'
--- a/bzrlib/tests/test_index.py 2007-07-28 01:33:53 +0000
+++ b/bzrlib/tests/test_index.py 2007-08-01 07:53:14 +0000
@@ -349,38 +349,38 @@
def test_iter_all_entries_simple(self):
index = self.make_index(nodes=[(('name', ), 'data', ())])
- self.assertEqual([(('name', ), 'data')],
+ self.assertEqual([(index, ('name', ), 'data')],
list(index.iter_all_entries()))
def test_iter_all_entries_simple_2_elements(self):
index = self.make_index(key_elements=2,
nodes=[(('name', 'surname'), 'data', ())])
- self.assertEqual([(('name', 'surname'), 'data')],
+ self.assertEqual([(index, ('name', 'surname'), 'data')],
list(index.iter_all_entries()))
def test_iter_all_entries_references_resolved(self):
index = self.make_index(1, nodes=[
(('name', ), 'data', ([('ref', )], )),
(('ref', ), 'refdata', ([], ))])
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
- (('ref', ), 'refdata', ((), ))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
+ (index, ('ref', ), 'refdata', ((), ))]),
set(index.iter_all_entries()))
def test_iteration_absent_skipped(self):
index = self.make_index(1, nodes=[
(('name', ), 'data', ([('ref', )], ))])
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
set(index.iter_all_entries()))
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
set(index.iter_entries([('name', )])))
self.assertEqual([], list(index.iter_entries([('ref', )])))
def test_iteration_absent_skipped_2_element_keys(self):
index = self.make_index(1, key_elements=2, nodes=[
(('name', 'fin'), 'data', ([('ref', 'erence')], ))])
- self.assertEqual(set([(('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
+ self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
set(index.iter_all_entries()))
- self.assertEqual(set([(('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
+ self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
set(index.iter_entries([('name', 'fin')])))
self.assertEqual([], list(index.iter_entries([('ref', 'erence')])))
@@ -388,8 +388,8 @@
index = self.make_index(1, nodes=[
(('name', ), 'data', ([('ref', )], )),
(('ref', ), 'refdata', ([], ))])
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
- (('ref', ), 'refdata', ((), ))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
+ (index, ('ref', ), 'refdata', ((), ))]),
set(index.iter_entries([('name', ), ('ref', )])))
def test_iter_nothing_empty(self):
@@ -419,16 +419,16 @@
index = self.make_index( nodes=[
(('name', ), 'data', ()),
(('ref', ), 'refdata', ())])
- self.assertEqual(set([(('name', ), 'data'),
- (('ref', ), 'refdata')]),
+ self.assertEqual(set([(index, ('name', ), 'data'),
+ (index, ('ref', ), 'refdata')]),
set(index.iter_entries_prefix([('name', ), ('ref', )])))
def test_iter_key_prefix_1_key_element_refs(self):
index = self.make_index(1, nodes=[
(('name', ), 'data', ([('ref', )], )),
(('ref', ), 'refdata', ([], ))])
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
- (('ref', ), 'refdata', ((), ))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
+ (index, ('ref', ), 'refdata', ((), ))]),
set(index.iter_entries_prefix([('name', ), ('ref', )])))
def test_iter_key_prefix_2_key_element_no_refs(self):
@@ -436,11 +436,11 @@
(('name', 'fin1'), 'data', ()),
(('name', 'fin2'), 'beta', ()),
(('ref', 'erence'), 'refdata', ())])
- self.assertEqual(set([(('name', 'fin1'), 'data'),
- (('ref', 'erence'), 'refdata')]),
+ self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
+ (index, ('ref', 'erence'), 'refdata')]),
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
- self.assertEqual(set([(('name', 'fin1'), 'data'),
- (('name', 'fin2'), 'beta')]),
+ self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
+ (index, ('name', 'fin2'), 'beta')]),
set(index.iter_entries_prefix([('name', None)])))
def test_iter_key_prefix_2_key_element_refs(self):
@@ -448,11 +448,11 @@
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
(('name', 'fin2'), 'beta', ([], )),
(('ref', 'erence'), 'refdata', ([], ))])
- self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
- (('ref', 'erence'), 'refdata', ((), ))]),
+ self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
+ (index, ('ref', 'erence'), 'refdata', ((), ))]),
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
- self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
- (('name', 'fin2'), 'beta', ((), ))]),
+ self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
+ (index, ('name', 'fin2'), 'beta', ((), ))]),
set(index.iter_entries_prefix([('name', None)])))
def test_validate_bad_index_errors(self):
@@ -515,7 +515,7 @@
index = CombinedGraphIndex([])
index1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
index.insert_index(0, index1)
- self.assertEqual([(('key', ), '')], list(index.iter_all_entries()))
+ self.assertEqual([(index1, ('key', ), '')], list(index.iter_all_entries()))
def test_iter_all_entries_empty(self):
index = CombinedGraphIndex([])
@@ -529,29 +529,29 @@
def test_iter_all_entries_simple(self):
index1 = self.make_index('name', nodes=[(('name', ), 'data', ())])
index = CombinedGraphIndex([index1])
- self.assertEqual([(('name', ), 'data')],
+ self.assertEqual([(index1, ('name', ), 'data')],
list(index.iter_all_entries()))
def test_iter_all_entries_two_indices(self):
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
index2 = self.make_index('name2', nodes=[(('2', ), '', ())])
index = CombinedGraphIndex([index1, index2])
- self.assertEqual([(('name', ), 'data'),
- (('2', ), '')],
+ self.assertEqual([(index1, ('name', ), 'data'),
+ (index2, ('2', ), '')],
list(index.iter_all_entries()))
def test_iter_entries_two_indices_dup_key(self):
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
index = CombinedGraphIndex([index1, index2])
- self.assertEqual([(('name', ), 'data')],
+ self.assertEqual([(index1, ('name', ), 'data')],
list(index.iter_entries([('name', )])))
def test_iter_all_entries_two_indices_dup_key(self):
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
index = CombinedGraphIndex([index1, index2])
- self.assertEqual([(('name', ), 'data')],
+ self.assertEqual([(index1, ('name', ), 'data')],
list(index.iter_all_entries()))
def test_iter_key_prefix_2_key_element_refs(self):
@@ -561,11 +561,11 @@
(('name', 'fin2'), 'beta', ([], )),
(('ref', 'erence'), 'refdata', ([], ))])
index = CombinedGraphIndex([index1, index2])
- self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
- (('ref', 'erence'), 'refdata', ((), ))]),
+ self.assertEqual(set([(index1, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
+ (index2, ('ref', 'erence'), 'refdata', ((), ))]),
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
- self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
- (('name', 'fin2'), 'beta', ((), ))]),
+ self.assertEqual(set([(index1, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
+ (index2, ('name', 'fin2'), 'beta', ((), ))]),
set(index.iter_entries_prefix([('name', None)])))
def test_iter_nothing_empty(self):
@@ -583,8 +583,8 @@
index2 = self.make_index('2', 1, nodes=[
(('ref', ), 'refdata', ((), ))])
index = CombinedGraphIndex([index1, index2])
- self.assertEqual(set([(('name', ), 'data', ((('ref', ), ), )),
- (('ref', ), 'refdata', ((), ))]),
+ self.assertEqual(set([(index1, ('name', ), 'data', ((('ref', ), ), )),
+ (index2, ('ref', ), 'refdata', ((), ))]),
set(index.iter_entries([('name', ), ('ref', )])))
def test_iter_all_keys_dup_entry(self):
@@ -594,8 +594,8 @@
index2 = self.make_index('2', 1, nodes=[
(('ref', ), 'refdata', ([], ))])
index = CombinedGraphIndex([index1, index2])
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
- (('ref', ), 'refdata', ((), ))]),
+ self.assertEqual(set([(index1, ('name', ), 'data', ((('ref',),),)),
+ (index1, ('ref', ), 'refdata', ((), ))]),
set(index.iter_entries([('name', ), ('ref', )])))
def test_iter_missing_entry_empty(self):
@@ -617,11 +617,11 @@
index1 = self.make_index('1', nodes=[(('key', ), '', ())])
index2 = self.make_index('2', nodes=[])
index = CombinedGraphIndex([index1, index2])
- self.assertEqual([(('key', ), '')],
+ self.assertEqual([(index1, ('key', ), '')],
list(index.iter_entries([('key', )])))
# and in the other direction
index = CombinedGraphIndex([index2, index1])
- self.assertEqual([(('key', ), '')],
+ self.assertEqual([(index1, ('key', ), '')],
list(index.iter_entries([('key', )])))
def test_validate_bad_child_index_errors(self):
@@ -648,9 +648,9 @@
index.add_nodes([(('name', ), 'data')])
index.add_nodes([(('name2', ), ''), (('name3', ), '')])
self.assertEqual(set([
- (('name', ), 'data'),
- (('name2', ), ''),
- (('name3', ), ''),
+ (index, ('name', ), 'data'),
+ (index, ('name2', ), ''),
+ (index, ('name3', ), ''),
]), set(index.iter_all_entries()))
def test_add_nodes(self):
@@ -658,9 +658,9 @@
index.add_nodes([(('name', ), 'data', ([],))])
index.add_nodes([(('name2', ), '', ([],)), (('name3', ), '', ([('r', )],))])
self.assertEqual(set([
- (('name', ), 'data', ((),)),
- (('name2', ), '', ((),)),
- (('name3', ), '', ((('r', ), ), )),
+ (index, ('name', ), 'data', ((),)),
+ (index, ('name2', ), '', ((),)),
+ (index, ('name3', ), '', ((('r', ), ), )),
]), set(index.iter_all_entries()))
def test_iter_all_entries_empty(self):
@@ -669,23 +669,23 @@
def test_iter_all_entries_simple(self):
index = self.make_index(nodes=[(('name', ), 'data')])
- self.assertEqual([(('name', ), 'data')],
+ self.assertEqual([(index, ('name', ), 'data')],
list(index.iter_all_entries()))
def test_iter_all_entries_references(self):
index = self.make_index(1, nodes=[
(('name', ), 'data', ([('ref', )], )),
(('ref', ), 'refdata', ([], ))])
- self.assertEqual(set([(('name', ), 'data', ((('ref', ),),)),
- (('ref', ), 'refdata', ((), ))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref', ),),)),
+ (index, ('ref', ), 'refdata', ((), ))]),
set(index.iter_all_entries()))
def test_iteration_absent_skipped(self):
index = self.make_index(1, nodes=[
(('name', ), 'data', ([('ref', )], ))])
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
set(index.iter_all_entries()))
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
set(index.iter_entries([('name', )])))
self.assertEqual([], list(index.iter_entries([('ref', )])))
@@ -693,24 +693,24 @@
index = self.make_index(1, nodes=[
(('name', ), 'data', ([('ref', )], )),
(('ref', ), 'refdata', ([], ))])
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
- (('ref', ), 'refdata', ((), ))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
+ (index, ('ref', ), 'refdata', ((), ))]),
set(index.iter_entries([('name', ), ('ref', )])))
def test_iter_key_prefix_1_key_element_no_refs(self):
index = self.make_index( nodes=[
(('name', ), 'data'),
(('ref', ), 'refdata')])
- self.assertEqual(set([(('name', ), 'data'),
- (('ref', ), 'refdata')]),
+ self.assertEqual(set([(index, ('name', ), 'data'),
+ (index, ('ref', ), 'refdata')]),
set(index.iter_entries_prefix([('name', ), ('ref', )])))
def test_iter_key_prefix_1_key_element_refs(self):
index = self.make_index(1, nodes=[
(('name', ), 'data', ([('ref', )], )),
(('ref', ), 'refdata', ([], ))])
- self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
- (('ref', ), 'refdata', ((), ))]),
+ self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
+ (index, ('ref', ), 'refdata', ((), ))]),
set(index.iter_entries_prefix([('name', ), ('ref', )])))
def test_iter_key_prefix_2_key_element_no_refs(self):
@@ -718,11 +718,11 @@
(('name', 'fin1'), 'data'),
(('name', 'fin2'), 'beta'),
(('ref', 'erence'), 'refdata')])
- self.assertEqual(set([(('name', 'fin1'), 'data'),
- (('ref', 'erence'), 'refdata')]),
+ self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
+ (index, ('ref', 'erence'), 'refdata')]),
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
- self.assertEqual(set([(('name', 'fin1'), 'data'),
- (('name', 'fin2'), 'beta')]),
+ self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
+ (index, ('name', 'fin2'), 'beta')]),
set(index.iter_entries_prefix([('name', None)])))
def test_iter_key_prefix_2_key_element_refs(self):
@@ -730,11 +730,11 @@
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
(('name', 'fin2'), 'beta', ([], )),
(('ref', 'erence'), 'refdata', ([], ))])
- self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
- (('ref', 'erence'), 'refdata', ((), ))]),
+ self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
+ (index, ('ref', 'erence'), 'refdata', ((), ))]),
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
- self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
- (('name', 'fin2'), 'beta', ((), ))]),
+ self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
+ (index, ('name', 'fin2'), 'beta', ((), ))]),
set(index.iter_entries_prefix([('name', None)])))
def test_iter_nothing_empty(self):
@@ -754,3 +754,90 @@
index.validate()
+class TestGraphIndexPrefixAdapter(TestCaseWithMemoryTransport):
+
+ def make_index(self, ref_lists=1, key_elements=2, nodes=[], add_callback=False):
+ result = InMemoryGraphIndex(ref_lists, key_elements=key_elements)
+ result.add_nodes(nodes)
+ if add_callback:
+ add_nodes_callback=result.add_nodes
+ else:
+ add_nodes_callback=None
+ adapter = GraphIndexPrefixAdapter(result, ('prefix', ), key_elements - 1,
+ add_nodes_callback=add_nodes_callback)
+ return result, adapter
+
+ def test_add_node(self):
+ index, adapter = self.make_index(add_callback=True)
+ adapter.add_node(('key',), 'value', ((('ref',),),))
+ self.assertEqual(set([(index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))]),
+ set(index.iter_all_entries()))
+
+ def test_add_nodes(self):
+ index, adapter = self.make_index(add_callback=True)
+ adapter.add_nodes((
+ (('key',), 'value', ((('ref',),),)),
+ (('key2',), 'value2', ((),)),
+ ))
+ self.assertEqual(set([
+ (index, ('prefix', 'key2'), 'value2', ((),)),
+ (index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))
+ ]),
+ set(index.iter_all_entries()))
+
+ def test_construct(self):
+ index = InMemoryGraphIndex()
+ adapter = GraphIndexPrefixAdapter(index, ('prefix', ), 1)
+
+ def test_construct_with_callback(self):
+ index = InMemoryGraphIndex()
+ adapter = GraphIndexPrefixAdapter(index, ('prefix', ), 1, index.add_nodes)
+
+ def test_iter_all_entries_cross_prefix_map_errors(self):
+ index, adapter = self.make_index(nodes=[
+ (('prefix', 'key1'), 'data1', ((('prefixaltered', 'key2'),),))])
+ self.assertRaises(errors.BadIndexData, list, adapter.iter_all_entries())
+
+ def test_iter_all_entries(self):
+ index, adapter = self.make_index(nodes=[
+ (('notprefix', 'key1'), 'data', ((), )),
+ (('prefix', 'key1'), 'data1', ((), )),
+ (('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
+ self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),
+ (index, ('key2', ), 'data2', ((('key1',),),))]),
+ set(adapter.iter_all_entries()))
+
+ def test_iter_entries(self):
+ index, adapter = self.make_index(nodes=[
+ (('notprefix', 'key1'), 'data', ((), )),
+ (('prefix', 'key1'), 'data1', ((), )),
+ (('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
+ # ask for many - get all
+ self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),
+ (index, ('key2', ), 'data2', ((('key1', ),),))]),
+ set(adapter.iter_entries([('key1', ), ('key2', )])))
+ # ask for one, get one
+ self.assertEqual(set([(index, ('key1', ), 'data1', ((),))]),
+ set(adapter.iter_entries([('key1', )])))
+ # ask for missing, get none
+ self.assertEqual(set(),
+ set(adapter.iter_entries([('key3', )])))
+
+ def test_iter_entries_prefix(self):
+ index, adapter = self.make_index(key_elements=3, nodes=[
+ (('notprefix', 'foo', 'key1'), 'data', ((), )),
+ (('prefix', 'prefix2', 'key1'), 'data1', ((), )),
+ (('prefix', 'prefix2', 'key2'), 'data2', ((('prefix', 'prefix2', 'key1'),),))])
+ # ask for a prefix, get the results for just that prefix, adjusted.
+ self.assertEqual(set([(index, ('prefix2', 'key1', ), 'data1', ((),)),
+ (index, ('prefix2', 'key2', ), 'data2', ((('prefix2', 'key1', ),),))]),
+ set(adapter.iter_entries_prefix([('prefix2', None)])))
+
+ def test_validate(self):
+ index, adapter = self.make_index()
+ calls = []
+ def validate():
+ calls.append('called')
+ index.validate = validate
+ adapter.validate()
+ self.assertEqual(['called'], calls)
=== modified file 'bzrlib/tests/test_knit.py'
--- a/bzrlib/tests/test_knit.py 2007-07-30 05:02:10 +0000
+++ b/bzrlib/tests/test_knit.py 2007-08-02 23:06:04 +0000
@@ -1017,8 +1017,8 @@
self.assertEqualDiff(''.join(k.get_lines('text-1a')), TEXT_1A)
# check the index had the right data added.
self.assertEqual(set([
- (('text-1', ), ' 0 127', ((), ())),
- (('text-1a', ), ' 127 140', ((('text-1', ),), (('text-1', ),))),
+ (index, ('text-1', ), ' 0 127', ((), ())),
+ (index, ('text-1a', ), ' 127 140', ((('text-1', ),), (('text-1', ),))),
]), set(index.iter_all_entries()))
# we should not have a .kndx file
self.assertFalse(get_transport('.').has('test.kndx'))
More information about the bazaar-commits
mailing list