943
946
def test_iter_key_prefix_1_element_key_None(self):
944
947
index = self.make_index()
945
self.assertRaises(_mod_index.BadIndexKey, list,
948
self.assertRaises(errors.BadIndexKey, list,
946
949
index.iter_entries_prefix([(None, )]))
948
951
def test_iter_key_prefix_wrong_length(self):
949
952
index = self.make_index()
950
self.assertRaises(_mod_index.BadIndexKey, list,
951
index.iter_entries_prefix([(b'foo', None)]))
953
self.assertRaises(errors.BadIndexKey, list,
954
index.iter_entries_prefix([('foo', None)]))
952
955
index = self.make_index(key_elements=2)
953
self.assertRaises(_mod_index.BadIndexKey, list,
954
index.iter_entries_prefix([(b'foo', )]))
955
self.assertRaises(_mod_index.BadIndexKey, list,
956
index.iter_entries_prefix([(b'foo', None, None)]))
956
self.assertRaises(errors.BadIndexKey, list,
957
index.iter_entries_prefix([('foo', )]))
958
self.assertRaises(errors.BadIndexKey, list,
959
index.iter_entries_prefix([('foo', None, None)]))
958
961
def test_iter_key_prefix_1_key_element_no_refs(self):
959
index = self.make_index(nodes=[
960
((b'name', ), b'data', ()),
961
((b'ref', ), b'refdata', ())])
962
self.assertEqual({(index, (b'name', ), b'data'),
963
(index, (b'ref', ), b'refdata')},
964
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
962
index = self.make_index( nodes=[
963
(('name', ), 'data', ()),
964
(('ref', ), 'refdata', ())])
965
self.assertEqual(set([(index, ('name', ), 'data'),
966
(index, ('ref', ), 'refdata')]),
967
set(index.iter_entries_prefix([('name', ), ('ref', )])))
966
969
def test_iter_key_prefix_1_key_element_refs(self):
967
970
index = self.make_index(1, nodes=[
968
((b'name', ), b'data', ([(b'ref', )], )),
969
((b'ref', ), b'refdata', ([], ))])
970
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
971
(index, (b'ref', ), b'refdata', ((), ))},
972
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
971
(('name', ), 'data', ([('ref', )], )),
972
(('ref', ), 'refdata', ([], ))])
973
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
974
(index, ('ref', ), 'refdata', ((), ))]),
975
set(index.iter_entries_prefix([('name', ), ('ref', )])))
974
977
def test_iter_key_prefix_2_key_element_no_refs(self):
975
978
index = self.make_index(key_elements=2, nodes=[
976
((b'name', b'fin1'), b'data', ()),
977
((b'name', b'fin2'), b'beta', ()),
978
((b'ref', b'erence'), b'refdata', ())])
979
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
980
(index, (b'ref', b'erence'), b'refdata')},
981
set(index.iter_entries_prefix(
982
[(b'name', b'fin1'), (b'ref', b'erence')])))
983
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
984
(index, (b'name', b'fin2'), b'beta')},
985
set(index.iter_entries_prefix([(b'name', None)])))
979
(('name', 'fin1'), 'data', ()),
980
(('name', 'fin2'), 'beta', ()),
981
(('ref', 'erence'), 'refdata', ())])
982
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
983
(index, ('ref', 'erence'), 'refdata')]),
984
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
985
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
986
(index, ('name', 'fin2'), 'beta')]),
987
set(index.iter_entries_prefix([('name', None)])))
987
989
def test_iter_key_prefix_2_key_element_refs(self):
988
990
index = self.make_index(1, key_elements=2, nodes=[
989
((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], )),
990
((b'name', b'fin2'), b'beta', ([], )),
991
((b'ref', b'erence'), b'refdata', ([], ))])
993
{(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
994
(index, (b'ref', b'erence'), b'refdata', ((), ))},
995
set(index.iter_entries_prefix(
996
[(b'name', b'fin1'), (b'ref', b'erence')])))
998
{(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
999
(index, (b'name', b'fin2'), b'beta', ((), ))},
1000
set(index.iter_entries_prefix([(b'name', None)])))
991
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
992
(('name', 'fin2'), 'beta', ([], )),
993
(('ref', 'erence'), 'refdata', ([], ))])
994
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
995
(index, ('ref', 'erence'), 'refdata', ((), ))]),
996
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
997
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
998
(index, ('name', 'fin2'), 'beta', ((), ))]),
999
set(index.iter_entries_prefix([('name', None)])))
1002
1001
# XXX: external_references tests are duplicated in test_index. We
1003
1002
# probably should have per_graph_index tests...
1008
1007
def test_external_references_no_results(self):
1009
1008
index = self.make_index(ref_lists=1, nodes=[
1010
((b'key',), b'value', ([],))])
1009
(('key',), 'value', ([],))])
1011
1010
self.assertEqual(set(), index.external_references(0))
1013
1012
def test_external_references_missing_ref(self):
1014
missing_key = (b'missing',)
1013
missing_key = ('missing',)
1015
1014
index = self.make_index(ref_lists=1, nodes=[
1016
((b'key',), b'value', ([missing_key],))])
1017
self.assertEqual({missing_key}, index.external_references(0))
1015
(('key',), 'value', ([missing_key],))])
1016
self.assertEqual(set([missing_key]), index.external_references(0))
1019
1018
def test_external_references_multiple_ref_lists(self):
1020
missing_key = (b'missing',)
1019
missing_key = ('missing',)
1021
1020
index = self.make_index(ref_lists=2, nodes=[
1022
((b'key',), b'value', ([], [missing_key]))])
1021
(('key',), 'value', ([], [missing_key]))])
1023
1022
self.assertEqual(set([]), index.external_references(0))
1024
self.assertEqual({missing_key}, index.external_references(1))
1023
self.assertEqual(set([missing_key]), index.external_references(1))
1026
1025
def test_external_references_two_records(self):
1027
1026
index = self.make_index(ref_lists=1, nodes=[
1028
((b'key-1',), b'value', ([(b'key-2',)],)),
1029
((b'key-2',), b'value', ([],)),
1027
(('key-1',), 'value', ([('key-2',)],)),
1028
(('key-2',), 'value', ([],)),
1031
1030
self.assertEqual(set([]), index.external_references(0))
1033
1032
def test__find_ancestors_one_page(self):
1036
1035
index = self.make_index(ref_lists=1, key_elements=1, nodes=[
1037
(key1, b'value', ([key2],)),
1038
(key2, b'value', ([],)),
1036
(key1, 'value', ([key2],)),
1037
(key2, 'value', ([],)),
1040
1039
parent_map = {}
1041
1040
missing_keys = set()
1211
1210
self.overrideAttr(btree_index, '_btree_serializer', self.parse_btree)
1213
1212
def test_LeafNode_1_0(self):
1214
node_bytes = (b"type=leaf\n"
1215
b"0000000000000000000000000000000000000000\x00\x00value:0\n"
1216
b"1111111111111111111111111111111111111111\x00\x00value:1\n"
1217
b"2222222222222222222222222222222222222222\x00\x00value:2\n"
1218
b"3333333333333333333333333333333333333333\x00\x00value:3\n"
1219
b"4444444444444444444444444444444444444444\x00\x00value:4\n")
1213
node_bytes = ("type=leaf\n"
1214
"0000000000000000000000000000000000000000\x00\x00value:0\n"
1215
"1111111111111111111111111111111111111111\x00\x00value:1\n"
1216
"2222222222222222222222222222222222222222\x00\x00value:2\n"
1217
"3333333333333333333333333333333333333333\x00\x00value:3\n"
1218
"4444444444444444444444444444444444444444\x00\x00value:4\n")
1220
1219
node = btree_index._LeafNode(node_bytes, 1, 0)
1221
1220
# We do direct access, or don't care about order, to leaf nodes most of
1222
1221
# the time, so a dict is useful:
1223
1222
self.assertEqual({
1224
(b"0000000000000000000000000000000000000000",): (b"value:0", ()),
1225
(b"1111111111111111111111111111111111111111",): (b"value:1", ()),
1226
(b"2222222222222222222222222222222222222222",): (b"value:2", ()),
1227
(b"3333333333333333333333333333333333333333",): (b"value:3", ()),
1228
(b"4444444444444444444444444444444444444444",): (b"value:4", ()),
1223
("0000000000000000000000000000000000000000",): ("value:0", ()),
1224
("1111111111111111111111111111111111111111",): ("value:1", ()),
1225
("2222222222222222222222222222222222222222",): ("value:2", ()),
1226
("3333333333333333333333333333333333333333",): ("value:3", ()),
1227
("4444444444444444444444444444444444444444",): ("value:4", ()),
1229
1228
}, dict(node.all_items()))
1231
1230
def test_LeafNode_2_2(self):
1232
node_bytes = (b"type=leaf\n"
1233
b"00\x0000\x00\t00\x00ref00\x00value:0\n"
1234
b"00\x0011\x0000\x00ref00\t00\x00ref00\r01\x00ref01\x00value:1\n"
1235
b"11\x0033\x0011\x00ref22\t11\x00ref22\r11\x00ref22\x00value:3\n"
1236
b"11\x0044\x00\t11\x00ref00\x00value:4\n"
1231
node_bytes = ("type=leaf\n"
1232
"00\x0000\x00\t00\x00ref00\x00value:0\n"
1233
"00\x0011\x0000\x00ref00\t00\x00ref00\r01\x00ref01\x00value:1\n"
1234
"11\x0033\x0011\x00ref22\t11\x00ref22\r11\x00ref22\x00value:3\n"
1235
"11\x0044\x00\t11\x00ref00\x00value:4\n"
1239
1238
node = btree_index._LeafNode(node_bytes, 2, 2)
1240
1239
# We do direct access, or don't care about order, to leaf nodes most of
1241
1240
# the time, so a dict is useful:
1242
1241
self.assertEqual({
1243
(b'00', b'00'): (b'value:0', ((), ((b'00', b'ref00'),))),
1244
(b'00', b'11'): (b'value:1', (((b'00', b'ref00'),),
1245
((b'00', b'ref00'), (b'01', b'ref01')))),
1246
(b'11', b'33'): (b'value:3', (((b'11', b'ref22'),),
1247
((b'11', b'ref22'), (b'11', b'ref22')))),
1248
(b'11', b'44'): (b'value:4', ((), ((b'11', b'ref00'),)))
1242
('00', '00'): ('value:0', ((), (('00', 'ref00'),))),
1243
('00', '11'): ('value:1',
1244
((('00', 'ref00'),), (('00', 'ref00'), ('01', 'ref01')))),
1245
('11', '33'): ('value:3',
1246
((('11', 'ref22'),), (('11', 'ref22'), ('11', 'ref22')))),
1247
('11', '44'): ('value:4', ((), (('11', 'ref00'),)))
1249
1248
}, dict(node.all_items()))
1251
1250
def test_InternalNode_1(self):
1252
node_bytes = (b"type=internal\n"
1254
b"0000000000000000000000000000000000000000\n"
1255
b"1111111111111111111111111111111111111111\n"
1256
b"2222222222222222222222222222222222222222\n"
1257
b"3333333333333333333333333333333333333333\n"
1258
b"4444444444444444444444444444444444444444\n"
1251
node_bytes = ("type=internal\n"
1253
"0000000000000000000000000000000000000000\n"
1254
"1111111111111111111111111111111111111111\n"
1255
"2222222222222222222222222222222222222222\n"
1256
"3333333333333333333333333333333333333333\n"
1257
"4444444444444444444444444444444444444444\n"
1260
1259
node = btree_index._InternalNode(node_bytes)
1261
1260
# We want to bisect to find the right children from this node, so a
1262
1261
# vector is most useful.
1263
1262
self.assertEqual([
1264
(b"0000000000000000000000000000000000000000",),
1265
(b"1111111111111111111111111111111111111111",),
1266
(b"2222222222222222222222222222222222222222",),
1267
(b"3333333333333333333333333333333333333333",),
1268
(b"4444444444444444444444444444444444444444",),
1263
("0000000000000000000000000000000000000000",),
1264
("1111111111111111111111111111111111111111",),
1265
("2222222222222222222222222222222222222222",),
1266
("3333333333333333333333333333333333333333",),
1267
("4444444444444444444444444444444444444444",),
1270
1269
self.assertEqual(1, node.offset)
1272
1271
def test_LeafNode_2_2(self):
1273
node_bytes = (b"type=leaf\n"
1274
b"00\x0000\x00\t00\x00ref00\x00value:0\n"
1275
b"00\x0011\x0000\x00ref00\t00\x00ref00\r01\x00ref01\x00value:1\n"
1276
b"11\x0033\x0011\x00ref22\t11\x00ref22\r11\x00ref22\x00value:3\n"
1277
b"11\x0044\x00\t11\x00ref00\x00value:4\n"
1272
node_bytes = ("type=leaf\n"
1273
"00\x0000\x00\t00\x00ref00\x00value:0\n"
1274
"00\x0011\x0000\x00ref00\t00\x00ref00\r01\x00ref01\x00value:1\n"
1275
"11\x0033\x0011\x00ref22\t11\x00ref22\r11\x00ref22\x00value:3\n"
1276
"11\x0044\x00\t11\x00ref00\x00value:4\n"
1280
1279
node = btree_index._LeafNode(node_bytes, 2, 2)
1281
1280
# We do direct access, or don't care about order, to leaf nodes most of
1282
1281
# the time, so a dict is useful:
1283
1282
self.assertEqual({
1284
(b'00', b'00'): (b'value:0', ((), ((b'00', b'ref00'),))),
1285
(b'00', b'11'): (b'value:1', (((b'00', b'ref00'),),
1286
((b'00', b'ref00'), (b'01', b'ref01')))),
1287
(b'11', b'33'): (b'value:3', (((b'11', b'ref22'),),
1288
((b'11', b'ref22'), (b'11', b'ref22')))),
1289
(b'11', b'44'): (b'value:4', ((), ((b'11', b'ref00'),)))
1283
('00', '00'): ('value:0', ((), (('00', 'ref00'),))),
1284
('00', '11'): ('value:1',
1285
((('00', 'ref00'),), (('00', 'ref00'), ('01', 'ref01')))),
1286
('11', '33'): ('value:3',
1287
((('11', 'ref22'),), (('11', 'ref22'), ('11', 'ref22')))),
1288
('11', '44'): ('value:4', ((), (('11', 'ref00'),)))
1290
1289
}, dict(node.all_items()))
1292
1291
def assertFlattened(self, expected, key, value, refs):
1293
1292
flat_key, flat_line = self.parse_btree._flatten_node(
1294
1293
(None, key, value, refs), bool(refs))
1295
self.assertEqual(b'\x00'.join(key), flat_key)
1294
self.assertEqual('\x00'.join(key), flat_key)
1296
1295
self.assertEqual(expected, flat_line)
1298
1297
def test__flatten_node(self):
1299
self.assertFlattened(b'key\0\0value\n', (b'key',), b'value', [])
1300
self.assertFlattened(b'key\0tuple\0\0value str\n',
1301
(b'key', b'tuple'), b'value str', [])
1302
self.assertFlattened(b'key\0tuple\0triple\0\0value str\n',
1303
(b'key', b'tuple', b'triple'), b'value str', [])
1304
self.assertFlattened(b'k\0t\0s\0ref\0value str\n',
1305
(b'k', b't', b's'), b'value str', [[(b'ref',)]])
1306
self.assertFlattened(b'key\0tuple\0ref\0key\0value str\n',
1307
(b'key', b'tuple'), b'value str', [[(b'ref', b'key')]])
1308
self.assertFlattened(b"00\x0000\x00\t00\x00ref00\x00value:0\n",
1309
(b'00', b'00'), b'value:0', ((), ((b'00', b'ref00'),)))
1310
self.assertFlattened(
1311
b"00\x0011\x0000\x00ref00\t00\x00ref00\r01\x00ref01\x00value:1\n",
1312
(b'00', b'11'), b'value:1',
1313
(((b'00', b'ref00'),), ((b'00', b'ref00'), (b'01', b'ref01'))))
1314
self.assertFlattened(
1315
b"11\x0033\x0011\x00ref22\t11\x00ref22\r11\x00ref22\x00value:3\n",
1316
(b'11', b'33'), b'value:3',
1317
(((b'11', b'ref22'),), ((b'11', b'ref22'), (b'11', b'ref22'))))
1318
self.assertFlattened(
1319
b"11\x0044\x00\t11\x00ref00\x00value:4\n",
1320
(b'11', b'44'), b'value:4', ((), ((b'11', b'ref00'),)))
1298
self.assertFlattened('key\0\0value\n', ('key',), 'value', [])
1299
self.assertFlattened('key\0tuple\0\0value str\n',
1300
('key', 'tuple'), 'value str', [])
1301
self.assertFlattened('key\0tuple\0triple\0\0value str\n',
1302
('key', 'tuple', 'triple'), 'value str', [])
1303
self.assertFlattened('k\0t\0s\0ref\0value str\n',
1304
('k', 't', 's'), 'value str', [[('ref',)]])
1305
self.assertFlattened('key\0tuple\0ref\0key\0value str\n',
1306
('key', 'tuple'), 'value str', [[('ref', 'key')]])
1307
self.assertFlattened("00\x0000\x00\t00\x00ref00\x00value:0\n",
1308
('00', '00'), 'value:0', ((), (('00', 'ref00'),)))
1309
self.assertFlattened(
1310
"00\x0011\x0000\x00ref00\t00\x00ref00\r01\x00ref01\x00value:1\n",
1311
('00', '11'), 'value:1',
1312
((('00', 'ref00'),), (('00', 'ref00'), ('01', 'ref01'))))
1313
self.assertFlattened(
1314
"11\x0033\x0011\x00ref22\t11\x00ref22\r11\x00ref22\x00value:3\n",
1315
('11', '33'), 'value:3',
1316
((('11', 'ref22'),), (('11', 'ref22'), ('11', 'ref22'))))
1317
self.assertFlattened(
1318
"11\x0044\x00\t11\x00ref00\x00value:4\n",
1319
('11', '44'), 'value:4', ((), (('11', 'ref00'),)))
1323
1322
class TestCompiledBtree(tests.TestCase):