bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
4634.71.1
by John Arbash Meinel
 Work around bug #402623 by allowing BTreeGraphIndex(...,unlimited_cache=True).  | 
1  | 
# Copyright (C) 2007, 2009 Canonical Ltd
 | 
| 
2592.1.4
by Robert Collins
 Create a GraphIndexBuilder.  | 
2  | 
#
 | 
3  | 
# This program is free software; you can redistribute it and/or modify
 | 
|
4  | 
# it under the terms of the GNU General Public License as published by
 | 
|
5  | 
# the Free Software Foundation; either version 2 of the License, or
 | 
|
6  | 
# (at your option) any later version.
 | 
|
7  | 
#
 | 
|
8  | 
# This program is distributed in the hope that it will be useful,
 | 
|
9  | 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|
10  | 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|
11  | 
# GNU General Public License for more details.
 | 
|
12  | 
#
 | 
|
13  | 
# You should have received a copy of the GNU General Public License
 | 
|
14  | 
# along with this program; if not, write to the Free Software
 | 
|
| 
4183.7.1
by Sabin Iacob
 update FSF mailing address  | 
15  | 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
| 
2592.1.4
by Robert Collins
 Create a GraphIndexBuilder.  | 
16  | 
|
17  | 
"""Tests for indices."""
 | 
|
18  | 
||
| 
2592.1.5
by Robert Collins
 Trivial index reading.  | 
19  | 
from bzrlib import errors  | 
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
20  | 
from bzrlib.index import *  | 
| 
2592.1.4
by Robert Collins
 Create a GraphIndexBuilder.  | 
21  | 
from bzrlib.tests import TestCaseWithMemoryTransport  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
22  | 
from bzrlib.transport import get_transport  | 
| 
2592.1.4
by Robert Collins
 Create a GraphIndexBuilder.  | 
23  | 
|
24  | 
||
25  | 
class TestGraphIndexBuilder(TestCaseWithMemoryTransport):  | 
|
26  | 
||
27  | 
def test_build_index_empty(self):  | 
|
28  | 
builder = GraphIndexBuilder()  | 
|
29  | 
stream = builder.finish()  | 
|
30  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
31  | 
self.assertEqual(  | 
32  | 
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=0\n\n",  | 
|
33  | 
contents)  | 
|
| 
2592.1.6
by Robert Collins
 Record the number of node reference lists a particular index has.  | 
34  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
35  | 
def test_build_index_empty_two_element_keys(self):  | 
36  | 
builder = GraphIndexBuilder(key_elements=2)  | 
|
37  | 
stream = builder.finish()  | 
|
38  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
39  | 
self.assertEqual(  | 
40  | 
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=0\n\n",  | 
|
41  | 
contents)  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
42  | 
|
| 
2592.1.6
by Robert Collins
 Record the number of node reference lists a particular index has.  | 
43  | 
def test_build_index_one_reference_list_empty(self):  | 
44  | 
builder = GraphIndexBuilder(reference_lists=1)  | 
|
45  | 
stream = builder.finish()  | 
|
46  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
47  | 
self.assertEqual(  | 
48  | 
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=0\n\n",  | 
|
49  | 
contents)  | 
|
| 
2592.1.4
by Robert Collins
 Create a GraphIndexBuilder.  | 
50  | 
|
| 
2592.1.10
by Robert Collins
 Make validate detect node reference parsing errors.  | 
51  | 
def test_build_index_two_reference_list_empty(self):  | 
52  | 
builder = GraphIndexBuilder(reference_lists=2)  | 
|
53  | 
stream = builder.finish()  | 
|
54  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
55  | 
self.assertEqual(  | 
56  | 
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=0\n\n",  | 
|
57  | 
contents)  | 
|
| 
2592.1.10
by Robert Collins
 Make validate detect node reference parsing errors.  | 
58  | 
|
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
59  | 
def test_build_index_one_node_no_refs(self):  | 
60  | 
builder = GraphIndexBuilder()  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
61  | 
builder.add_node(('akey', ), 'data')  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
62  | 
stream = builder.finish()  | 
63  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
64  | 
self.assertEqual(  | 
65  | 
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"  | 
|
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
66  | 
"akey\x00\x00\x00data\n\n", contents)  | 
67  | 
||
68  | 
def test_build_index_one_node_no_refs_accepts_empty_reflist(self):  | 
|
69  | 
builder = GraphIndexBuilder()  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
70  | 
builder.add_node(('akey', ), 'data', ())  | 
| 
2592.1.12
by Robert Collins
 Handle basic node adds.  | 
71  | 
stream = builder.finish()  | 
72  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
73  | 
self.assertEqual(  | 
74  | 
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"  | 
|
| 
2592.1.43
by Robert Collins
 Various index tweaks and test clarity from John's review.  | 
75  | 
"akey\x00\x00\x00data\n\n", contents)  | 
| 
2592.1.12
by Robert Collins
 Handle basic node adds.  | 
76  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
77  | 
def test_build_index_one_node_2_element_keys(self):  | 
| 
2624.2.11
by Robert Collins
 Review comments.  | 
78  | 
        # multipart keys are separated by \x00 - because they are fixed length,
 | 
79  | 
        # not variable this does not cause any issues, and seems clearer to the
 | 
|
80  | 
        # author.
 | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
81  | 
builder = GraphIndexBuilder(key_elements=2)  | 
82  | 
builder.add_node(('akey', 'secondpart'), 'data')  | 
|
83  | 
stream = builder.finish()  | 
|
84  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
85  | 
self.assertEqual(  | 
86  | 
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=1\n"  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
87  | 
"akey\x00secondpart\x00\x00\x00data\n\n", contents)  | 
88  | 
||
| 
2592.1.21
by Robert Collins
 Empty values are ok.  | 
89  | 
def test_add_node_empty_value(self):  | 
90  | 
builder = GraphIndexBuilder()  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
91  | 
builder.add_node(('akey', ), '')  | 
| 
2592.1.21
by Robert Collins
 Empty values are ok.  | 
92  | 
stream = builder.finish()  | 
93  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
94  | 
self.assertEqual(  | 
95  | 
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"  | 
|
| 
2592.1.43
by Robert Collins
 Various index tweaks and test clarity from John's review.  | 
96  | 
"akey\x00\x00\x00\n\n", contents)  | 
| 
2592.1.21
by Robert Collins
 Empty values are ok.  | 
97  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
98  | 
def test_build_index_nodes_sorted(self):  | 
| 
2592.1.17
by Robert Collins
 Multi node sort order is defined.  | 
99  | 
        # the highest sorted node comes first.
 | 
100  | 
builder = GraphIndexBuilder()  | 
|
101  | 
        # use three to have a good chance of glitching dictionary hash
 | 
|
102  | 
        # lookups etc. Insert in randomish order that is not correct
 | 
|
103  | 
        # and not the reverse of the correct order.
 | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
104  | 
builder.add_node(('2002', ), 'data')  | 
105  | 
builder.add_node(('2000', ), 'data')  | 
|
106  | 
builder.add_node(('2001', ), 'data')  | 
|
| 
2592.1.17
by Robert Collins
 Multi node sort order is defined.  | 
107  | 
stream = builder.finish()  | 
108  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
109  | 
self.assertEqual(  | 
110  | 
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=3\n"  | 
|
| 
2592.1.43
by Robert Collins
 Various index tweaks and test clarity from John's review.  | 
111  | 
"2000\x00\x00\x00data\n"  | 
112  | 
"2001\x00\x00\x00data\n"  | 
|
113  | 
"2002\x00\x00\x00data\n"  | 
|
| 
2592.1.17
by Robert Collins
 Multi node sort order is defined.  | 
114  | 
"\n", contents)  | 
115  | 
||
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
116  | 
def test_build_index_2_element_key_nodes_sorted(self):  | 
117  | 
        # multiple element keys are sorted first-key, second-key.
 | 
|
118  | 
builder = GraphIndexBuilder(key_elements=2)  | 
|
119  | 
        # use three values of each key element, to have a good chance of
 | 
|
120  | 
        # glitching dictionary hash lookups etc. Insert in randomish order that
 | 
|
121  | 
        # is not correct and not the reverse of the correct order.
 | 
|
122  | 
builder.add_node(('2002', '2002'), 'data')  | 
|
123  | 
builder.add_node(('2002', '2000'), 'data')  | 
|
124  | 
builder.add_node(('2002', '2001'), 'data')  | 
|
125  | 
builder.add_node(('2000', '2002'), 'data')  | 
|
126  | 
builder.add_node(('2000', '2000'), 'data')  | 
|
127  | 
builder.add_node(('2000', '2001'), 'data')  | 
|
128  | 
builder.add_node(('2001', '2002'), 'data')  | 
|
129  | 
builder.add_node(('2001', '2000'), 'data')  | 
|
130  | 
builder.add_node(('2001', '2001'), 'data')  | 
|
131  | 
stream = builder.finish()  | 
|
132  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
133  | 
self.assertEqual(  | 
134  | 
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=9\n"  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
135  | 
"2000\x002000\x00\x00\x00data\n"  | 
136  | 
"2000\x002001\x00\x00\x00data\n"  | 
|
137  | 
"2000\x002002\x00\x00\x00data\n"  | 
|
138  | 
"2001\x002000\x00\x00\x00data\n"  | 
|
139  | 
"2001\x002001\x00\x00\x00data\n"  | 
|
140  | 
"2001\x002002\x00\x00\x00data\n"  | 
|
141  | 
"2002\x002000\x00\x00\x00data\n"  | 
|
142  | 
"2002\x002001\x00\x00\x00data\n"  | 
|
143  | 
"2002\x002002\x00\x00\x00data\n"  | 
|
144  | 
"\n", contents)  | 
|
145  | 
||
| 
2592.1.19
by Robert Collins
 Node references are tab separated.  | 
146  | 
def test_build_index_reference_lists_are_included_one(self):  | 
147  | 
builder = GraphIndexBuilder(reference_lists=1)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
148  | 
builder.add_node(('key', ), 'data', ([], ))  | 
| 
2592.1.19
by Robert Collins
 Node references are tab separated.  | 
149  | 
stream = builder.finish()  | 
150  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
151  | 
self.assertEqual(  | 
152  | 
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"  | 
|
| 
2592.1.43
by Robert Collins
 Various index tweaks and test clarity from John's review.  | 
153  | 
"key\x00\x00\x00data\n"  | 
| 
2592.1.19
by Robert Collins
 Node references are tab separated.  | 
154  | 
"\n", contents)  | 
155  | 
||
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
156  | 
def test_build_index_reference_lists_with_2_element_keys(self):  | 
157  | 
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)  | 
|
158  | 
builder.add_node(('key', 'key2'), 'data', ([], ))  | 
|
159  | 
stream = builder.finish()  | 
|
160  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
161  | 
self.assertEqual(  | 
162  | 
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\nlen=1\n"  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
163  | 
"key\x00key2\x00\x00\x00data\n"  | 
164  | 
"\n", contents)  | 
|
165  | 
||
| 
2592.1.19
by Robert Collins
 Node references are tab separated.  | 
166  | 
def test_build_index_reference_lists_are_included_two(self):  | 
167  | 
builder = GraphIndexBuilder(reference_lists=2)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
168  | 
builder.add_node(('key', ), 'data', ([], []))  | 
| 
2592.1.19
by Robert Collins
 Node references are tab separated.  | 
169  | 
stream = builder.finish()  | 
170  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
171  | 
self.assertEqual(  | 
172  | 
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"  | 
|
| 
2592.1.43
by Robert Collins
 Various index tweaks and test clarity from John's review.  | 
173  | 
"key\x00\x00\t\x00data\n"  | 
| 
2592.1.19
by Robert Collins
 Node references are tab separated.  | 
174  | 
"\n", contents)  | 
175  | 
||
| 
4744.2.7
by John Arbash Meinel
 Add .clear_cache() members to GraphIndexBuilder and BTreeBuilder.  | 
176  | 
def test_clear_cache(self):  | 
177  | 
builder = GraphIndexBuilder(reference_lists=2)  | 
|
178  | 
        # This is a no-op, but the api should exist
 | 
|
179  | 
builder.clear_cache()  | 
|
180  | 
||
| 
2592.1.22
by Robert Collins
 Node references are byte offsets.  | 
181  | 
def test_node_references_are_byte_offsets(self):  | 
182  | 
builder = GraphIndexBuilder(reference_lists=1)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
183  | 
builder.add_node(('reference', ), 'data', ([], ))  | 
184  | 
builder.add_node(('key', ), 'data', ([('reference', )], ))  | 
|
| 
2592.1.22
by Robert Collins
 Node references are byte offsets.  | 
185  | 
stream = builder.finish()  | 
186  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
187  | 
self.assertEqual(  | 
188  | 
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=2\n"  | 
|
189  | 
"key\x00\x0072\x00data\n"  | 
|
| 
2592.1.40
by Robert Collins
 Reverse index ordering - we do not have date prefixed revids.  | 
190  | 
"reference\x00\x00\x00data\n"  | 
| 
2592.1.22
by Robert Collins
 Node references are byte offsets.  | 
191  | 
"\n", contents)  | 
192  | 
||
| 
2592.1.23
by Robert Collins
 node reference delimiting tested.  | 
193  | 
def test_node_references_are_cr_delimited(self):  | 
194  | 
builder = GraphIndexBuilder(reference_lists=1)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
195  | 
builder.add_node(('reference', ), 'data', ([], ))  | 
196  | 
builder.add_node(('reference2', ), 'data', ([], ))  | 
|
197  | 
builder.add_node(('key', ), 'data', ([('reference', ), ('reference2', )], ))  | 
|
| 
2592.1.23
by Robert Collins
 node reference delimiting tested.  | 
198  | 
stream = builder.finish()  | 
199  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
200  | 
self.assertEqual(  | 
201  | 
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=3\n"  | 
|
202  | 
"key\x00\x00077\r094\x00data\n"  | 
|
| 
2592.1.43
by Robert Collins
 Various index tweaks and test clarity from John's review.  | 
203  | 
"reference\x00\x00\x00data\n"  | 
204  | 
"reference2\x00\x00\x00data\n"  | 
|
| 
2592.1.23
by Robert Collins
 node reference delimiting tested.  | 
205  | 
"\n", contents)  | 
206  | 
||
| 
2592.1.24
by Robert Collins
 Delimiting of multiple reference lists is by \t  | 
207  | 
def test_multiple_reference_lists_are_tab_delimited(self):  | 
208  | 
builder = GraphIndexBuilder(reference_lists=2)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
209  | 
builder.add_node(('keference', ), 'data', ([], []))  | 
210  | 
builder.add_node(('rey', ), 'data', ([('keference', )], [('keference', )]))  | 
|
| 
2592.1.24
by Robert Collins
 Delimiting of multiple reference lists is by \t  | 
211  | 
stream = builder.finish()  | 
212  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
213  | 
self.assertEqual(  | 
214  | 
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=2\n"  | 
|
| 
2592.1.43
by Robert Collins
 Various index tweaks and test clarity from John's review.  | 
215  | 
"keference\x00\x00\t\x00data\n"  | 
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
216  | 
"rey\x00\x0059\t59\x00data\n"  | 
| 
2592.1.24
by Robert Collins
 Delimiting of multiple reference lists is by \t  | 
217  | 
"\n", contents)  | 
218  | 
||
| 
2592.1.25
by Robert Collins
 Fix and tune node offset calculation.  | 
219  | 
def test_add_node_referencing_missing_key_makes_absent(self):  | 
220  | 
builder = GraphIndexBuilder(reference_lists=1)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
221  | 
builder.add_node(('rey', ), 'data', ([('beference', ), ('aeference2', )], ))  | 
| 
2592.1.25
by Robert Collins
 Fix and tune node offset calculation.  | 
222  | 
stream = builder.finish()  | 
223  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
224  | 
self.assertEqual(  | 
225  | 
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"  | 
|
| 
2592.1.43
by Robert Collins
 Various index tweaks and test clarity from John's review.  | 
226  | 
"aeference2\x00a\x00\x00\n"  | 
227  | 
"beference\x00a\x00\x00\n"  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
228  | 
"rey\x00\x00074\r059\x00data\n"  | 
| 
2592.1.25
by Robert Collins
 Fix and tune node offset calculation.  | 
229  | 
"\n", contents)  | 
230  | 
||
| 
2592.1.26
by Robert Collins
 Test digit buffering is accurate.  | 
231  | 
def test_node_references_three_digits(self):  | 
232  | 
        # test the node digit expands as needed.
 | 
|
233  | 
builder = GraphIndexBuilder(reference_lists=1)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
234  | 
references = [(str(val), ) for val in reversed(range(9))]  | 
235  | 
builder.add_node(('2-key', ), '', (references, ))  | 
|
| 
2592.1.26
by Robert Collins
 Test digit buffering is accurate.  | 
236  | 
stream = builder.finish()  | 
237  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
238  | 
self.assertEqual(  | 
239  | 
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"  | 
|
| 
2592.1.40
by Robert Collins
 Reverse index ordering - we do not have date prefixed revids.  | 
240  | 
"0\x00a\x00\x00\n"  | 
241  | 
"1\x00a\x00\x00\n"  | 
|
242  | 
"2\x00a\x00\x00\n"  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
243  | 
"2-key\x00\x00151\r145\r139\r133\r127\r121\r071\r065\r059\x00\n"  | 
| 
2592.1.40
by Robert Collins
 Reverse index ordering - we do not have date prefixed revids.  | 
244  | 
"3\x00a\x00\x00\n"  | 
245  | 
"4\x00a\x00\x00\n"  | 
|
246  | 
"5\x00a\x00\x00\n"  | 
|
247  | 
"6\x00a\x00\x00\n"  | 
|
248  | 
"7\x00a\x00\x00\n"  | 
|
| 
2592.1.26
by Robert Collins
 Test digit buffering is accurate.  | 
249  | 
"8\x00a\x00\x00\n"  | 
| 
2592.1.40
by Robert Collins
 Reverse index ordering - we do not have date prefixed revids.  | 
250  | 
"\n", contents)  | 
251  | 
||
252  | 
def test_absent_has_no_reference_overhead(self):  | 
|
253  | 
        # the offsets after an absent record should be correct when there are
 | 
|
254  | 
        # >1 reference lists.
 | 
|
255  | 
builder = GraphIndexBuilder(reference_lists=2)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
256  | 
builder.add_node(('parent', ), '', ([('aail', ), ('zther', )], []))  | 
| 
2592.1.40
by Robert Collins
 Reverse index ordering - we do not have date prefixed revids.  | 
257  | 
stream = builder.finish()  | 
258  | 
contents = stream.read()  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
259  | 
self.assertEqual(  | 
260  | 
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"  | 
|
| 
2592.1.40
by Robert Collins
 Reverse index ordering - we do not have date prefixed revids.  | 
261  | 
"aail\x00a\x00\x00\n"  | 
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
262  | 
"parent\x00\x0059\r84\t\x00\n"  | 
| 
2592.1.40
by Robert Collins
 Reverse index ordering - we do not have date prefixed revids.  | 
263  | 
"zther\x00a\x00\x00\n"  | 
| 
2592.1.26
by Robert Collins
 Test digit buffering is accurate.  | 
264  | 
"\n", contents)  | 
265  | 
||
| 
2592.1.13
by Robert Collins
 Handle mismatched numbers of reference lists.  | 
266  | 
def test_add_node_bad_key(self):  | 
| 
2592.1.12
by Robert Collins
 Handle basic node adds.  | 
267  | 
builder = GraphIndexBuilder()  | 
| 
2592.1.14
by Robert Collins
 Detect bad reference key values.  | 
268  | 
for bad_char in '\t\n\x0b\x0c\r\x00 ':  | 
269  | 
self.assertRaises(errors.BadIndexKey, builder.add_node,  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
270  | 
('a%skey' % bad_char, ), 'data')  | 
271  | 
self.assertRaises(errors.BadIndexKey, builder.add_node,  | 
|
272  | 
('', ), 'data')  | 
|
273  | 
self.assertRaises(errors.BadIndexKey, builder.add_node,  | 
|
274  | 
'not-a-tuple', 'data')  | 
|
275  | 
        # not enough length
 | 
|
276  | 
self.assertRaises(errors.BadIndexKey, builder.add_node,  | 
|
277  | 
(), 'data')  | 
|
278  | 
        # too long
 | 
|
279  | 
self.assertRaises(errors.BadIndexKey, builder.add_node,  | 
|
280  | 
('primary', 'secondary'), 'data')  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
281  | 
        # secondary key elements get checked too:
 | 
282  | 
builder = GraphIndexBuilder(key_elements=2)  | 
|
283  | 
for bad_char in '\t\n\x0b\x0c\r\x00 ':  | 
|
284  | 
self.assertRaises(errors.BadIndexKey, builder.add_node,  | 
|
285  | 
('prefix', 'a%skey' % bad_char), 'data')  | 
|
| 
2592.1.12
by Robert Collins
 Handle basic node adds.  | 
286  | 
|
| 
2592.1.13
by Robert Collins
 Handle mismatched numbers of reference lists.  | 
287  | 
def test_add_node_bad_data(self):  | 
| 
2592.1.12
by Robert Collins
 Handle basic node adds.  | 
288  | 
builder = GraphIndexBuilder()  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
289  | 
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
290  | 
'data\naa')  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
291  | 
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
292  | 
'data\x00aa')  | 
| 
2592.1.12
by Robert Collins
 Handle basic node adds.  | 
293  | 
|
| 
2592.1.13
by Robert Collins
 Handle mismatched numbers of reference lists.  | 
294  | 
def test_add_node_bad_mismatched_ref_lists_length(self):  | 
295  | 
builder = GraphIndexBuilder()  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
296  | 
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
297  | 
'data aa', ([], ))  | 
| 
2592.1.13
by Robert Collins
 Handle mismatched numbers of reference lists.  | 
298  | 
builder = GraphIndexBuilder(reference_lists=1)  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
299  | 
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
300  | 
'data aa')  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
301  | 
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
302  | 
'data aa', (), )  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
303  | 
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
304  | 
'data aa', ([], []))  | 
| 
2592.1.13
by Robert Collins
 Handle mismatched numbers of reference lists.  | 
305  | 
builder = GraphIndexBuilder(reference_lists=2)  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
306  | 
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
307  | 
'data aa')  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
308  | 
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
309  | 
'data aa', ([], ))  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
310  | 
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
311  | 
'data aa', ([], [], []))  | 
| 
2592.1.13
by Robert Collins
 Handle mismatched numbers of reference lists.  | 
312  | 
|
| 
2592.1.14
by Robert Collins
 Detect bad reference key values.  | 
313  | 
def test_add_node_bad_key_in_reference_lists(self):  | 
314  | 
        # first list, first key - trivial
 | 
|
315  | 
builder = GraphIndexBuilder(reference_lists=1)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
316  | 
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),  | 
317  | 
'data aa', ([('a key', )], ))  | 
|
318  | 
        # references keys must be tuples too
 | 
|
319  | 
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),  | 
|
320  | 
'data aa', (['not-a-tuple'], ))  | 
|
321  | 
        # not enough length
 | 
|
322  | 
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),  | 
|
323  | 
'data aa', ([()], ))  | 
|
324  | 
        # too long
 | 
|
325  | 
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),  | 
|
326  | 
'data aa', ([('primary', 'secondary')], ))  | 
|
| 
2592.1.14
by Robert Collins
 Detect bad reference key values.  | 
327  | 
        # need to check more than the first key in the list
 | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
328  | 
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),  | 
329  | 
'data aa', ([('agoodkey', ), ('that is a bad key', )], ))  | 
|
| 
2592.1.14
by Robert Collins
 Detect bad reference key values.  | 
330  | 
        # and if there is more than one list it should be getting checked
 | 
331  | 
        # too
 | 
|
332  | 
builder = GraphIndexBuilder(reference_lists=2)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
333  | 
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),  | 
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
334  | 
'data aa', ([], ['a bad key']))  | 
| 
2592.1.14
by Robert Collins
 Detect bad reference key values.  | 
335  | 
|
| 
2592.1.15
by Robert Collins
 Detect duplicate key insertion.  | 
336  | 
def test_add_duplicate_key(self):  | 
337  | 
builder = GraphIndexBuilder()  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
338  | 
builder.add_node(('key', ), 'data')  | 
339  | 
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node, ('key', ),  | 
|
| 
2592.1.46
by Robert Collins
 Make GraphIndex accept nodes as key, value, references, so that the method  | 
340  | 
'data')  | 
| 
2592.1.15
by Robert Collins
 Detect duplicate key insertion.  | 
341  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
342  | 
def test_add_duplicate_key_2_elements(self):  | 
343  | 
builder = GraphIndexBuilder(key_elements=2)  | 
|
344  | 
builder.add_node(('key', 'key'), 'data')  | 
|
345  | 
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node,  | 
|
346  | 
('key', 'key'), 'data')  | 
|
347  | 
||
| 
2592.1.16
by Robert Collins
 Can add keys after referencing them.  | 
348  | 
def test_add_key_after_referencing_key(self):  | 
349  | 
builder = GraphIndexBuilder(reference_lists=1)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
350  | 
builder.add_node(('key', ), 'data', ([('reference', )], ))  | 
351  | 
builder.add_node(('reference', ), 'data', ([],))  | 
|
| 
2592.1.16
by Robert Collins
 Can add keys after referencing them.  | 
352  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
353  | 
def test_add_key_after_referencing_key_2_elements(self):  | 
354  | 
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)  | 
|
355  | 
builder.add_node(('k', 'ey'), 'data', ([('reference', 'tokey')], ))  | 
|
356  | 
builder.add_node(('reference', 'tokey'), 'data', ([],))  | 
|
357  | 
||
| 
3777.5.3
by John Arbash Meinel
 Add Builder.set_optimize(for_size=True) for GraphIndexBuilder and BTreeBuilder.  | 
358  | 
def test_set_optimize(self):  | 
359  | 
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)  | 
|
360  | 
builder.set_optimize(for_size=True)  | 
|
361  | 
self.assertTrue(builder._optimize_for_size)  | 
|
362  | 
builder.set_optimize(for_size=False)  | 
|
363  | 
self.assertFalse(builder._optimize_for_size)  | 
|
364  | 
||
| 
2592.1.5
by Robert Collins
 Trivial index reading.  | 
365  | 
|
366  | 
class TestGraphIndex(TestCaseWithMemoryTransport):  | 
|
367  | 
||
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
368  | 
def make_key(self, number):  | 
369  | 
return (str(number) + 'X'*100,)  | 
|
370  | 
||
371  | 
def make_value(self, number):  | 
|
372  | 
return str(number) + 'Y'*100  | 
|
373  | 
||
374  | 
def make_nodes(self, count=64):  | 
|
375  | 
        # generate a big enough index that we only read some of it on a typical
 | 
|
376  | 
        # bisection lookup.
 | 
|
377  | 
nodes = []  | 
|
378  | 
for counter in range(count):  | 
|
379  | 
nodes.append((self.make_key(counter), self.make_value(counter), ()))  | 
|
380  | 
return nodes  | 
|
381  | 
||
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
382  | 
def make_index(self, ref_lists=0, key_elements=1, nodes=[]):  | 
383  | 
builder = GraphIndexBuilder(ref_lists, key_elements=key_elements)  | 
|
| 
2624.2.17
by Robert Collins
 Review feedback.  | 
384  | 
for key, value, references in nodes:  | 
385  | 
builder.add_node(key, value, references)  | 
|
| 
2592.1.5
by Robert Collins
 Trivial index reading.  | 
386  | 
stream = builder.finish()  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
387  | 
trans = get_transport('trace+' + self.get_url())  | 
| 
2890.2.1
by Robert Collins
 * ``bzrlib.index.GraphIndex`` now requires a size parameter to the  | 
388  | 
size = trans.put_file('index', stream)  | 
389  | 
return GraphIndex(trans, 'index', size)  | 
|
| 
2592.1.5
by Robert Collins
 Trivial index reading.  | 
390  | 
|
| 
4744.2.6
by John Arbash Meinel
 Start exposing an GraphIndex.clear_cache() member.  | 
391  | 
def test_clear_cache(self):  | 
392  | 
index = self.make_index()  | 
|
393  | 
        # For now, we just want to make sure the api is available. As this is
 | 
|
394  | 
        # old code, we don't really worry if it *does* anything.
 | 
|
395  | 
index.clear_cache()  | 
|
396  | 
||
| 
2592.1.7
by Robert Collins
 A validate that goes boom.  | 
397  | 
def test_open_bad_index_no_error(self):  | 
398  | 
trans = self.get_transport()  | 
|
399  | 
trans.put_bytes('name', "not an index\n")  | 
|
| 
2890.2.1
by Robert Collins
 * ``bzrlib.index.GraphIndex`` now requires a size parameter to the  | 
400  | 
index = GraphIndex(trans, 'name', 13)  | 
| 
2592.1.7
by Robert Collins
 A validate that goes boom.  | 
401  | 
|
| 
2890.2.2
by Robert Collins
 Opening an index creates a map for the parsed bytes.  | 
402  | 
def test_open_sets_parsed_map_empty(self):  | 
403  | 
index = self.make_index()  | 
|
404  | 
self.assertEqual([], index._parsed_byte_map)  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
405  | 
self.assertEqual([], index._parsed_key_map)  | 
406  | 
||
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
407  | 
def test_key_count_buffers(self):  | 
408  | 
index = self.make_index(nodes=self.make_nodes(2))  | 
|
409  | 
        # reset the transport log
 | 
|
410  | 
del index._transport._activity[:]  | 
|
411  | 
self.assertEqual(2, index.key_count())  | 
|
412  | 
        # We should have requested reading the header bytes
 | 
|
413  | 
self.assertEqual([  | 
|
414  | 
('readv', 'index', [(0, 200)], True, index._size),  | 
|
415  | 
            ],
 | 
|
416  | 
index._transport._activity)  | 
|
417  | 
        # And that should have been enough to trigger reading the whole index
 | 
|
418  | 
        # with buffering
 | 
|
419  | 
self.assertIsNot(None, index._nodes)  | 
|
420  | 
||
421  | 
def test_lookup_key_via_location_buffers(self):  | 
|
422  | 
index = self.make_index()  | 
|
423  | 
        # reset the transport log
 | 
|
424  | 
del index._transport._activity[:]  | 
|
425  | 
        # do a _lookup_keys_via_location call for the middle of the file, which
 | 
|
426  | 
        # is what bisection uses.
 | 
|
427  | 
result = index._lookup_keys_via_location(  | 
|
428  | 
[(index._size // 2, ('missing', ))])  | 
|
429  | 
        # this should have asked for a readv request, with adjust_for_latency,
 | 
|
430  | 
        # and two regions: the header, and half-way into the file.
 | 
|
431  | 
self.assertEqual([  | 
|
432  | 
('readv', 'index', [(30, 30), (0, 200)], True, 60),  | 
|
433  | 
            ],
 | 
|
434  | 
index._transport._activity)  | 
|
435  | 
        # and the result should be that the key cannot be present, because this
 | 
|
436  | 
        # is a trivial index.
 | 
|
437  | 
self.assertEqual([((index._size // 2, ('missing', )), False)],  | 
|
438  | 
result)  | 
|
439  | 
        # And this should have caused the file to be fully buffered
 | 
|
440  | 
self.assertIsNot(None, index._nodes)  | 
|
441  | 
self.assertEqual([], index._parsed_byte_map)  | 
|
442  | 
||
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
443  | 
def test_first_lookup_key_via_location(self):  | 
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
444  | 
        # We need enough data so that the _HEADER_READV doesn't consume the
 | 
445  | 
        # whole file. We always read 800 bytes for every key, and the local
 | 
|
446  | 
        # transport natural expansion is 4096 bytes. So we have to have >8192
 | 
|
447  | 
        # bytes or we will trigger "buffer_all".
 | 
|
448  | 
        # We also want the 'missing' key to fall within the range that *did*
 | 
|
449  | 
        # read
 | 
|
450  | 
nodes = []  | 
|
451  | 
index = self.make_index(nodes=self.make_nodes(64))  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
452  | 
        # reset the transport log
 | 
453  | 
del index._transport._activity[:]  | 
|
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
454  | 
        # do a _lookup_keys_via_location call for the middle of the file, which
 | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
455  | 
        # is what bisection uses.
 | 
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
456  | 
start_lookup = index._size // 2  | 
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
457  | 
result = index._lookup_keys_via_location(  | 
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
458  | 
[(start_lookup, ('40missing', ))])  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
459  | 
        # this should have asked for a readv request, with adjust_for_latency,
 | 
460  | 
        # and two regions: the header, and half-way into the file.
 | 
|
461  | 
self.assertEqual([  | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
462  | 
('readv', 'index',  | 
463  | 
[(start_lookup, 800), (0, 200)], True, index._size),  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
464  | 
            ],
 | 
465  | 
index._transport._activity)  | 
|
466  | 
        # and the result should be that the key cannot be present, because this
 | 
|
467  | 
        # is a trivial index.
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
468  | 
self.assertEqual([((start_lookup, ('40missing', )), False)],  | 
469  | 
result)  | 
|
470  | 
        # And this should not have caused the file to be fully buffered
 | 
|
471  | 
self.assertIs(None, index._nodes)  | 
|
472  | 
        # And the regions of the file that have been parsed should be in the
 | 
|
473  | 
        # parsed_byte_map and the parsed_key_map
 | 
|
474  | 
self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)  | 
|
475  | 
self.assertEqual([(None, self.make_key(26)),  | 
|
476  | 
(self.make_key(31), self.make_key(48))],  | 
|
477  | 
index._parsed_key_map)  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
478  | 
|
479  | 
def test_parsing_non_adjacent_data_trims(self):  | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
480  | 
index = self.make_index(nodes=self.make_nodes(64))  | 
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
481  | 
result = index._lookup_keys_via_location(  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
482  | 
[(index._size // 2, ('40', ))])  | 
483  | 
        # and the result should be that the key cannot be present, because key is
 | 
|
484  | 
        # in the middle of the observed data from a 4K read - the smallest transport
 | 
|
485  | 
        # will do today with this api.
 | 
|
486  | 
self.assertEqual([((index._size // 2, ('40', )), False)],  | 
|
487  | 
result)  | 
|
488  | 
        # and we should have a parse map that includes the header and the
 | 
|
489  | 
        # region that was parsed after trimming.
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
490  | 
self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)  | 
491  | 
self.assertEqual([(None, self.make_key(26)),  | 
|
492  | 
(self.make_key(31), self.make_key(48))],  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
493  | 
index._parsed_key_map)  | 
494  | 
||
| 
2890.2.14
by Robert Collins
 Parse more than one segment of data from a single readv response if needed.  | 
495  | 
def test_parsing_data_handles_parsed_contained_regions(self):  | 
496  | 
        # the following patten creates a parsed region that is wholly within a
 | 
|
497  | 
        # single result from the readv layer:
 | 
|
498  | 
        # .... single-read (readv-minimum-size) ...
 | 
|
499  | 
        # which then trims the start and end so the parsed size is < readv
 | 
|
500  | 
        # miniumum.
 | 
|
501  | 
        # then a dual lookup (or a reference lookup for that matter) which
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
502  | 
        # abuts or overlaps the parsed region on both sides will need to
 | 
| 
2890.2.14
by Robert Collins
 Parse more than one segment of data from a single readv response if needed.  | 
503  | 
        # discard the data in the middle, but parse the end as well.
 | 
504  | 
        #
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
505  | 
        # we test this by doing a single lookup to seed the data, then
 | 
506  | 
        # a lookup for two keys that are present, and adjacent -
 | 
|
| 
2890.2.14
by Robert Collins
 Parse more than one segment of data from a single readv response if needed.  | 
507  | 
        # we except both to be found, and the parsed byte map to include the
 | 
508  | 
        # locations of both keys.
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
509  | 
index = self.make_index(nodes=self.make_nodes(128))  | 
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
510  | 
result = index._lookup_keys_via_location(  | 
| 
2890.2.14
by Robert Collins
 Parse more than one segment of data from a single readv response if needed.  | 
511  | 
[(index._size // 2, ('40', ))])  | 
512  | 
        # and we should have a parse map that includes the header and the
 | 
|
513  | 
        # region that was parsed after trimming.
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
514  | 
self.assertEqual([(0, 4045), (11759, 15707)], index._parsed_byte_map)  | 
515  | 
self.assertEqual([(None, self.make_key(116)),  | 
|
516  | 
(self.make_key(35), self.make_key(51))],  | 
|
| 
2890.2.14
by Robert Collins
 Parse more than one segment of data from a single readv response if needed.  | 
517  | 
index._parsed_key_map)  | 
518  | 
        # now ask for two keys, right before and after the parsed region
 | 
|
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
519  | 
result = index._lookup_keys_via_location(  | 
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
520  | 
[(11450, self.make_key(34)), (15707, self.make_key(52))])  | 
| 
2890.2.14
by Robert Collins
 Parse more than one segment of data from a single readv response if needed.  | 
521  | 
self.assertEqual([  | 
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
522  | 
((11450, self.make_key(34)),  | 
523  | 
(index, self.make_key(34), self.make_value(34))),  | 
|
524  | 
((15707, self.make_key(52)),  | 
|
525  | 
(index, self.make_key(52), self.make_value(52))),  | 
|
| 
2890.2.14
by Robert Collins
 Parse more than one segment of data from a single readv response if needed.  | 
526  | 
            ],
 | 
527  | 
result)  | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
528  | 
self.assertEqual([(0, 4045), (9889, 17993)], index._parsed_byte_map)  | 
| 
2890.2.14
by Robert Collins
 Parse more than one segment of data from a single readv response if needed.  | 
529  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
530  | 
def test_lookup_missing_key_answers_without_io_when_map_permits(self):  | 
531  | 
        # generate a big enough index that we only read some of it on a typical
 | 
|
532  | 
        # bisection lookup.
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
533  | 
index = self.make_index(nodes=self.make_nodes(64))  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
534  | 
        # lookup the keys in the middle of the file
 | 
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
535  | 
result =index._lookup_keys_via_location(  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
536  | 
[(index._size // 2, ('40', ))])  | 
537  | 
        # check the parse map, this determines the test validity
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
538  | 
self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)  | 
539  | 
self.assertEqual([(None, self.make_key(26)),  | 
|
540  | 
(self.make_key(31), self.make_key(48))],  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
541  | 
index._parsed_key_map)  | 
542  | 
        # reset the transport log
 | 
|
543  | 
del index._transport._activity[:]  | 
|
544  | 
        # now looking up a key in the portion of the file already parsed should
 | 
|
545  | 
        # not create a new transport request, and should return False (cannot
 | 
|
546  | 
        # be in the index) - even when the byte location we ask for is outside
 | 
|
547  | 
        # the parsed region
 | 
|
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
548  | 
result = index._lookup_keys_via_location(  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
549  | 
[(4000, ('40', ))])  | 
550  | 
self.assertEqual([((4000, ('40', )), False)],  | 
|
551  | 
result)  | 
|
552  | 
self.assertEqual([], index._transport._activity)  | 
|
553  | 
||
554  | 
def test_lookup_present_key_answers_without_io_when_map_permits(self):  | 
|
555  | 
        # generate a big enough index that we only read some of it on a typical
 | 
|
556  | 
        # bisection lookup.
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
557  | 
index = self.make_index(nodes=self.make_nodes(64))  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
558  | 
        # lookup the keys in the middle of the file
 | 
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
559  | 
result =index._lookup_keys_via_location(  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
560  | 
[(index._size // 2, ('40', ))])  | 
561  | 
        # check the parse map, this determines the test validity
 | 
|
562  | 
self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)  | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
563  | 
self.assertEqual([(None, self.make_key(26)),  | 
564  | 
(self.make_key(31), self.make_key(48))],  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
565  | 
index._parsed_key_map)  | 
566  | 
        # reset the transport log
 | 
|
567  | 
del index._transport._activity[:]  | 
|
568  | 
        # now looking up a key in the portion of the file already parsed should
 | 
|
569  | 
        # not create a new transport request, and should return False (cannot
 | 
|
570  | 
        # be in the index) - even when the byte location we ask for is outside
 | 
|
571  | 
        # the parsed region
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
572  | 
        #
 | 
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
573  | 
result = index._lookup_keys_via_location([(4000, self.make_key(40))])  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
574  | 
self.assertEqual(  | 
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
575  | 
[((4000, self.make_key(40)),  | 
576  | 
(index, self.make_key(40), self.make_value(40)))],  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
577  | 
result)  | 
578  | 
self.assertEqual([], index._transport._activity)  | 
|
579  | 
||
580  | 
def test_lookup_key_below_probed_area(self):  | 
|
581  | 
        # generate a big enough index that we only read some of it on a typical
 | 
|
582  | 
        # bisection lookup.
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
583  | 
index = self.make_index(nodes=self.make_nodes(64))  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
584  | 
        # ask for the key in the middle, but a key that is located in the
 | 
585  | 
        # unparsed region before the middle.
 | 
|
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
586  | 
result =index._lookup_keys_via_location(  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
587  | 
[(index._size // 2, ('30', ))])  | 
588  | 
        # check the parse map, this determines the test validity
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
589  | 
self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)  | 
590  | 
self.assertEqual([(None, self.make_key(26)),  | 
|
591  | 
(self.make_key(31), self.make_key(48))],  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
592  | 
index._parsed_key_map)  | 
593  | 
self.assertEqual([((index._size // 2, ('30', )), -1)],  | 
|
594  | 
result)  | 
|
595  | 
||
596  | 
def test_lookup_key_above_probed_area(self):  | 
|
597  | 
        # generate a big enough index that we only read some of it on a typical
 | 
|
598  | 
        # bisection lookup.
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
599  | 
index = self.make_index(nodes=self.make_nodes(64))  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
600  | 
        # ask for the key in the middle, but a key that is located in the
 | 
601  | 
        # unparsed region after the middle.
 | 
|
| 
2890.2.18
by Robert Collins
 Review feedback.  | 
602  | 
result =index._lookup_keys_via_location(  | 
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
603  | 
[(index._size // 2, ('50', ))])  | 
604  | 
        # check the parse map, this determines the test validity
 | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
605  | 
self.assertEqual([(0, 4008), (5046, 8996)], index._parsed_byte_map)  | 
606  | 
self.assertEqual([(None, self.make_key(26)),  | 
|
607  | 
(self.make_key(31), self.make_key(48))],  | 
|
| 
2890.2.5
by Robert Collins
 Create a content lookup function for bisection in GraphIndex.  | 
608  | 
index._parsed_key_map)  | 
609  | 
self.assertEqual([((index._size // 2, ('50', )), +1)],  | 
|
610  | 
result)  | 
|
| 
2890.2.2
by Robert Collins
 Opening an index creates a map for the parsed bytes.  | 
611  | 
|
| 
2890.2.6
by Robert Collins
 Add support for key references to the index lookup_keys_via_location bisection interface.  | 
612  | 
def test_lookup_key_resolves_references(self):  | 
613  | 
        # generate a big enough index that we only read some of it on a typical
 | 
|
614  | 
        # bisection lookup.
 | 
|
615  | 
nodes = []  | 
|
| 
3665.3.5
by John Arbash Meinel
 Move the point at which we 'buffer_all' if we've read >50% of the index.  | 
616  | 
for counter in range(99):  | 
617  | 
nodes.append((self.make_key(counter), self.make_value(counter),  | 
|
618  | 
((self.make_key(counter + 20),),) ))  | 
|
619  | 
index = self.make_index(ref_lists=1, nodes=nodes)  | 
|
620  | 
        # lookup a key in the middle that does not exist, so that when we can
 | 
|
621  | 
        # check that the referred-to-keys are not accessed automatically.
 | 
|
622  | 
index_size = index._size  | 
|
623  | 
index_center = index_size // 2  | 
|
624  | 
result = index._lookup_keys_via_location(  | 
|
625  | 
[(index_center, ('40', ))])  | 
|
626  | 
        # check the parse map - only the start and middle should have been
 | 
|
627  | 
        # parsed.
 | 
|
628  | 
self.assertEqual([(0, 4027), (10198, 14028)], index._parsed_byte_map)  | 
|
629  | 
self.assertEqual([(None, self.make_key(17)),  | 
|
630  | 
(self.make_key(44), self.make_key(5))],  | 
|
631  | 
index._parsed_key_map)  | 
|
632  | 
        # and check the transport activity likewise.
 | 
|
633  | 
self.assertEqual(  | 
|
634  | 
[('readv', 'index', [(index_center, 800), (0, 200)], True,  | 
|
635  | 
index_size)],  | 
|
636  | 
index._transport._activity)  | 
|
637  | 
        # reset the transport log for testing the reference lookup
 | 
|
638  | 
del index._transport._activity[:]  | 
|
639  | 
        # now looking up a key in the portion of the file already parsed should
 | 
|
640  | 
        # only perform IO to resolve its key references.
 | 
|
641  | 
result = index._lookup_keys_via_location([(11000, self.make_key(45))])  | 
|
642  | 
self.assertEqual(  | 
|
643  | 
[((11000, self.make_key(45)),  | 
|
644  | 
(index, self.make_key(45), self.make_value(45),  | 
|
645  | 
((self.make_key(65),),)))],  | 
|
646  | 
result)  | 
|
647  | 
self.assertEqual([('readv', 'index', [(15093, 800)], True, index_size)],  | 
|
648  | 
index._transport._activity)  | 
|
649  | 
||
650  | 
def test_lookup_key_can_buffer_all(self):  | 
|
651  | 
nodes = []  | 
|
| 
2890.2.6
by Robert Collins
 Add support for key references to the index lookup_keys_via_location bisection interface.  | 
652  | 
for counter in range(64):  | 
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
653  | 
nodes.append((self.make_key(counter), self.make_value(counter),  | 
654  | 
((self.make_key(counter + 20),),) ))  | 
|
| 
2890.2.6
by Robert Collins
 Add support for key references to the index lookup_keys_via_location bisection interface.  | 
655  | 
index = self.make_index(ref_lists=1, nodes=nodes)  | 
656  | 
        # lookup a key in the middle that does not exist, so that when we can
 | 
|
657  | 
        # check that the referred-to-keys are not accessed automatically.
 | 
|
| 
3665.3.5
by John Arbash Meinel
 Move the point at which we 'buffer_all' if we've read >50% of the index.  | 
658  | 
index_size = index._size  | 
659  | 
index_center = index_size // 2  | 
|
660  | 
result = index._lookup_keys_via_location([(index_center, ('40', ))])  | 
|
| 
2890.2.6
by Robert Collins
 Add support for key references to the index lookup_keys_via_location bisection interface.  | 
661  | 
        # check the parse map - only the start and middle should have been
 | 
662  | 
        # parsed.
 | 
|
663  | 
self.assertEqual([(0, 3890), (6444, 10274)], index._parsed_byte_map)  | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
664  | 
self.assertEqual([(None, self.make_key(25)),  | 
665  | 
(self.make_key(37), self.make_key(52))],  | 
|
| 
2890.2.6
by Robert Collins
 Add support for key references to the index lookup_keys_via_location bisection interface.  | 
666  | 
index._parsed_key_map)  | 
667  | 
        # and check the transport activity likewise.
 | 
|
668  | 
self.assertEqual(  | 
|
| 
3665.3.5
by John Arbash Meinel
 Move the point at which we 'buffer_all' if we've read >50% of the index.  | 
669  | 
[('readv', 'index', [(index_center, 800), (0, 200)], True,  | 
670  | 
index_size)],  | 
|
| 
2890.2.6
by Robert Collins
 Add support for key references to the index lookup_keys_via_location bisection interface.  | 
671  | 
index._transport._activity)  | 
672  | 
        # reset the transport log for testing the reference lookup
 | 
|
673  | 
del index._transport._activity[:]  | 
|
674  | 
        # now looking up a key in the portion of the file already parsed should
 | 
|
675  | 
        # only perform IO to resolve its key references.
 | 
|
| 
3665.3.5
by John Arbash Meinel
 Move the point at which we 'buffer_all' if we've read >50% of the index.  | 
676  | 
result = index._lookup_keys_via_location([(7000, self.make_key(40))])  | 
| 
2890.2.6
by Robert Collins
 Add support for key references to the index lookup_keys_via_location bisection interface.  | 
677  | 
self.assertEqual(  | 
| 
3665.3.5
by John Arbash Meinel
 Move the point at which we 'buffer_all' if we've read >50% of the index.  | 
678  | 
[((7000, self.make_key(40)),  | 
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
679  | 
(index, self.make_key(40), self.make_value(40),  | 
680  | 
((self.make_key(60),),)))],  | 
|
| 
2890.2.6
by Robert Collins
 Add support for key references to the index lookup_keys_via_location bisection interface.  | 
681  | 
result)  | 
| 
3665.3.5
by John Arbash Meinel
 Move the point at which we 'buffer_all' if we've read >50% of the index.  | 
682  | 
        # Resolving the references would have required more data read, and we
 | 
683  | 
        # are already above the 50% threshold, so it triggered a _buffer_all
 | 
|
684  | 
self.assertEqual([('get', 'index')], index._transport._activity)  | 
|
| 
2890.2.6
by Robert Collins
 Add support for key references to the index lookup_keys_via_location bisection interface.  | 
685  | 
|
| 
2592.1.5
by Robert Collins
 Trivial index reading.  | 
686  | 
def test_iter_all_entries_empty(self):  | 
687  | 
index = self.make_index()  | 
|
688  | 
self.assertEqual([], list(index.iter_all_entries()))  | 
|
689  | 
||
| 
2592.1.27
by Robert Collins
 Test missing end lines with non-empty indices.  | 
690  | 
def test_iter_all_entries_simple(self):  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
691  | 
index = self.make_index(nodes=[(('name', ), 'data', ())])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
692  | 
self.assertEqual([(index, ('name', ), 'data')],  | 
| 
2592.1.27
by Robert Collins
 Test missing end lines with non-empty indices.  | 
693  | 
list(index.iter_all_entries()))  | 
694  | 
||
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
695  | 
def test_iter_all_entries_simple_2_elements(self):  | 
696  | 
index = self.make_index(key_elements=2,  | 
|
697  | 
nodes=[(('name', 'surname'), 'data', ())])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
698  | 
self.assertEqual([(index, ('name', 'surname'), 'data')],  | 
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
699  | 
list(index.iter_all_entries()))  | 
700  | 
||
| 
2592.1.28
by Robert Collins
 Basic two pass iter_all_entries.  | 
701  | 
def test_iter_all_entries_references_resolved(self):  | 
702  | 
index = self.make_index(1, nodes=[  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
703  | 
(('name', ), 'data', ([('ref', )], )),  | 
704  | 
(('ref', ), 'refdata', ([], ))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
705  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),  | 
706  | 
(index, ('ref', ), 'refdata', ((), ))]),  | 
|
| 
2592.1.28
by Robert Collins
 Basic two pass iter_all_entries.  | 
707  | 
set(index.iter_all_entries()))  | 
708  | 
||
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
709  | 
def test_iter_entries_buffers_once(self):  | 
710  | 
index = self.make_index(nodes=self.make_nodes(2))  | 
|
711  | 
        # reset the transport log
 | 
|
712  | 
del index._transport._activity[:]  | 
|
713  | 
self.assertEqual(set([(index, self.make_key(1), self.make_value(1))]),  | 
|
714  | 
set(index.iter_entries([self.make_key(1)])))  | 
|
715  | 
        # We should have requested reading the header bytes
 | 
|
716  | 
        # But not needed any more than that because it would have triggered a
 | 
|
717  | 
        # buffer all
 | 
|
718  | 
self.assertEqual([  | 
|
719  | 
('readv', 'index', [(0, 200)], True, index._size),  | 
|
720  | 
            ],
 | 
|
721  | 
index._transport._activity)  | 
|
722  | 
        # And that should have been enough to trigger reading the whole index
 | 
|
723  | 
        # with buffering
 | 
|
724  | 
self.assertIsNot(None, index._nodes)  | 
|
725  | 
||
| 
3665.3.3
by John Arbash Meinel
 If we read more than 50% of the whole index,  | 
726  | 
def test_iter_entries_buffers_by_bytes_read(self):  | 
727  | 
index = self.make_index(nodes=self.make_nodes(64))  | 
|
728  | 
list(index.iter_entries([self.make_key(10)]))  | 
|
729  | 
        # The first time through isn't enough to trigger a buffer all
 | 
|
730  | 
self.assertIs(None, index._nodes)  | 
|
731  | 
self.assertEqual(4096, index._bytes_read)  | 
|
732  | 
        # Grabbing a key in that same page won't trigger a buffer all, as we
 | 
|
733  | 
        # still haven't read 50% of the file
 | 
|
734  | 
list(index.iter_entries([self.make_key(11)]))  | 
|
735  | 
self.assertIs(None, index._nodes)  | 
|
736  | 
self.assertEqual(4096, index._bytes_read)  | 
|
737  | 
        # We haven't read more data, so reading outside the range won't trigger
 | 
|
738  | 
        # a buffer all right away
 | 
|
739  | 
list(index.iter_entries([self.make_key(40)]))  | 
|
740  | 
self.assertIs(None, index._nodes)  | 
|
741  | 
self.assertEqual(8192, index._bytes_read)  | 
|
| 
3665.3.5
by John Arbash Meinel
 Move the point at which we 'buffer_all' if we've read >50% of the index.  | 
742  | 
        # On the next pass, we will not trigger buffer all if the key is
 | 
743  | 
        # available without reading more
 | 
|
| 
3665.3.3
by John Arbash Meinel
 If we read more than 50% of the whole index,  | 
744  | 
list(index.iter_entries([self.make_key(32)]))  | 
| 
3665.3.5
by John Arbash Meinel
 Move the point at which we 'buffer_all' if we've read >50% of the index.  | 
745  | 
self.assertIs(None, index._nodes)  | 
746  | 
        # But if we *would* need to read more to resolve it, then we will
 | 
|
747  | 
        # buffer all.
 | 
|
748  | 
list(index.iter_entries([self.make_key(60)]))  | 
|
| 
3665.3.3
by John Arbash Meinel
 If we read more than 50% of the whole index,  | 
749  | 
self.assertIsNot(None, index._nodes)  | 
750  | 
||
| 
2890.2.10
by Robert Collins
 Add test coverage to ensure \r's are not mangled by bisection parsing.  | 
751  | 
def test_iter_entries_references_resolved(self):  | 
752  | 
index = self.make_index(1, nodes=[  | 
|
753  | 
(('name', ), 'data', ([('ref', ), ('ref', )], )),  | 
|
754  | 
(('ref', ), 'refdata', ([], ))])  | 
|
755  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),('ref',)),)),  | 
|
756  | 
(index, ('ref', ), 'refdata', ((), ))]),  | 
|
757  | 
set(index.iter_entries([('name',), ('ref',)])))  | 
|
758  | 
||
759  | 
def test_iter_entries_references_2_refs_resolved(self):  | 
|
760  | 
index = self.make_index(2, nodes=[  | 
|
761  | 
(('name', ), 'data', ([('ref', )], [('ref', )])),  | 
|
762  | 
(('ref', ), 'refdata', ([], []))])  | 
|
763  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),), (('ref',),))),  | 
|
764  | 
(index, ('ref', ), 'refdata', ((), ()))]),  | 
|
765  | 
set(index.iter_entries([('name',), ('ref',)])))  | 
|
766  | 
||
| 
2592.1.30
by Robert Collins
 Absent entries are not yeilded.  | 
767  | 
def test_iteration_absent_skipped(self):  | 
768  | 
index = self.make_index(1, nodes=[  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
769  | 
(('name', ), 'data', ([('ref', )], ))])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
770  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),  | 
| 
2592.1.30
by Robert Collins
 Absent entries are not yeilded.  | 
771  | 
set(index.iter_all_entries()))  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
772  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
773  | 
set(index.iter_entries([('name', )])))  | 
774  | 
self.assertEqual([], list(index.iter_entries([('ref', )])))  | 
|
| 
2592.1.30
by Robert Collins
 Absent entries are not yeilded.  | 
775  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
776  | 
def test_iteration_absent_skipped_2_element_keys(self):  | 
777  | 
index = self.make_index(1, key_elements=2, nodes=[  | 
|
778  | 
(('name', 'fin'), 'data', ([('ref', 'erence')], ))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
779  | 
self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),  | 
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
780  | 
set(index.iter_all_entries()))  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
781  | 
self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),  | 
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
782  | 
set(index.iter_entries([('name', 'fin')])))  | 
783  | 
self.assertEqual([], list(index.iter_entries([('ref', 'erence')])))  | 
|
784  | 
||
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
785  | 
def test_iter_all_keys(self):  | 
| 
2592.1.29
by Robert Collins
 Basic iter_entries working.  | 
786  | 
index = self.make_index(1, nodes=[  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
787  | 
(('name', ), 'data', ([('ref', )], )),  | 
788  | 
(('ref', ), 'refdata', ([], ))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
789  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),  | 
790  | 
(index, ('ref', ), 'refdata', ((), ))]),  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
791  | 
set(index.iter_entries([('name', ), ('ref', )])))  | 
| 
2592.1.29
by Robert Collins
 Basic iter_entries working.  | 
792  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
793  | 
def test_iter_nothing_empty(self):  | 
| 
2592.1.9
by Robert Collins
 Iterating no keys should work too.  | 
794  | 
index = self.make_index()  | 
795  | 
self.assertEqual([], list(index.iter_entries([])))  | 
|
796  | 
||
| 
2592.1.5
by Robert Collins
 Trivial index reading.  | 
797  | 
def test_iter_missing_entry_empty(self):  | 
798  | 
index = self.make_index()  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
799  | 
self.assertEqual([], list(index.iter_entries([('a', )])))  | 
| 
2592.1.7
by Robert Collins
 A validate that goes boom.  | 
800  | 
|
| 
2890.2.8
by Robert Collins
 Make the size of the index optionally None for the pack-names index.  | 
801  | 
def test_iter_missing_entry_empty_no_size(self):  | 
802  | 
index = self.make_index()  | 
|
803  | 
index = GraphIndex(index._transport, 'index', None)  | 
|
804  | 
self.assertEqual([], list(index.iter_entries([('a', )])))  | 
|
805  | 
||
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
806  | 
def test_iter_key_prefix_1_element_key_None(self):  | 
807  | 
index = self.make_index()  | 
|
808  | 
self.assertRaises(errors.BadIndexKey, list,  | 
|
809  | 
index.iter_entries_prefix([(None, )]))  | 
|
810  | 
||
811  | 
def test_iter_key_prefix_wrong_length(self):  | 
|
812  | 
index = self.make_index()  | 
|
813  | 
self.assertRaises(errors.BadIndexKey, list,  | 
|
814  | 
index.iter_entries_prefix([('foo', None)]))  | 
|
815  | 
index = self.make_index(key_elements=2)  | 
|
816  | 
self.assertRaises(errors.BadIndexKey, list,  | 
|
817  | 
index.iter_entries_prefix([('foo', )]))  | 
|
818  | 
self.assertRaises(errors.BadIndexKey, list,  | 
|
819  | 
index.iter_entries_prefix([('foo', None, None)]))  | 
|
820  | 
||
821  | 
def test_iter_key_prefix_1_key_element_no_refs(self):  | 
|
822  | 
index = self.make_index( nodes=[  | 
|
823  | 
(('name', ), 'data', ()),  | 
|
824  | 
(('ref', ), 'refdata', ())])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
825  | 
self.assertEqual(set([(index, ('name', ), 'data'),  | 
826  | 
(index, ('ref', ), 'refdata')]),  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
827  | 
set(index.iter_entries_prefix([('name', ), ('ref', )])))  | 
828  | 
||
829  | 
def test_iter_key_prefix_1_key_element_refs(self):  | 
|
830  | 
index = self.make_index(1, nodes=[  | 
|
831  | 
(('name', ), 'data', ([('ref', )], )),  | 
|
832  | 
(('ref', ), 'refdata', ([], ))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
833  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),  | 
834  | 
(index, ('ref', ), 'refdata', ((), ))]),  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
835  | 
set(index.iter_entries_prefix([('name', ), ('ref', )])))  | 
836  | 
||
837  | 
def test_iter_key_prefix_2_key_element_no_refs(self):  | 
|
838  | 
index = self.make_index(key_elements=2, nodes=[  | 
|
839  | 
(('name', 'fin1'), 'data', ()),  | 
|
840  | 
(('name', 'fin2'), 'beta', ()),  | 
|
841  | 
(('ref', 'erence'), 'refdata', ())])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
842  | 
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),  | 
843  | 
(index, ('ref', 'erence'), 'refdata')]),  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
844  | 
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
845  | 
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),  | 
846  | 
(index, ('name', 'fin2'), 'beta')]),  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
847  | 
set(index.iter_entries_prefix([('name', None)])))  | 
848  | 
||
849  | 
def test_iter_key_prefix_2_key_element_refs(self):  | 
|
850  | 
index = self.make_index(1, key_elements=2, nodes=[  | 
|
851  | 
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),  | 
|
852  | 
(('name', 'fin2'), 'beta', ([], )),  | 
|
853  | 
(('ref', 'erence'), 'refdata', ([], ))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
854  | 
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),  | 
855  | 
(index, ('ref', 'erence'), 'refdata', ((), ))]),  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
856  | 
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
857  | 
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),  | 
858  | 
(index, ('name', 'fin2'), 'beta', ((), ))]),  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
859  | 
set(index.iter_entries_prefix([('name', None)])))  | 
860  | 
||
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
861  | 
def test_key_count_empty(self):  | 
862  | 
index = self.make_index()  | 
|
863  | 
self.assertEqual(0, index.key_count())  | 
|
864  | 
||
865  | 
def test_key_count_one(self):  | 
|
866  | 
index = self.make_index(nodes=[(('name', ), '', ())])  | 
|
867  | 
self.assertEqual(1, index.key_count())  | 
|
868  | 
||
869  | 
def test_key_count_two(self):  | 
|
870  | 
index = self.make_index(nodes=[  | 
|
871  | 
(('name', ), '', ()), (('foo', ), '', ())])  | 
|
872  | 
self.assertEqual(2, index.key_count())  | 
|
873  | 
||
| 
3665.3.3
by John Arbash Meinel
 If we read more than 50% of the whole index,  | 
874  | 
def test_read_and_parse_tracks_real_read_value(self):  | 
875  | 
index = self.make_index(nodes=self.make_nodes(10))  | 
|
876  | 
del index._transport._activity[:]  | 
|
877  | 
index._read_and_parse([(0, 200)])  | 
|
878  | 
self.assertEqual([  | 
|
879  | 
('readv', 'index', [(0, 200)], True, index._size),  | 
|
880  | 
            ],
 | 
|
881  | 
index._transport._activity)  | 
|
882  | 
        # The readv expansion code will expand the initial request to 4096
 | 
|
883  | 
        # bytes, which is more than enough to read the entire index, and we
 | 
|
884  | 
        # will track the fact that we read that many bytes.
 | 
|
885  | 
self.assertEqual(index._size, index._bytes_read)  | 
|
886  | 
||
887  | 
def test_read_and_parse_triggers_buffer_all(self):  | 
|
| 
3665.3.1
by John Arbash Meinel
 Updates to GraphIndex processing.  | 
888  | 
index = self.make_index(key_elements=2, nodes=[  | 
889  | 
(('name', 'fin1'), 'data', ()),  | 
|
890  | 
(('name', 'fin2'), 'beta', ()),  | 
|
891  | 
(('ref', 'erence'), 'refdata', ())])  | 
|
892  | 
self.assertTrue(index._size > 0)  | 
|
893  | 
self.assertIs(None, index._nodes)  | 
|
894  | 
index._read_and_parse([(0, index._size)])  | 
|
895  | 
self.assertIsNot(None, index._nodes)  | 
|
896  | 
||
| 
2592.1.7
by Robert Collins
 A validate that goes boom.  | 
897  | 
def test_validate_bad_index_errors(self):  | 
898  | 
trans = self.get_transport()  | 
|
899  | 
trans.put_bytes('name', "not an index\n")  | 
|
| 
2890.2.1
by Robert Collins
 * ``bzrlib.index.GraphIndex`` now requires a size parameter to the  | 
900  | 
index = GraphIndex(trans, 'name', 13)  | 
| 
2592.1.7
by Robert Collins
 A validate that goes boom.  | 
901  | 
self.assertRaises(errors.BadIndexFormatSignature, index.validate)  | 
| 
2592.1.8
by Robert Collins
 Empty files should validate ok.  | 
902  | 
|
| 
2592.1.10
by Robert Collins
 Make validate detect node reference parsing errors.  | 
903  | 
def test_validate_bad_node_refs(self):  | 
904  | 
index = self.make_index(2)  | 
|
905  | 
trans = self.get_transport()  | 
|
906  | 
content = trans.get_bytes('index')  | 
|
907  | 
        # change the options line to end with a rather than a parseable number
 | 
|
908  | 
new_content = content[:-2] + 'a\n\n'  | 
|
909  | 
trans.put_bytes('index', new_content)  | 
|
910  | 
self.assertRaises(errors.BadIndexOptions, index.validate)  | 
|
911  | 
||
| 
2592.1.27
by Robert Collins
 Test missing end lines with non-empty indices.  | 
912  | 
def test_validate_missing_end_line_empty(self):  | 
| 
2592.1.11
by Robert Collins
 Detect truncated indices.  | 
913  | 
index = self.make_index(2)  | 
914  | 
trans = self.get_transport()  | 
|
915  | 
content = trans.get_bytes('index')  | 
|
916  | 
        # truncate the last byte
 | 
|
917  | 
trans.put_bytes('index', content[:-1])  | 
|
918  | 
self.assertRaises(errors.BadIndexData, index.validate)  | 
|
919  | 
||
| 
2592.1.27
by Robert Collins
 Test missing end lines with non-empty indices.  | 
920  | 
def test_validate_missing_end_line_nonempty(self):  | 
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
921  | 
index = self.make_index(2, nodes=[(('key', ), '', ([], []))])  | 
| 
2592.1.27
by Robert Collins
 Test missing end lines with non-empty indices.  | 
922  | 
trans = self.get_transport()  | 
923  | 
content = trans.get_bytes('index')  | 
|
924  | 
        # truncate the last byte
 | 
|
925  | 
trans.put_bytes('index', content[:-1])  | 
|
926  | 
self.assertRaises(errors.BadIndexData, index.validate)  | 
|
927  | 
||
| 
2592.1.8
by Robert Collins
 Empty files should validate ok.  | 
928  | 
def test_validate_empty(self):  | 
929  | 
index = self.make_index()  | 
|
930  | 
index.validate()  | 
|
| 
2592.1.12
by Robert Collins
 Handle basic node adds.  | 
931  | 
|
932  | 
def test_validate_no_refs_content(self):  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
933  | 
index = self.make_index(nodes=[(('key', ), 'value', ())])  | 
| 
2592.1.12
by Robert Collins
 Handle basic node adds.  | 
934  | 
index.validate()  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
935  | 
|
| 
4011.5.3
by Andrew Bennetts
 Implement and test external_references on GraphIndex and BTreeGraphIndex.  | 
936  | 
    # XXX: external_references tests are duplicated in test_btree_index.  We
 | 
937  | 
    # probably should have per_graph_index tests...
 | 
|
938  | 
def test_external_references_no_refs(self):  | 
|
939  | 
index = self.make_index(ref_lists=0, nodes=[])  | 
|
940  | 
self.assertRaises(ValueError, index.external_references, 0)  | 
|
941  | 
||
942  | 
def test_external_references_no_results(self):  | 
|
943  | 
index = self.make_index(ref_lists=1, nodes=[  | 
|
944  | 
(('key',), 'value', ([],))])  | 
|
945  | 
self.assertEqual(set(), index.external_references(0))  | 
|
946  | 
||
947  | 
def test_external_references_missing_ref(self):  | 
|
948  | 
missing_key = ('missing',)  | 
|
949  | 
index = self.make_index(ref_lists=1, nodes=[  | 
|
950  | 
(('key',), 'value', ([missing_key],))])  | 
|
951  | 
self.assertEqual(set([missing_key]), index.external_references(0))  | 
|
952  | 
||
953  | 
def test_external_references_multiple_ref_lists(self):  | 
|
954  | 
missing_key = ('missing',)  | 
|
955  | 
index = self.make_index(ref_lists=2, nodes=[  | 
|
956  | 
(('key',), 'value', ([], [missing_key]))])  | 
|
957  | 
self.assertEqual(set([]), index.external_references(0))  | 
|
958  | 
self.assertEqual(set([missing_key]), index.external_references(1))  | 
|
959  | 
||
960  | 
def test_external_references_two_records(self):  | 
|
961  | 
index = self.make_index(ref_lists=1, nodes=[  | 
|
962  | 
(('key-1',), 'value', ([('key-2',)],)),  | 
|
963  | 
(('key-2',), 'value', ([],)),  | 
|
964  | 
            ])
 | 
|
965  | 
self.assertEqual(set([]), index.external_references(0))  | 
|
966  | 
||
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
967  | 
def test__find_ancestors(self):  | 
| 
4593.4.7
by John Arbash Meinel
 Basic implementation of a conforming interface for GraphIndex.  | 
968  | 
key1 = ('key-1',)  | 
969  | 
key2 = ('key-2',)  | 
|
970  | 
index = self.make_index(ref_lists=1, key_elements=1, nodes=[  | 
|
971  | 
(key1, 'value', ([key2],)),  | 
|
972  | 
(key2, 'value', ([],)),  | 
|
973  | 
            ])
 | 
|
974  | 
parent_map = {}  | 
|
975  | 
missing_keys = set()  | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
976  | 
search_keys = index._find_ancestors([key1], 0, parent_map, missing_keys)  | 
| 
4593.4.7
by John Arbash Meinel
 Basic implementation of a conforming interface for GraphIndex.  | 
977  | 
self.assertEqual({key1: (key2,)}, parent_map)  | 
978  | 
self.assertEqual(set(), missing_keys)  | 
|
979  | 
self.assertEqual(set([key2]), search_keys)  | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
980  | 
search_keys = index._find_ancestors(search_keys, 0, parent_map,  | 
981  | 
missing_keys)  | 
|
| 
4593.4.7
by John Arbash Meinel
 Basic implementation of a conforming interface for GraphIndex.  | 
982  | 
self.assertEqual({key1: (key2,), key2: ()}, parent_map)  | 
983  | 
self.assertEqual(set(), missing_keys)  | 
|
984  | 
self.assertEqual(set(), search_keys)  | 
|
985  | 
||
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
986  | 
def test__find_ancestors_w_missing(self):  | 
| 
4593.4.7
by John Arbash Meinel
 Basic implementation of a conforming interface for GraphIndex.  | 
987  | 
key1 = ('key-1',)  | 
988  | 
key2 = ('key-2',)  | 
|
989  | 
key3 = ('key-3',)  | 
|
990  | 
index = self.make_index(ref_lists=1, key_elements=1, nodes=[  | 
|
991  | 
(key1, 'value', ([key2],)),  | 
|
992  | 
(key2, 'value', ([],)),  | 
|
993  | 
            ])
 | 
|
994  | 
parent_map = {}  | 
|
995  | 
missing_keys = set()  | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
996  | 
search_keys = index._find_ancestors([key2, key3], 0, parent_map,  | 
997  | 
missing_keys)  | 
|
| 
4593.4.7
by John Arbash Meinel
 Basic implementation of a conforming interface for GraphIndex.  | 
998  | 
self.assertEqual({key2: ()}, parent_map)  | 
999  | 
self.assertEqual(set([key3]), missing_keys)  | 
|
1000  | 
self.assertEqual(set(), search_keys)  | 
|
1001  | 
||
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1002  | 
def test__find_ancestors_dont_search_known(self):  | 
| 
4593.4.7
by John Arbash Meinel
 Basic implementation of a conforming interface for GraphIndex.  | 
1003  | 
key1 = ('key-1',)  | 
1004  | 
key2 = ('key-2',)  | 
|
1005  | 
key3 = ('key-3',)  | 
|
1006  | 
index = self.make_index(ref_lists=1, key_elements=1, nodes=[  | 
|
1007  | 
(key1, 'value', ([key2],)),  | 
|
1008  | 
(key2, 'value', ([key3],)),  | 
|
1009  | 
(key3, 'value', ([],)),  | 
|
1010  | 
            ])
 | 
|
1011  | 
        # We already know about key2, so we won't try to search for key3
 | 
|
1012  | 
parent_map = {key2: (key3,)}  | 
|
1013  | 
missing_keys = set()  | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1014  | 
search_keys = index._find_ancestors([key1], 0, parent_map,  | 
1015  | 
missing_keys)  | 
|
| 
4593.4.7
by John Arbash Meinel
 Basic implementation of a conforming interface for GraphIndex.  | 
1016  | 
self.assertEqual({key1: (key2,), key2: (key3,)}, parent_map)  | 
1017  | 
self.assertEqual(set(), missing_keys)  | 
|
1018  | 
self.assertEqual(set(), search_keys)  | 
|
1019  | 
||
| 
4634.71.1
by John Arbash Meinel
 Work around bug #402623 by allowing BTreeGraphIndex(...,unlimited_cache=True).  | 
1020  | 
def test_supports_unlimited_cache(self):  | 
1021  | 
builder = GraphIndexBuilder(0, key_elements=1)  | 
|
1022  | 
stream = builder.finish()  | 
|
1023  | 
trans = get_transport(self.get_url())  | 
|
1024  | 
size = trans.put_file('index', stream)  | 
|
1025  | 
        # It doesn't matter what unlimited_cache does here, just that it can be
 | 
|
1026  | 
        # passed
 | 
|
1027  | 
index = GraphIndex(trans, 'index', size, unlimited_cache=True)  | 
|
1028  | 
||
| 
4011.5.3
by Andrew Bennetts
 Implement and test external_references on GraphIndex and BTreeGraphIndex.  | 
1029  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1030  | 
class TestCombinedGraphIndex(TestCaseWithMemoryTransport):  | 
1031  | 
||
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
1032  | 
def make_index(self, name, ref_lists=0, key_elements=1, nodes=[]):  | 
1033  | 
builder = GraphIndexBuilder(ref_lists, key_elements=key_elements)  | 
|
| 
2624.2.17
by Robert Collins
 Review feedback.  | 
1034  | 
for key, value, references in nodes:  | 
1035  | 
builder.add_node(key, value, references)  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1036  | 
stream = builder.finish()  | 
1037  | 
trans = self.get_transport()  | 
|
| 
2890.2.1
by Robert Collins
 * ``bzrlib.index.GraphIndex`` now requires a size parameter to the  | 
1038  | 
size = trans.put_file(name, stream)  | 
1039  | 
return GraphIndex(trans, name, size)  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1040  | 
|
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1041  | 
def make_combined_index_with_missing(self, missing=['1', '2']):  | 
| 
3789.1.3
by John Arbash Meinel
 CombinedGraphIndex can now reload when calling key_count().  | 
1042  | 
"""Create a CombinedGraphIndex which will have missing indexes.  | 
1043  | 
||
1044  | 
        This creates a CGI which thinks it has 2 indexes, however they have
 | 
|
1045  | 
        been deleted. If CGI._reload_func() is called, then it will repopulate
 | 
|
1046  | 
        with a new index.
 | 
|
1047  | 
||
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1048  | 
        :param missing: The underlying indexes to delete
 | 
| 
3789.1.3
by John Arbash Meinel
 CombinedGraphIndex can now reload when calling key_count().  | 
1049  | 
        :return: (CombinedGraphIndex, reload_counter)
 | 
1050  | 
        """
 | 
|
1051  | 
index1 = self.make_index('1', nodes=[(('1',), '', ())])  | 
|
1052  | 
index2 = self.make_index('2', nodes=[(('2',), '', ())])  | 
|
1053  | 
index3 = self.make_index('3', nodes=[  | 
|
1054  | 
(('1',), '', ()),  | 
|
1055  | 
(('2',), '', ())])  | 
|
1056  | 
||
1057  | 
        # total_reloads, num_changed, num_unchanged
 | 
|
1058  | 
reload_counter = [0, 0, 0]  | 
|
1059  | 
def reload():  | 
|
1060  | 
reload_counter[0] += 1  | 
|
1061  | 
new_indices = [index3]  | 
|
1062  | 
if index._indices == new_indices:  | 
|
1063  | 
reload_counter[2] += 1  | 
|
1064  | 
return False  | 
|
1065  | 
reload_counter[1] += 1  | 
|
1066  | 
index._indices[:] = new_indices  | 
|
1067  | 
return True  | 
|
1068  | 
index = CombinedGraphIndex([index1, index2], reload_func=reload)  | 
|
1069  | 
trans = self.get_transport()  | 
|
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1070  | 
for fname in missing:  | 
1071  | 
trans.delete(fname)  | 
|
| 
3789.1.3
by John Arbash Meinel
 CombinedGraphIndex can now reload when calling key_count().  | 
1072  | 
return index, reload_counter  | 
1073  | 
||
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1074  | 
def test_open_missing_index_no_error(self):  | 
1075  | 
trans = self.get_transport()  | 
|
| 
2890.2.1
by Robert Collins
 * ``bzrlib.index.GraphIndex`` now requires a size parameter to the  | 
1076  | 
index1 = GraphIndex(trans, 'missing', 100)  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1077  | 
index = CombinedGraphIndex([index1])  | 
1078  | 
||
| 
2592.1.37
by Robert Collins
 Add CombinedGraphIndex.insert_index.  | 
1079  | 
def test_add_index(self):  | 
1080  | 
index = CombinedGraphIndex([])  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1081  | 
index1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])  | 
| 
2592.1.37
by Robert Collins
 Add CombinedGraphIndex.insert_index.  | 
1082  | 
index.insert_index(0, index1)  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1083  | 
self.assertEqual([(index1, ('key', ), '')], list(index.iter_all_entries()))  | 
| 
2592.1.37
by Robert Collins
 Add CombinedGraphIndex.insert_index.  | 
1084  | 
|
| 
4744.2.6
by John Arbash Meinel
 Start exposing an GraphIndex.clear_cache() member.  | 
1085  | 
def test_clear_cache(self):  | 
1086  | 
log = []  | 
|
1087  | 
||
1088  | 
class ClearCacheProxy(object):  | 
|
1089  | 
||
1090  | 
def __init__(self, index):  | 
|
1091  | 
self._index = index  | 
|
1092  | 
||
1093  | 
def __getattr__(self, name):  | 
|
1094  | 
return getattr(self._index)  | 
|
1095  | 
||
1096  | 
def clear_cache(self):  | 
|
1097  | 
log.append(self._index)  | 
|
1098  | 
return self._index.clear_cache()  | 
|
1099  | 
||
1100  | 
index = CombinedGraphIndex([])  | 
|
1101  | 
index1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])  | 
|
1102  | 
index.insert_index(0, ClearCacheProxy(index1))  | 
|
1103  | 
index2 = self.make_index('name', 0, nodes=[(('key', ), '', ())])  | 
|
1104  | 
index.insert_index(1, ClearCacheProxy(index2))  | 
|
1105  | 
        # CombinedGraphIndex should call 'clear_cache()' on all children
 | 
|
1106  | 
index.clear_cache()  | 
|
1107  | 
self.assertEqual(sorted([index1, index2]), sorted(log))  | 
|
1108  | 
||
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1109  | 
def test_iter_all_entries_empty(self):  | 
1110  | 
index = CombinedGraphIndex([])  | 
|
1111  | 
self.assertEqual([], list(index.iter_all_entries()))  | 
|
1112  | 
||
1113  | 
def test_iter_all_entries_children_empty(self):  | 
|
1114  | 
index1 = self.make_index('name')  | 
|
1115  | 
index = CombinedGraphIndex([index1])  | 
|
1116  | 
self.assertEqual([], list(index.iter_all_entries()))  | 
|
1117  | 
||
1118  | 
def test_iter_all_entries_simple(self):  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1119  | 
index1 = self.make_index('name', nodes=[(('name', ), 'data', ())])  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1120  | 
index = CombinedGraphIndex([index1])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1121  | 
self.assertEqual([(index1, ('name', ), 'data')],  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1122  | 
list(index.iter_all_entries()))  | 
1123  | 
||
1124  | 
def test_iter_all_entries_two_indices(self):  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1125  | 
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])  | 
1126  | 
index2 = self.make_index('name2', nodes=[(('2', ), '', ())])  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1127  | 
index = CombinedGraphIndex([index1, index2])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1128  | 
self.assertEqual([(index1, ('name', ), 'data'),  | 
1129  | 
(index2, ('2', ), '')],  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1130  | 
list(index.iter_all_entries()))  | 
1131  | 
||
| 
2592.1.39
by Robert Collins
 CombinedGraphIndex.iter_entries does not need to see all entries.  | 
1132  | 
def test_iter_entries_two_indices_dup_key(self):  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1133  | 
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])  | 
1134  | 
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])  | 
|
| 
2592.1.39
by Robert Collins
 CombinedGraphIndex.iter_entries does not need to see all entries.  | 
1135  | 
index = CombinedGraphIndex([index1, index2])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1136  | 
self.assertEqual([(index1, ('name', ), 'data')],  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1137  | 
list(index.iter_entries([('name', )])))  | 
| 
2592.1.39
by Robert Collins
 CombinedGraphIndex.iter_entries does not need to see all entries.  | 
1138  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1139  | 
def test_iter_all_entries_two_indices_dup_key(self):  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1140  | 
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])  | 
1141  | 
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1142  | 
index = CombinedGraphIndex([index1, index2])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1143  | 
self.assertEqual([(index1, ('name', ), 'data')],  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1144  | 
list(index.iter_all_entries()))  | 
1145  | 
||
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
1146  | 
def test_iter_key_prefix_2_key_element_refs(self):  | 
1147  | 
index1 = self.make_index('1', 1, key_elements=2, nodes=[  | 
|
1148  | 
(('name', 'fin1'), 'data', ([('ref', 'erence')], ))])  | 
|
1149  | 
index2 = self.make_index('2', 1, key_elements=2, nodes=[  | 
|
1150  | 
(('name', 'fin2'), 'beta', ([], )),  | 
|
1151  | 
(('ref', 'erence'), 'refdata', ([], ))])  | 
|
1152  | 
index = CombinedGraphIndex([index1, index2])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1153  | 
self.assertEqual(set([(index1, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),  | 
1154  | 
(index2, ('ref', 'erence'), 'refdata', ((), ))]),  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
1155  | 
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1156  | 
self.assertEqual(set([(index1, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),  | 
1157  | 
(index2, ('name', 'fin2'), 'beta', ((), ))]),  | 
|
| 
2624.2.9
by Robert Collins
 Introduce multiple component keys, which is what is needed to combine multiple knit indices into one.  | 
1158  | 
set(index.iter_entries_prefix([('name', None)])))  | 
1159  | 
||
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1160  | 
def test_iter_nothing_empty(self):  | 
1161  | 
index = CombinedGraphIndex([])  | 
|
1162  | 
self.assertEqual([], list(index.iter_entries([])))  | 
|
1163  | 
||
1164  | 
def test_iter_nothing_children_empty(self):  | 
|
1165  | 
index1 = self.make_index('name')  | 
|
1166  | 
index = CombinedGraphIndex([index1])  | 
|
1167  | 
self.assertEqual([], list(index.iter_entries([])))  | 
|
1168  | 
||
1169  | 
def test_iter_all_keys(self):  | 
|
1170  | 
index1 = self.make_index('1', 1, nodes=[  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1171  | 
(('name', ), 'data', ([('ref', )], ))])  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1172  | 
index2 = self.make_index('2', 1, nodes=[  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1173  | 
(('ref', ), 'refdata', ((), ))])  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1174  | 
index = CombinedGraphIndex([index1, index2])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1175  | 
self.assertEqual(set([(index1, ('name', ), 'data', ((('ref', ), ), )),  | 
1176  | 
(index2, ('ref', ), 'refdata', ((), ))]),  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1177  | 
set(index.iter_entries([('name', ), ('ref', )])))  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1178  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1179  | 
def test_iter_all_keys_dup_entry(self):  | 
1180  | 
index1 = self.make_index('1', 1, nodes=[  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1181  | 
(('name', ), 'data', ([('ref', )], )),  | 
1182  | 
(('ref', ), 'refdata', ([], ))])  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1183  | 
index2 = self.make_index('2', 1, nodes=[  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1184  | 
(('ref', ), 'refdata', ([], ))])  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1185  | 
index = CombinedGraphIndex([index1, index2])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1186  | 
self.assertEqual(set([(index1, ('name', ), 'data', ((('ref',),),)),  | 
1187  | 
(index1, ('ref', ), 'refdata', ((), ))]),  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1188  | 
set(index.iter_entries([('name', ), ('ref', )])))  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1189  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1190  | 
def test_iter_missing_entry_empty(self):  | 
1191  | 
index = CombinedGraphIndex([])  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1192  | 
self.assertEqual([], list(index.iter_entries([('a', )])))  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1193  | 
|
1194  | 
def test_iter_missing_entry_one_index(self):  | 
|
1195  | 
index1 = self.make_index('1')  | 
|
1196  | 
index = CombinedGraphIndex([index1])  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1197  | 
self.assertEqual([], list(index.iter_entries([('a', )])))  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1198  | 
|
1199  | 
def test_iter_missing_entry_two_index(self):  | 
|
1200  | 
index1 = self.make_index('1')  | 
|
1201  | 
index2 = self.make_index('2')  | 
|
1202  | 
index = CombinedGraphIndex([index1, index2])  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1203  | 
self.assertEqual([], list(index.iter_entries([('a', )])))  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1204  | 
|
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1205  | 
def test_iter_entry_present_one_index_only(self):  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1206  | 
index1 = self.make_index('1', nodes=[(('key', ), '', ())])  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1207  | 
index2 = self.make_index('2', nodes=[])  | 
1208  | 
index = CombinedGraphIndex([index1, index2])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1209  | 
self.assertEqual([(index1, ('key', ), '')],  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1210  | 
list(index.iter_entries([('key', )])))  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1211  | 
        # and in the other direction
 | 
1212  | 
index = CombinedGraphIndex([index2, index1])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1213  | 
self.assertEqual([(index1, ('key', ), '')],  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1214  | 
list(index.iter_entries([('key', )])))  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1215  | 
|
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
1216  | 
def test_key_count_empty(self):  | 
1217  | 
index1 = self.make_index('1', nodes=[])  | 
|
1218  | 
index2 = self.make_index('2', nodes=[])  | 
|
1219  | 
index = CombinedGraphIndex([index1, index2])  | 
|
1220  | 
self.assertEqual(0, index.key_count())  | 
|
1221  | 
||
1222  | 
def test_key_count_sums_index_keys(self):  | 
|
1223  | 
index1 = self.make_index('1', nodes=[  | 
|
1224  | 
(('1',), '', ()),  | 
|
1225  | 
(('2',), '', ())])  | 
|
1226  | 
index2 = self.make_index('2', nodes=[(('1',), '', ())])  | 
|
1227  | 
index = CombinedGraphIndex([index1, index2])  | 
|
1228  | 
self.assertEqual(3, index.key_count())  | 
|
1229  | 
||
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1230  | 
def test_validate_bad_child_index_errors(self):  | 
1231  | 
trans = self.get_transport()  | 
|
1232  | 
trans.put_bytes('name', "not an index\n")  | 
|
| 
2890.2.1
by Robert Collins
 * ``bzrlib.index.GraphIndex`` now requires a size parameter to the  | 
1233  | 
index1 = GraphIndex(trans, 'name', 13)  | 
| 
2592.1.31
by Robert Collins
 Build a combined graph index to use multiple indices at once.  | 
1234  | 
index = CombinedGraphIndex([index1])  | 
1235  | 
self.assertRaises(errors.BadIndexFormatSignature, index.validate)  | 
|
1236  | 
||
1237  | 
def test_validate_empty(self):  | 
|
1238  | 
index = CombinedGraphIndex([])  | 
|
1239  | 
index.validate()  | 
|
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1240  | 
|
| 
3789.1.3
by John Arbash Meinel
 CombinedGraphIndex can now reload when calling key_count().  | 
1241  | 
def test_key_count_reloads(self):  | 
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1242  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
| 
3789.1.3
by John Arbash Meinel
 CombinedGraphIndex can now reload when calling key_count().  | 
1243  | 
self.assertEqual(2, index.key_count())  | 
1244  | 
self.assertEqual([1, 1, 0], reload_counter)  | 
|
1245  | 
||
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1246  | 
def test_key_count_no_reload(self):  | 
1247  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
|
1248  | 
index._reload_func = None  | 
|
1249  | 
        # Without a _reload_func we just raise the exception
 | 
|
1250  | 
self.assertRaises(errors.NoSuchFile, index.key_count)  | 
|
1251  | 
||
| 
3789.1.3
by John Arbash Meinel
 CombinedGraphIndex can now reload when calling key_count().  | 
1252  | 
def test_key_count_reloads_and_fails(self):  | 
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1253  | 
        # We have deleted all underlying indexes, so we will try to reload, but
 | 
| 
3789.1.3
by John Arbash Meinel
 CombinedGraphIndex can now reload when calling key_count().  | 
1254  | 
        # still fail. This is mostly to test we don't get stuck in an infinite
 | 
1255  | 
        # loop trying to reload
 | 
|
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1256  | 
index, reload_counter = self.make_combined_index_with_missing(  | 
1257  | 
['1', '2', '3'])  | 
|
| 
3789.1.3
by John Arbash Meinel
 CombinedGraphIndex can now reload when calling key_count().  | 
1258  | 
self.assertRaises(errors.NoSuchFile, index.key_count)  | 
1259  | 
self.assertEqual([2, 1, 1], reload_counter)  | 
|
1260  | 
||
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1261  | 
def test_iter_entries_reloads(self):  | 
1262  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
|
1263  | 
result = list(index.iter_entries([('1',), ('2',), ('3',)]))  | 
|
1264  | 
index3 = index._indices[0]  | 
|
1265  | 
self.assertEqual([(index3, ('1',), ''), (index3, ('2',), '')],  | 
|
1266  | 
result)  | 
|
1267  | 
self.assertEqual([1, 1, 0], reload_counter)  | 
|
1268  | 
||
1269  | 
def test_iter_entries_reloads_midway(self):  | 
|
1270  | 
        # The first index still looks present, so we get interrupted mid-way
 | 
|
1271  | 
        # through
 | 
|
1272  | 
index, reload_counter = self.make_combined_index_with_missing(['2'])  | 
|
1273  | 
index1, index2 = index._indices  | 
|
1274  | 
result = list(index.iter_entries([('1',), ('2',), ('3',)]))  | 
|
1275  | 
index3 = index._indices[0]  | 
|
| 
3789.1.5
by John Arbash Meinel
 CombinedGraphIndex.iter_all_entries() can now reload when needed.  | 
1276  | 
        # We had already yielded '1', so we just go on to the next, we should
 | 
| 
3789.1.6
by John Arbash Meinel
 CombinedGraphIndex.iter_entries_prefix can now reload when needed.  | 
1277  | 
        # not yield '1' twice.
 | 
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1278  | 
self.assertEqual([(index1, ('1',), ''), (index3, ('2',), '')],  | 
1279  | 
result)  | 
|
1280  | 
self.assertEqual([1, 1, 0], reload_counter)  | 
|
1281  | 
||
1282  | 
def test_iter_entries_no_reload(self):  | 
|
1283  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
|
1284  | 
index._reload_func = None  | 
|
1285  | 
        # Without a _reload_func we just raise the exception
 | 
|
1286  | 
self.assertListRaises(errors.NoSuchFile, index.iter_entries, [('3',)])  | 
|
1287  | 
||
1288  | 
def test_iter_entries_reloads_and_fails(self):  | 
|
1289  | 
index, reload_counter = self.make_combined_index_with_missing(  | 
|
1290  | 
['1', '2', '3'])  | 
|
1291  | 
self.assertListRaises(errors.NoSuchFile, index.iter_entries, [('3',)])  | 
|
1292  | 
self.assertEqual([2, 1, 1], reload_counter)  | 
|
1293  | 
||
| 
3789.1.5
by John Arbash Meinel
 CombinedGraphIndex.iter_all_entries() can now reload when needed.  | 
1294  | 
def test_iter_all_entries_reloads(self):  | 
1295  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
|
1296  | 
result = list(index.iter_all_entries())  | 
|
1297  | 
index3 = index._indices[0]  | 
|
1298  | 
self.assertEqual([(index3, ('1',), ''), (index3, ('2',), '')],  | 
|
1299  | 
result)  | 
|
1300  | 
self.assertEqual([1, 1, 0], reload_counter)  | 
|
1301  | 
||
1302  | 
def test_iter_all_entries_reloads_midway(self):  | 
|
1303  | 
index, reload_counter = self.make_combined_index_with_missing(['2'])  | 
|
1304  | 
index1, index2 = index._indices  | 
|
1305  | 
result = list(index.iter_all_entries())  | 
|
1306  | 
index3 = index._indices[0]  | 
|
1307  | 
        # We had already yielded '1', so we just go on to the next, we should
 | 
|
| 
3789.1.6
by John Arbash Meinel
 CombinedGraphIndex.iter_entries_prefix can now reload when needed.  | 
1308  | 
        # not yield '1' twice.
 | 
| 
3789.1.5
by John Arbash Meinel
 CombinedGraphIndex.iter_all_entries() can now reload when needed.  | 
1309  | 
self.assertEqual([(index1, ('1',), ''), (index3, ('2',), '')],  | 
1310  | 
result)  | 
|
1311  | 
self.assertEqual([1, 1, 0], reload_counter)  | 
|
1312  | 
||
1313  | 
def test_iter_all_entries_no_reload(self):  | 
|
1314  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
|
1315  | 
index._reload_func = None  | 
|
1316  | 
self.assertListRaises(errors.NoSuchFile, index.iter_all_entries)  | 
|
1317  | 
||
1318  | 
def test_iter_all_entries_reloads_and_fails(self):  | 
|
1319  | 
index, reload_counter = self.make_combined_index_with_missing(  | 
|
1320  | 
['1', '2', '3'])  | 
|
1321  | 
self.assertListRaises(errors.NoSuchFile, index.iter_all_entries)  | 
|
| 
3789.1.4
by John Arbash Meinel
 CombinedGraphIndex.iter_entries() is now able to reload on request.  | 
1322  | 
|
| 
3789.1.6
by John Arbash Meinel
 CombinedGraphIndex.iter_entries_prefix can now reload when needed.  | 
1323  | 
def test_iter_entries_prefix_reloads(self):  | 
1324  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
|
1325  | 
result = list(index.iter_entries_prefix([('1',)]))  | 
|
1326  | 
index3 = index._indices[0]  | 
|
1327  | 
self.assertEqual([(index3, ('1',), '')], result)  | 
|
1328  | 
self.assertEqual([1, 1, 0], reload_counter)  | 
|
1329  | 
||
1330  | 
def test_iter_entries_prefix_reloads_midway(self):  | 
|
1331  | 
index, reload_counter = self.make_combined_index_with_missing(['2'])  | 
|
1332  | 
index1, index2 = index._indices  | 
|
1333  | 
result = list(index.iter_entries_prefix([('1',)]))  | 
|
1334  | 
index3 = index._indices[0]  | 
|
1335  | 
        # We had already yielded '1', so we just go on to the next, we should
 | 
|
1336  | 
        # not yield '1' twice.
 | 
|
1337  | 
self.assertEqual([(index1, ('1',), '')], result)  | 
|
1338  | 
self.assertEqual([1, 1, 0], reload_counter)  | 
|
1339  | 
||
1340  | 
def test_iter_entries_prefix_no_reload(self):  | 
|
1341  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
|
1342  | 
index._reload_func = None  | 
|
1343  | 
self.assertListRaises(errors.NoSuchFile, index.iter_entries_prefix,  | 
|
1344  | 
[('1',)])  | 
|
1345  | 
||
1346  | 
def test_iter_entries_prefix_reloads_and_fails(self):  | 
|
1347  | 
index, reload_counter = self.make_combined_index_with_missing(  | 
|
1348  | 
['1', '2', '3'])  | 
|
1349  | 
self.assertListRaises(errors.NoSuchFile, index.iter_entries_prefix,  | 
|
1350  | 
[('1',)])  | 
|
1351  | 
||
| 
3789.1.7
by John Arbash Meinel
 CombinedGraphIndex.validate() will now reload.  | 
1352  | 
def test_validate_reloads(self):  | 
1353  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
|
1354  | 
index.validate()  | 
|
1355  | 
self.assertEqual([1, 1, 0], reload_counter)  | 
|
1356  | 
||
1357  | 
def test_validate_reloads_midway(self):  | 
|
1358  | 
index, reload_counter = self.make_combined_index_with_missing(['2'])  | 
|
1359  | 
index.validate()  | 
|
1360  | 
||
1361  | 
def test_validate_no_reload(self):  | 
|
1362  | 
index, reload_counter = self.make_combined_index_with_missing()  | 
|
1363  | 
index._reload_func = None  | 
|
1364  | 
self.assertRaises(errors.NoSuchFile, index.validate)  | 
|
1365  | 
||
1366  | 
def test_validate_reloads_and_fails(self):  | 
|
1367  | 
index, reload_counter = self.make_combined_index_with_missing(  | 
|
1368  | 
['1', '2', '3'])  | 
|
1369  | 
self.assertRaises(errors.NoSuchFile, index.validate)  | 
|
1370  | 
||
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1371  | 
def test_find_ancestors_across_indexes(self):  | 
| 
4593.4.8
by John Arbash Meinel
 Implement CombinedGraphIndex.get_ancestry()  | 
1372  | 
key1 = ('key-1',)  | 
1373  | 
key2 = ('key-2',)  | 
|
1374  | 
key3 = ('key-3',)  | 
|
1375  | 
key4 = ('key-4',)  | 
|
1376  | 
index1 = self.make_index('12', ref_lists=1, nodes=[  | 
|
1377  | 
(key1, 'value', ([],)),  | 
|
1378  | 
(key2, 'value', ([key1],)),  | 
|
1379  | 
            ])
 | 
|
1380  | 
index2 = self.make_index('34', ref_lists=1, nodes=[  | 
|
1381  | 
(key3, 'value', ([key2],)),  | 
|
1382  | 
(key4, 'value', ([key3],)),  | 
|
1383  | 
            ])
 | 
|
1384  | 
c_index = CombinedGraphIndex([index1, index2])  | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1385  | 
parent_map, missing_keys = c_index.find_ancestry([key1], 0)  | 
| 
4593.4.8
by John Arbash Meinel
 Implement CombinedGraphIndex.get_ancestry()  | 
1386  | 
self.assertEqual({key1: ()}, parent_map)  | 
1387  | 
self.assertEqual(set(), missing_keys)  | 
|
1388  | 
        # Now look for a key from index2 which requires us to find the key in
 | 
|
1389  | 
        # the second index, and then continue searching for parents in the
 | 
|
1390  | 
        # first index
 | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1391  | 
parent_map, missing_keys = c_index.find_ancestry([key3], 0)  | 
| 
4593.4.8
by John Arbash Meinel
 Implement CombinedGraphIndex.get_ancestry()  | 
1392  | 
self.assertEqual({key1: (), key2: (key1,), key3: (key2,)}, parent_map)  | 
1393  | 
self.assertEqual(set(), missing_keys)  | 
|
1394  | 
||
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1395  | 
def test_find_ancestors_missing_keys(self):  | 
| 
4593.4.8
by John Arbash Meinel
 Implement CombinedGraphIndex.get_ancestry()  | 
1396  | 
key1 = ('key-1',)  | 
1397  | 
key2 = ('key-2',)  | 
|
1398  | 
key3 = ('key-3',)  | 
|
1399  | 
key4 = ('key-4',)  | 
|
1400  | 
index1 = self.make_index('12', ref_lists=1, nodes=[  | 
|
1401  | 
(key1, 'value', ([],)),  | 
|
1402  | 
(key2, 'value', ([key1],)),  | 
|
1403  | 
            ])
 | 
|
1404  | 
index2 = self.make_index('34', ref_lists=1, nodes=[  | 
|
1405  | 
(key3, 'value', ([key2],)),  | 
|
1406  | 
            ])
 | 
|
1407  | 
c_index = CombinedGraphIndex([index1, index2])  | 
|
1408  | 
        # Searching for a key which is actually not present at all should
 | 
|
1409  | 
        # eventually converge
 | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1410  | 
parent_map, missing_keys = c_index.find_ancestry([key4], 0)  | 
| 
4593.4.8
by John Arbash Meinel
 Implement CombinedGraphIndex.get_ancestry()  | 
1411  | 
self.assertEqual({}, parent_map)  | 
1412  | 
self.assertEqual(set([key4]), missing_keys)  | 
|
1413  | 
||
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1414  | 
def test_find_ancestors_no_indexes(self):  | 
| 
4593.4.8
by John Arbash Meinel
 Implement CombinedGraphIndex.get_ancestry()  | 
1415  | 
c_index = CombinedGraphIndex([])  | 
1416  | 
key1 = ('key-1',)  | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1417  | 
parent_map, missing_keys = c_index.find_ancestry([key1], 0)  | 
| 
4593.4.8
by John Arbash Meinel
 Implement CombinedGraphIndex.get_ancestry()  | 
1418  | 
self.assertEqual({}, parent_map)  | 
1419  | 
self.assertEqual(set([key1]), missing_keys)  | 
|
1420  | 
||
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1421  | 
def test_find_ancestors_ghost_parent(self):  | 
| 
4593.4.8
by John Arbash Meinel
 Implement CombinedGraphIndex.get_ancestry()  | 
1422  | 
key1 = ('key-1',)  | 
1423  | 
key2 = ('key-2',)  | 
|
1424  | 
key3 = ('key-3',)  | 
|
1425  | 
key4 = ('key-4',)  | 
|
1426  | 
index1 = self.make_index('12', ref_lists=1, nodes=[  | 
|
1427  | 
(key1, 'value', ([],)),  | 
|
1428  | 
(key2, 'value', ([key1],)),  | 
|
1429  | 
            ])
 | 
|
1430  | 
index2 = self.make_index('34', ref_lists=1, nodes=[  | 
|
1431  | 
(key4, 'value', ([key2, key3],)),  | 
|
1432  | 
            ])
 | 
|
1433  | 
c_index = CombinedGraphIndex([index1, index2])  | 
|
1434  | 
        # Searching for a key which is actually not present at all should
 | 
|
1435  | 
        # eventually converge
 | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1436  | 
parent_map, missing_keys = c_index.find_ancestry([key4], 0)  | 
| 
4593.4.8
by John Arbash Meinel
 Implement CombinedGraphIndex.get_ancestry()  | 
1437  | 
self.assertEqual({key4: (key2, key3), key2: (key1,), key1: ()},  | 
1438  | 
parent_map)  | 
|
1439  | 
self.assertEqual(set([key3]), missing_keys)  | 
|
1440  | 
||
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1441  | 
def test__find_ancestors_empty_index(self):  | 
1442  | 
index = self.make_index('test', ref_lists=1, key_elements=1, nodes=[])  | 
|
| 
4593.4.11
by John Arbash Meinel
 Snapshot the work in progress.  | 
1443  | 
parent_map = {}  | 
1444  | 
missing_keys = set()  | 
|
| 
4593.4.12
by John Arbash Meinel
 Name the specific index api _find_ancestors, and the public CombinedGraphIndex api find_ancestry()  | 
1445  | 
search_keys = index._find_ancestors([('one',), ('two',)], 0, parent_map,  | 
1446  | 
missing_keys)  | 
|
| 
4593.4.11
by John Arbash Meinel
 Snapshot the work in progress.  | 
1447  | 
self.assertEqual(set(), search_keys)  | 
1448  | 
self.assertEqual({}, parent_map)  | 
|
1449  | 
self.assertEqual(set([('one',), ('two',)]), missing_keys)  | 
|
1450  | 
||
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1451  | 
|
1452  | 
class TestInMemoryGraphIndex(TestCaseWithMemoryTransport):  | 
|
1453  | 
||
| 
2624.2.10
by Robert Collins
 Also add iter_key_prefix support to InMemoryGraphIndex.  | 
1454  | 
def make_index(self, ref_lists=0, key_elements=1, nodes=[]):  | 
1455  | 
result = InMemoryGraphIndex(ref_lists, key_elements=key_elements)  | 
|
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1456  | 
result.add_nodes(nodes)  | 
1457  | 
return result  | 
|
1458  | 
||
| 
2624.2.1
by Robert Collins
 InMemoryGraphIndex.add_nodes was inconsistent with other metods for non-node-reference indices.  | 
1459  | 
def test_add_nodes_no_refs(self):  | 
1460  | 
index = self.make_index(0)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1461  | 
index.add_nodes([(('name', ), 'data')])  | 
1462  | 
index.add_nodes([(('name2', ), ''), (('name3', ), '')])  | 
|
| 
2624.2.1
by Robert Collins
 InMemoryGraphIndex.add_nodes was inconsistent with other metods for non-node-reference indices.  | 
1463  | 
self.assertEqual(set([  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1464  | 
(index, ('name', ), 'data'),  | 
1465  | 
(index, ('name2', ), ''),  | 
|
1466  | 
(index, ('name3', ), ''),  | 
|
| 
2624.2.1
by Robert Collins
 InMemoryGraphIndex.add_nodes was inconsistent with other metods for non-node-reference indices.  | 
1467  | 
]), set(index.iter_all_entries()))  | 
1468  | 
||
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1469  | 
def test_add_nodes(self):  | 
1470  | 
index = self.make_index(1)  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1471  | 
index.add_nodes([(('name', ), 'data', ([],))])  | 
1472  | 
index.add_nodes([(('name2', ), '', ([],)), (('name3', ), '', ([('r', )],))])  | 
|
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1473  | 
self.assertEqual(set([  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1474  | 
(index, ('name', ), 'data', ((),)),  | 
1475  | 
(index, ('name2', ), '', ((),)),  | 
|
1476  | 
(index, ('name3', ), '', ((('r', ), ), )),  | 
|
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1477  | 
]), set(index.iter_all_entries()))  | 
1478  | 
||
1479  | 
def test_iter_all_entries_empty(self):  | 
|
1480  | 
index = self.make_index()  | 
|
1481  | 
self.assertEqual([], list(index.iter_all_entries()))  | 
|
1482  | 
||
1483  | 
def test_iter_all_entries_simple(self):  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1484  | 
index = self.make_index(nodes=[(('name', ), 'data')])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1485  | 
self.assertEqual([(index, ('name', ), 'data')],  | 
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1486  | 
list(index.iter_all_entries()))  | 
1487  | 
||
1488  | 
def test_iter_all_entries_references(self):  | 
|
1489  | 
index = self.make_index(1, nodes=[  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1490  | 
(('name', ), 'data', ([('ref', )], )),  | 
1491  | 
(('ref', ), 'refdata', ([], ))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1492  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref', ),),)),  | 
1493  | 
(index, ('ref', ), 'refdata', ((), ))]),  | 
|
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1494  | 
set(index.iter_all_entries()))  | 
1495  | 
||
1496  | 
def test_iteration_absent_skipped(self):  | 
|
1497  | 
index = self.make_index(1, nodes=[  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1498  | 
(('name', ), 'data', ([('ref', )], ))])  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1499  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),  | 
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1500  | 
set(index.iter_all_entries()))  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1501  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),  | 
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1502  | 
set(index.iter_entries([('name', )])))  | 
1503  | 
self.assertEqual([], list(index.iter_entries([('ref', )])))  | 
|
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1504  | 
|
1505  | 
def test_iter_all_keys(self):  | 
|
1506  | 
index = self.make_index(1, nodes=[  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1507  | 
(('name', ), 'data', ([('ref', )], )),  | 
1508  | 
(('ref', ), 'refdata', ([], ))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1509  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),  | 
1510  | 
(index, ('ref', ), 'refdata', ((), ))]),  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1511  | 
set(index.iter_entries([('name', ), ('ref', )])))  | 
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1512  | 
|
| 
2624.2.10
by Robert Collins
 Also add iter_key_prefix support to InMemoryGraphIndex.  | 
1513  | 
def test_iter_key_prefix_1_key_element_no_refs(self):  | 
1514  | 
index = self.make_index( nodes=[  | 
|
1515  | 
(('name', ), 'data'),  | 
|
1516  | 
(('ref', ), 'refdata')])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1517  | 
self.assertEqual(set([(index, ('name', ), 'data'),  | 
1518  | 
(index, ('ref', ), 'refdata')]),  | 
|
| 
2624.2.10
by Robert Collins
 Also add iter_key_prefix support to InMemoryGraphIndex.  | 
1519  | 
set(index.iter_entries_prefix([('name', ), ('ref', )])))  | 
1520  | 
||
1521  | 
def test_iter_key_prefix_1_key_element_refs(self):  | 
|
1522  | 
index = self.make_index(1, nodes=[  | 
|
1523  | 
(('name', ), 'data', ([('ref', )], )),  | 
|
1524  | 
(('ref', ), 'refdata', ([], ))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1525  | 
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),  | 
1526  | 
(index, ('ref', ), 'refdata', ((), ))]),  | 
|
| 
2624.2.10
by Robert Collins
 Also add iter_key_prefix support to InMemoryGraphIndex.  | 
1527  | 
set(index.iter_entries_prefix([('name', ), ('ref', )])))  | 
1528  | 
||
1529  | 
def test_iter_key_prefix_2_key_element_no_refs(self):  | 
|
1530  | 
index = self.make_index(key_elements=2, nodes=[  | 
|
1531  | 
(('name', 'fin1'), 'data'),  | 
|
1532  | 
(('name', 'fin2'), 'beta'),  | 
|
1533  | 
(('ref', 'erence'), 'refdata')])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1534  | 
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),  | 
1535  | 
(index, ('ref', 'erence'), 'refdata')]),  | 
|
| 
2624.2.10
by Robert Collins
 Also add iter_key_prefix support to InMemoryGraphIndex.  | 
1536  | 
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1537  | 
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),  | 
1538  | 
(index, ('name', 'fin2'), 'beta')]),  | 
|
| 
2624.2.10
by Robert Collins
 Also add iter_key_prefix support to InMemoryGraphIndex.  | 
1539  | 
set(index.iter_entries_prefix([('name', None)])))  | 
1540  | 
||
1541  | 
def test_iter_key_prefix_2_key_element_refs(self):  | 
|
1542  | 
index = self.make_index(1, key_elements=2, nodes=[  | 
|
1543  | 
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),  | 
|
1544  | 
(('name', 'fin2'), 'beta', ([], )),  | 
|
1545  | 
(('ref', 'erence'), 'refdata', ([], ))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1546  | 
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),  | 
1547  | 
(index, ('ref', 'erence'), 'refdata', ((), ))]),  | 
|
| 
2624.2.10
by Robert Collins
 Also add iter_key_prefix support to InMemoryGraphIndex.  | 
1548  | 
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))  | 
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1549  | 
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),  | 
1550  | 
(index, ('name', 'fin2'), 'beta', ((), ))]),  | 
|
| 
2624.2.10
by Robert Collins
 Also add iter_key_prefix support to InMemoryGraphIndex.  | 
1551  | 
set(index.iter_entries_prefix([('name', None)])))  | 
1552  | 
||
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1553  | 
def test_iter_nothing_empty(self):  | 
1554  | 
index = self.make_index()  | 
|
1555  | 
self.assertEqual([], list(index.iter_entries([])))  | 
|
1556  | 
||
1557  | 
def test_iter_missing_entry_empty(self):  | 
|
1558  | 
index = self.make_index()  | 
|
1559  | 
self.assertEqual([], list(index.iter_entries(['a'])))  | 
|
1560  | 
||
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
1561  | 
def test_key_count_empty(self):  | 
1562  | 
index = self.make_index()  | 
|
1563  | 
self.assertEqual(0, index.key_count())  | 
|
1564  | 
||
1565  | 
def test_key_count_one(self):  | 
|
1566  | 
index = self.make_index(nodes=[(('name', ), '')])  | 
|
1567  | 
self.assertEqual(1, index.key_count())  | 
|
1568  | 
||
1569  | 
def test_key_count_two(self):  | 
|
1570  | 
index = self.make_index(nodes=[(('name', ), ''), (('foo', ), '')])  | 
|
1571  | 
self.assertEqual(2, index.key_count())  | 
|
1572  | 
||
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1573  | 
def test_validate_empty(self):  | 
1574  | 
index = self.make_index()  | 
|
1575  | 
index.validate()  | 
|
1576  | 
||
1577  | 
def test_validate_no_refs_content(self):  | 
|
| 
2624.2.5
by Robert Collins
 Change bzrlib.index.Index keys to be 1-tuples, not strings.  | 
1578  | 
index = self.make_index(nodes=[(('key', ), 'value')])  | 
| 
2592.1.38
by Robert Collins
 Create an InMemoryGraphIndex for temporary indexing.  | 
1579  | 
index.validate()  | 
1580  | 
||
1581  | 
||
| 
2624.2.12
by Robert Collins
 Create an adapter between indices with differing key lengths.  | 
1582  | 
class TestGraphIndexPrefixAdapter(TestCaseWithMemoryTransport):  | 
1583  | 
||
| 
2624.2.13
by Robert Collins
 Implement add_node/add_nodes to the GraphIndexPrefixAdapter.  | 
1584  | 
def make_index(self, ref_lists=1, key_elements=2, nodes=[], add_callback=False):  | 
| 
2624.2.12
by Robert Collins
 Create an adapter between indices with differing key lengths.  | 
1585  | 
result = InMemoryGraphIndex(ref_lists, key_elements=key_elements)  | 
1586  | 
result.add_nodes(nodes)  | 
|
| 
2624.2.13
by Robert Collins
 Implement add_node/add_nodes to the GraphIndexPrefixAdapter.  | 
1587  | 
if add_callback:  | 
| 
2624.2.17
by Robert Collins
 Review feedback.  | 
1588  | 
add_nodes_callback = result.add_nodes  | 
| 
2624.2.13
by Robert Collins
 Implement add_node/add_nodes to the GraphIndexPrefixAdapter.  | 
1589  | 
else:  | 
| 
2624.2.17
by Robert Collins
 Review feedback.  | 
1590  | 
add_nodes_callback = None  | 
| 
2624.2.13
by Robert Collins
 Implement add_node/add_nodes to the GraphIndexPrefixAdapter.  | 
1591  | 
adapter = GraphIndexPrefixAdapter(result, ('prefix', ), key_elements - 1,  | 
1592  | 
add_nodes_callback=add_nodes_callback)  | 
|
| 
2624.2.12
by Robert Collins
 Create an adapter between indices with differing key lengths.  | 
1593  | 
return result, adapter  | 
1594  | 
||
| 
2624.2.13
by Robert Collins
 Implement add_node/add_nodes to the GraphIndexPrefixAdapter.  | 
1595  | 
def test_add_node(self):  | 
1596  | 
index, adapter = self.make_index(add_callback=True)  | 
|
1597  | 
adapter.add_node(('key',), 'value', ((('ref',),),))  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1598  | 
self.assertEqual(set([(index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))]),  | 
| 
2624.2.13
by Robert Collins
 Implement add_node/add_nodes to the GraphIndexPrefixAdapter.  | 
1599  | 
set(index.iter_all_entries()))  | 
1600  | 
||
1601  | 
def test_add_nodes(self):  | 
|
1602  | 
index, adapter = self.make_index(add_callback=True)  | 
|
1603  | 
adapter.add_nodes((  | 
|
1604  | 
(('key',), 'value', ((('ref',),),)),  | 
|
1605  | 
(('key2',), 'value2', ((),)),  | 
|
1606  | 
            ))
 | 
|
1607  | 
self.assertEqual(set([  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1608  | 
(index, ('prefix', 'key2'), 'value2', ((),)),  | 
1609  | 
(index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))  | 
|
| 
2624.2.13
by Robert Collins
 Implement add_node/add_nodes to the GraphIndexPrefixAdapter.  | 
1610  | 
            ]),
 | 
1611  | 
set(index.iter_all_entries()))  | 
|
1612  | 
||
| 
2624.2.12
by Robert Collins
 Create an adapter between indices with differing key lengths.  | 
1613  | 
def test_construct(self):  | 
1614  | 
index = InMemoryGraphIndex()  | 
|
1615  | 
adapter = GraphIndexPrefixAdapter(index, ('prefix', ), 1)  | 
|
1616  | 
||
1617  | 
def test_construct_with_callback(self):  | 
|
1618  | 
index = InMemoryGraphIndex()  | 
|
1619  | 
adapter = GraphIndexPrefixAdapter(index, ('prefix', ), 1, index.add_nodes)  | 
|
1620  | 
||
1621  | 
def test_iter_all_entries_cross_prefix_map_errors(self):  | 
|
1622  | 
index, adapter = self.make_index(nodes=[  | 
|
1623  | 
(('prefix', 'key1'), 'data1', ((('prefixaltered', 'key2'),),))])  | 
|
1624  | 
self.assertRaises(errors.BadIndexData, list, adapter.iter_all_entries())  | 
|
1625  | 
||
1626  | 
def test_iter_all_entries(self):  | 
|
1627  | 
index, adapter = self.make_index(nodes=[  | 
|
1628  | 
(('notprefix', 'key1'), 'data', ((), )),  | 
|
1629  | 
(('prefix', 'key1'), 'data1', ((), )),  | 
|
1630  | 
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])  | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1631  | 
self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),  | 
1632  | 
(index, ('key2', ), 'data2', ((('key1',),),))]),  | 
|
| 
2624.2.12
by Robert Collins
 Create an adapter between indices with differing key lengths.  | 
1633  | 
set(adapter.iter_all_entries()))  | 
1634  | 
||
1635  | 
def test_iter_entries(self):  | 
|
1636  | 
index, adapter = self.make_index(nodes=[  | 
|
1637  | 
(('notprefix', 'key1'), 'data', ((), )),  | 
|
1638  | 
(('prefix', 'key1'), 'data1', ((), )),  | 
|
1639  | 
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])  | 
|
1640  | 
        # ask for many - get all
 | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1641  | 
self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),  | 
1642  | 
(index, ('key2', ), 'data2', ((('key1', ),),))]),  | 
|
| 
2624.2.12
by Robert Collins
 Create an adapter between indices with differing key lengths.  | 
1643  | 
set(adapter.iter_entries([('key1', ), ('key2', )])))  | 
1644  | 
        # ask for one, get one
 | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1645  | 
self.assertEqual(set([(index, ('key1', ), 'data1', ((),))]),  | 
| 
2624.2.12
by Robert Collins
 Create an adapter between indices with differing key lengths.  | 
1646  | 
set(adapter.iter_entries([('key1', )])))  | 
1647  | 
        # ask for missing, get none
 | 
|
1648  | 
self.assertEqual(set(),  | 
|
1649  | 
set(adapter.iter_entries([('key3', )])))  | 
|
1650  | 
||
1651  | 
def test_iter_entries_prefix(self):  | 
|
1652  | 
index, adapter = self.make_index(key_elements=3, nodes=[  | 
|
1653  | 
(('notprefix', 'foo', 'key1'), 'data', ((), )),  | 
|
1654  | 
(('prefix', 'prefix2', 'key1'), 'data1', ((), )),  | 
|
1655  | 
(('prefix', 'prefix2', 'key2'), 'data2', ((('prefix', 'prefix2', 'key1'),),))])  | 
|
1656  | 
        # ask for a prefix, get the results for just that prefix, adjusted.
 | 
|
| 
2624.2.14
by Robert Collins
 Add source index to the index iteration API to allow mapping back to the origin of retrieved data.  | 
1657  | 
self.assertEqual(set([(index, ('prefix2', 'key1', ), 'data1', ((),)),  | 
1658  | 
(index, ('prefix2', 'key2', ), 'data2', ((('prefix2', 'key1', ),),))]),  | 
|
| 
2624.2.12
by Robert Collins
 Create an adapter between indices with differing key lengths.  | 
1659  | 
set(adapter.iter_entries_prefix([('prefix2', None)])))  | 
1660  | 
||
| 
2624.2.16
by Robert Collins
 Add a key_count method to GraphIndex and friends, allowing optimisation of length calculations by the index.  | 
1661  | 
def test_key_count_no_matching_keys(self):  | 
1662  | 
index, adapter = self.make_index(nodes=[  | 
|
1663  | 
(('notprefix', 'key1'), 'data', ((), ))])  | 
|
1664  | 
self.assertEqual(0, adapter.key_count())  | 
|
1665  | 
||
1666  | 
def test_key_count_some_keys(self):  | 
|
1667  | 
index, adapter = self.make_index(nodes=[  | 
|
1668  | 
(('notprefix', 'key1'), 'data', ((), )),  | 
|
1669  | 
(('prefix', 'key1'), 'data1', ((), )),  | 
|
1670  | 
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])  | 
|
1671  | 
self.assertEqual(2, adapter.key_count())  | 
|
1672  | 
||
| 
2624.2.12
by Robert Collins
 Create an adapter between indices with differing key lengths.  | 
1673  | 
def test_validate(self):  | 
1674  | 
index, adapter = self.make_index()  | 
|
1675  | 
calls = []  | 
|
1676  | 
def validate():  | 
|
1677  | 
calls.append('called')  | 
|
1678  | 
index.validate = validate  | 
|
1679  | 
adapter.validate()  | 
|
1680  | 
self.assertEqual(['called'], calls)  |