166
168
node_content = content[73:]
167
169
node_bytes = zlib.decompress(node_content)
168
170
expected_node = (b"type=leaf\n"
169
b"0000000000000000000000000000000000000000\x00\x00value:0\n"
170
b"1111111111111111111111111111111111111111\x00\x00value:1\n"
171
b"2222222222222222222222222222222222222222\x00\x00value:2\n"
172
b"3333333333333333333333333333333333333333\x00\x00value:3\n"
173
b"4444444444444444444444444444444444444444\x00\x00value:4\n")
171
b"0000000000000000000000000000000000000000\x00\x00value:0\n"
172
b"1111111111111111111111111111111111111111\x00\x00value:1\n"
173
b"2222222222222222222222222222222222222222\x00\x00value:2\n"
174
b"3333333333333333333333333333333333333333\x00\x00value:3\n"
175
b"4444444444444444444444444444444444444444\x00\x00value:4\n")
174
176
self.assertEqual(expected_node, node_bytes)
176
178
def test_root_leaf_2_2(self):
405
407
# Test that memory and disk are both used for query methods; and that
406
408
# None is skipped over happily.
407
409
self.assertEqual([(builder,) + node for node in sorted(nodes[:13])],
408
list(builder.iter_all_entries()))
410
list(builder.iter_all_entries()))
409
411
# Two nodes - one memory one disk
410
412
self.assertEqual({(builder,) + node for node in nodes[11:13]},
411
set(builder.iter_entries([nodes[12][0], nodes[11][0]])))
413
set(builder.iter_entries([nodes[12][0], nodes[11][0]])))
412
414
self.assertEqual(13, builder.key_count())
413
415
self.assertEqual({(builder,) + node for node in nodes[11:13]},
414
set(builder.iter_entries_prefix([nodes[12][0], nodes[11][0]])))
416
set(builder.iter_entries_prefix([nodes[12][0], nodes[11][0]])))
415
417
builder.add_node(*nodes[13])
416
418
self.assertEqual(3, len(builder._backing_indices))
417
419
self.assertEqual(2, builder._backing_indices[0].key_count())
479
481
# Test that memory and disk are both used for query methods; and that
480
482
# None is skipped over happily.
481
483
self.assertEqual([(builder,) + node for node in sorted(nodes[:13])],
482
list(builder.iter_all_entries()))
484
list(builder.iter_all_entries()))
483
485
# Two nodes - one memory one disk
484
486
self.assertEqual({(builder,) + node for node in nodes[11:13]},
485
set(builder.iter_entries([nodes[12][0], nodes[11][0]])))
487
set(builder.iter_entries([nodes[12][0], nodes[11][0]])))
486
488
self.assertEqual(13, builder.key_count())
487
489
self.assertEqual({(builder,) + node for node in nodes[11:13]},
488
set(builder.iter_entries_prefix([nodes[12][0], nodes[11][0]])))
490
set(builder.iter_entries_prefix([nodes[12][0], nodes[11][0]])))
489
491
builder.add_node(*nodes[13])
490
492
builder.add_node(*nodes[14])
491
493
builder.add_node(*nodes[15])
579
582
# Test that memory and disk are both used for query methods; and that
580
583
# None is skipped over happily.
581
584
self.assertEqual([(builder,) + node for node in sorted(nodes[:13])],
582
list(builder.iter_all_entries()))
585
list(builder.iter_all_entries()))
583
586
# Two nodes - one memory one disk
584
587
self.assertEqual({(builder,) + node for node in nodes[11:13]},
585
set(builder.iter_entries([nodes[12][0], nodes[11][0]])))
588
set(builder.iter_entries([nodes[12][0], nodes[11][0]])))
586
589
self.assertEqual(13, builder.key_count())
587
590
self.assertEqual({(builder,) + node for node in nodes[11:13]},
588
set(builder.iter_entries_prefix([nodes[12][0], nodes[11][0]])))
591
set(builder.iter_entries_prefix([nodes[12][0], nodes[11][0]])))
589
592
builder.add_node(*nodes[13])
590
593
self.assertEqual(3, len(builder._backing_indices))
591
594
self.assertEqual(2, builder._backing_indices[0].key_count())
714
717
self.assertEqual(70, index.key_count())
715
718
# The entire index should have been read, as it is one page long.
716
719
self.assertEqual([('readv', 'index', [(0, size)], False, None)],
718
721
self.assertEqualApproxCompressed(1173, size)
720
723
def test_with_offset_no_size(self):
721
724
index = self.make_index_with_offset(key_elements=1, ref_lists=1,
723
726
nodes=self.make_nodes(200, 1, 1))
724
index._size = None # throw away the size info
727
index._size = None # throw away the size info
725
728
self.assertEqual(200, index.key_count())
727
730
def test_with_small_offset(self):
817
820
t1 = transport.get_transport_from_url('trace+' + self.get_url(''))
818
821
t2 = self.get_transport()
820
btree_index.BTreeGraphIndex(t1, 'index', None) ==
821
btree_index.BTreeGraphIndex(t1, 'index', None))
823
btree_index.BTreeGraphIndex(t1, 'index', 20) ==
824
btree_index.BTreeGraphIndex(t1, 'index', 20))
826
btree_index.BTreeGraphIndex(t1, 'index', 20) ==
827
btree_index.BTreeGraphIndex(t2, 'index', 20))
829
btree_index.BTreeGraphIndex(t1, 'inde1', 20) ==
830
btree_index.BTreeGraphIndex(t1, 'inde2', 20))
832
btree_index.BTreeGraphIndex(t1, 'index', 10) ==
833
btree_index.BTreeGraphIndex(t1, 'index', 20))
835
btree_index.BTreeGraphIndex(t1, 'index', None) !=
836
btree_index.BTreeGraphIndex(t1, 'index', None))
838
btree_index.BTreeGraphIndex(t1, 'index', 20) !=
839
btree_index.BTreeGraphIndex(t1, 'index', 20))
841
btree_index.BTreeGraphIndex(t1, 'index', 20) !=
842
btree_index.BTreeGraphIndex(t2, 'index', 20))
844
btree_index.BTreeGraphIndex(t1, 'inde1', 20) !=
845
btree_index.BTreeGraphIndex(t1, 'inde2', 20))
847
btree_index.BTreeGraphIndex(t1, 'index', 10) !=
848
btree_index.BTreeGraphIndex(t1, 'index', 20))
823
btree_index.BTreeGraphIndex(t1, 'index', None)
824
== btree_index.BTreeGraphIndex(t1, 'index', None))
826
btree_index.BTreeGraphIndex(t1, 'index', 20)
827
== btree_index.BTreeGraphIndex(t1, 'index', 20))
829
btree_index.BTreeGraphIndex(t1, 'index', 20)
830
== btree_index.BTreeGraphIndex(t2, 'index', 20))
832
btree_index.BTreeGraphIndex(t1, 'inde1', 20)
833
== btree_index.BTreeGraphIndex(t1, 'inde2', 20))
835
btree_index.BTreeGraphIndex(t1, 'index', 10)
836
== btree_index.BTreeGraphIndex(t1, 'index', 20))
838
btree_index.BTreeGraphIndex(t1, 'index', None)
839
!= btree_index.BTreeGraphIndex(t1, 'index', None))
841
btree_index.BTreeGraphIndex(t1, 'index', 20)
842
!= btree_index.BTreeGraphIndex(t1, 'index', 20))
844
btree_index.BTreeGraphIndex(t1, 'index', 20)
845
!= btree_index.BTreeGraphIndex(t2, 'index', 20))
847
btree_index.BTreeGraphIndex(t1, 'inde1', 20)
848
!= btree_index.BTreeGraphIndex(t1, 'inde2', 20))
850
btree_index.BTreeGraphIndex(t1, 'index', 10)
851
!= btree_index.BTreeGraphIndex(t1, 'index', 20))
850
853
def test_key_too_big(self):
851
854
# the size that matters here is the _compressed_ size of the key, so we can't
906
909
# The last page is truncated
907
910
readv_request[-1] = (readv_request[-1][0], size % page_size)
908
911
expected = [('readv', 'index', [(0, page_size)], False, None),
909
('readv', 'index', readv_request, False, None)]
912
('readv', 'index', readv_request, False, None)]
910
913
if expected != t._activity:
911
914
self.assertEqualDiff(pprint.pformat(expected),
912
915
pprint.pformat(t._activity))
937
940
self.assertEqual(nodes[30], bare_nodes[0])
938
941
# Should have read the root node, then one leaf page:
939
942
self.assertEqual([('readv', 'index', [(0, 4096)], False, None),
940
('readv', 'index', [(8192, 4096), ], False, None)],
943
('readv', 'index', [(8192, 4096), ], False, None)],
943
946
def test_iter_key_prefix_1_element_key_None(self):
944
947
index = self.make_index()
945
948
self.assertRaises(_mod_index.BadIndexKey, list,
946
index.iter_entries_prefix([(None, )]))
949
index.iter_entries_prefix([(None, )]))
948
951
def test_iter_key_prefix_wrong_length(self):
949
952
index = self.make_index()
950
953
self.assertRaises(_mod_index.BadIndexKey, list,
951
index.iter_entries_prefix([(b'foo', None)]))
954
index.iter_entries_prefix([(b'foo', None)]))
952
955
index = self.make_index(key_elements=2)
953
956
self.assertRaises(_mod_index.BadIndexKey, list,
954
index.iter_entries_prefix([(b'foo', )]))
957
index.iter_entries_prefix([(b'foo', )]))
955
958
self.assertRaises(_mod_index.BadIndexKey, list,
956
index.iter_entries_prefix([(b'foo', None, None)]))
959
index.iter_entries_prefix([(b'foo', None, None)]))
958
961
def test_iter_key_prefix_1_key_element_no_refs(self):
959
962
index = self.make_index(nodes=[
960
963
((b'name', ), b'data', ()),
961
964
((b'ref', ), b'refdata', ())])
962
965
self.assertEqual({(index, (b'name', ), b'data'),
963
(index, (b'ref', ), b'refdata')},
964
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
966
(index, (b'ref', ), b'refdata')},
967
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
966
969
def test_iter_key_prefix_1_key_element_refs(self):
967
970
index = self.make_index(1, nodes=[
968
971
((b'name', ), b'data', ([(b'ref', )], )),
969
972
((b'ref', ), b'refdata', ([], ))])
970
973
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', )])))
974
(index, (b'ref', ), b'refdata', ((), ))},
975
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
974
977
def test_iter_key_prefix_2_key_element_no_refs(self):
975
978
index = self.make_index(key_elements=2, nodes=[
977
980
((b'name', b'fin2'), b'beta', ()),
978
981
((b'ref', b'erence'), b'refdata', ())])
979
982
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
(index, (b'ref', b'erence'), b'refdata')},
984
set(index.iter_entries_prefix(
985
[(b'name', b'fin1'), (b'ref', b'erence')])))
983
986
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)])))
987
(index, (b'name', b'fin2'), b'beta')},
988
set(index.iter_entries_prefix([(b'name', None)])))
987
990
def test_iter_key_prefix_2_key_element_refs(self):
988
991
index = self.make_index(1, key_elements=2, nodes=[
1213
1217
def test_LeafNode_1_0(self):
1214
1218
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")
1219
b"0000000000000000000000000000000000000000\x00\x00value:0\n"
1220
b"1111111111111111111111111111111111111111\x00\x00value:1\n"
1221
b"2222222222222222222222222222222222222222\x00\x00value:2\n"
1222
b"3333333333333333333333333333333333333333\x00\x00value:3\n"
1223
b"4444444444444444444444444444444444444444\x00\x00value:4\n")
1220
1224
node = btree_index._LeafNode(node_bytes, 1, 0)
1221
1225
# We do direct access, or don't care about order, to leaf nodes most of
1222
1226
# the time, so a dict is useful:
1231
1235
def test_LeafNode_2_2(self):
1232
1236
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"
1237
b"00\x0000\x00\t00\x00ref00\x00value:0\n"
1238
b"00\x0011\x0000\x00ref00\t00\x00ref00\r01\x00ref01\x00value:1\n"
1239
b"11\x0033\x0011\x00ref22\t11\x00ref22\r11\x00ref22\x00value:3\n"
1240
b"11\x0044\x00\t11\x00ref00\x00value:4\n"
1239
1243
node = btree_index._LeafNode(node_bytes, 2, 2)
1240
1244
# We do direct access, or don't care about order, to leaf nodes most of
1241
1245
# the time, so a dict is useful:
1242
1246
self.assertEqual({
1243
1247
(b'00', b'00'): (b'value:0', ((), ((b'00', b'ref00'),))),
1244
1248
(b'00', b'11'): (b'value:1', (((b'00', b'ref00'),),
1245
((b'00', b'ref00'), (b'01', b'ref01')))),
1249
((b'00', b'ref00'), (b'01', b'ref01')))),
1246
1250
(b'11', b'33'): (b'value:3', (((b'11', b'ref22'),),
1247
((b'11', b'ref22'), (b'11', b'ref22')))),
1251
((b'11', b'ref22'), (b'11', b'ref22')))),
1248
1252
(b'11', b'44'): (b'value:4', ((), ((b'11', b'ref00'),)))
1249
1253
}, dict(node.all_items()))
1251
1255
def test_InternalNode_1(self):
1252
1256
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"
1258
b"0000000000000000000000000000000000000000\n"
1259
b"1111111111111111111111111111111111111111\n"
1260
b"2222222222222222222222222222222222222222\n"
1261
b"3333333333333333333333333333333333333333\n"
1262
b"4444444444444444444444444444444444444444\n"
1260
1264
node = btree_index._InternalNode(node_bytes)
1261
1265
# We want to bisect to find the right children from this node, so a
1262
1266
# vector is most useful.
1272
1276
def test_LeafNode_2_2(self):
1273
1277
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"
1278
b"00\x0000\x00\t00\x00ref00\x00value:0\n"
1279
b"00\x0011\x0000\x00ref00\t00\x00ref00\r01\x00ref01\x00value:1\n"
1280
b"11\x0033\x0011\x00ref22\t11\x00ref22\r11\x00ref22\x00value:3\n"
1281
b"11\x0044\x00\t11\x00ref00\x00value:4\n"
1280
1284
node = btree_index._LeafNode(node_bytes, 2, 2)
1281
1285
# We do direct access, or don't care about order, to leaf nodes most of
1282
1286
# the time, so a dict is useful:
1283
1287
self.assertEqual({
1284
1288
(b'00', b'00'): (b'value:0', ((), ((b'00', b'ref00'),))),
1285
1289
(b'00', b'11'): (b'value:1', (((b'00', b'ref00'),),
1286
((b'00', b'ref00'), (b'01', b'ref01')))),
1290
((b'00', b'ref00'), (b'01', b'ref01')))),
1287
1291
(b'11', b'33'): (b'value:3', (((b'11', b'ref22'),),
1288
((b'11', b'ref22'), (b'11', b'ref22')))),
1292
((b'11', b'ref22'), (b'11', b'ref22')))),
1289
1293
(b'11', b'44'): (b'value:4', ((), ((b'11', b'ref00'),)))
1290
1294
}, dict(node.all_items()))
1298
1302
def test__flatten_node(self):
1299
1303
self.assertFlattened(b'key\0\0value\n', (b'key',), b'value', [])
1300
1304
self.assertFlattened(b'key\0tuple\0\0value str\n',
1301
(b'key', b'tuple'), b'value str', [])
1305
(b'key', b'tuple'), b'value str', [])
1302
1306
self.assertFlattened(b'key\0tuple\0triple\0\0value str\n',
1303
(b'key', b'tuple', b'triple'), b'value str', [])
1307
(b'key', b'tuple', b'triple'), b'value str', [])
1304
1308
self.assertFlattened(b'k\0t\0s\0ref\0value str\n',
1305
(b'k', b't', b's'), b'value str', [[(b'ref',)]])
1309
(b'k', b't', b's'), b'value str', [[(b'ref',)]])
1306
1310
self.assertFlattened(b'key\0tuple\0ref\0key\0value str\n',
1307
(b'key', b'tuple'), b'value str', [[(b'ref', b'key')]])
1311
(b'key', b'tuple'), b'value str', [[(b'ref', b'key')]])
1308
1312
self.assertFlattened(b"00\x0000\x00\t00\x00ref00\x00value:0\n",
1309
(b'00', b'00'), b'value:0', ((), ((b'00', b'ref00'),)))
1313
(b'00', b'00'), b'value:0', ((), ((b'00', b'ref00'),)))
1310
1314
self.assertFlattened(
1311
1315
b"00\x0011\x0000\x00ref00\t00\x00ref00\r01\x00ref01\x00value:1\n",
1312
1316
(b'00', b'11'), b'value:1',
1313
(((b'00', b'ref00'),), ((b'00', b'ref00'), (b'01', b'ref01'))))
1317
(((b'00', b'ref00'),), ((b'00', b'ref00'), (b'01', b'ref01'))))
1314
1318
self.assertFlattened(
1315
1319
b"11\x0033\x0011\x00ref22\t11\x00ref22\r11\x00ref22\x00value:3\n",
1316
1320
(b'11', b'33'), b'value:3',
1317
(((b'11', b'ref22'),), ((b'11', b'ref22'), (b'11', b'ref22'))))
1321
(((b'11', b'ref22'),), ((b'11', b'ref22'), (b'11', b'ref22'))))
1318
1322
self.assertFlattened(
1319
1323
b"11\x0044\x00\t11\x00ref00\x00value:4\n",
1320
1324
(b'11', b'44'), b'value:4', ((), ((b'11', b'ref00'),)))
1348
1352
def test_exact(self):
1349
1353
self.assertMultiBisectRight([(1, ['a'])], ['a'], ['a'])
1350
self.assertMultiBisectRight([(1, ['a']), (2, ['b'])], ['a', 'b'], ['a', 'b'])
1354
self.assertMultiBisectRight(
1355
[(1, ['a']), (2, ['b'])], ['a', 'b'], ['a', 'b'])
1351
1356
self.assertMultiBisectRight([(1, ['a']), (3, ['c'])],
1352
1357
['a', 'c'], ['a', 'b', 'c'])
1451
1456
self.assertExpandOffsets([1, 4, 9], index, [1, 4, 9])
1453
1458
def test_more_than_recommended(self):
1454
index = self.make_index(4096*100, 2)
1459
index = self.make_index(4096 * 100, 2)
1455
1460
self.assertExpandOffsets([1, 10], index, [1, 10])
1456
1461
self.assertExpandOffsets([1, 10, 20], index, [1, 10, 20])
1458
1463
def test_read_all_from_root(self):
1459
index = self.make_index(4096*10, 20)
1464
index = self.make_index(4096 * 10, 20)
1460
1465
self.assertExpandOffsets(list(range(10)), index, [0])
1462
1467
def test_read_all_when_cached(self):
1463
1468
# We've read enough that we can grab all the rest in a single request
1464
index = self.make_index(4096*10, 5)
1469
index = self.make_index(4096 * 10, 5)
1465
1470
self.prepare_index(index, node_ref_lists=0, key_length=1,
1466
1471
key_count=1000, row_lengths=[1, 9],
1467
1472
cached_offsets=[0, 1, 2, 5, 6])