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