855
876
chkmap._dump_tree())
856
877
# Save everything to the map, and start over
857
878
chkmap = CHKMap(store, chkmap._save())
858
chkmap.map(('aac',), 'v')
859
chkmap.map(('aad',), 'v')
860
chkmap.map(('aae',), 'v')
861
chkmap.map(('aaf',), 'v')
879
chkmap.map((b'aac',), b'v')
880
chkmap.map((b'aad',), b'v')
881
chkmap.map((b'aae',), b'v')
882
chkmap.map((b'aaf',), b'v')
862
883
# At this point, the previous nodes should not be paged in, but the
863
884
# newly added nodes would be
864
self.assertIsInstance(chkmap._root_node._items['aaa'], StaticTuple)
865
self.assertIsInstance(chkmap._root_node._items['aab'], StaticTuple)
866
self.assertIsInstance(chkmap._root_node._items['aac'], LeafNode)
867
self.assertIsInstance(chkmap._root_node._items['aad'], LeafNode)
868
self.assertIsInstance(chkmap._root_node._items['aae'], LeafNode)
869
self.assertIsInstance(chkmap._root_node._items['aaf'], LeafNode)
885
self.assertIsInstance(chkmap._root_node._items[b'aaa'], StaticTuple)
886
self.assertIsInstance(chkmap._root_node._items[b'aab'], StaticTuple)
887
self.assertIsInstance(chkmap._root_node._items[b'aac'], LeafNode)
888
self.assertIsInstance(chkmap._root_node._items[b'aad'], LeafNode)
889
self.assertIsInstance(chkmap._root_node._items[b'aae'], LeafNode)
890
self.assertIsInstance(chkmap._root_node._items[b'aaf'], LeafNode)
870
891
# Now unmapping one of the new nodes will use only the already-paged-in
871
892
# nodes to determine that we don't need to do more.
872
chkmap.unmap(('aaf',))
873
self.assertIsInstance(chkmap._root_node._items['aaa'], StaticTuple)
874
self.assertIsInstance(chkmap._root_node._items['aab'], StaticTuple)
875
self.assertIsInstance(chkmap._root_node._items['aac'], LeafNode)
876
self.assertIsInstance(chkmap._root_node._items['aad'], LeafNode)
877
self.assertIsInstance(chkmap._root_node._items['aae'], LeafNode)
893
chkmap.unmap((b'aaf',))
894
self.assertIsInstance(chkmap._root_node._items[b'aaa'], StaticTuple)
895
self.assertIsInstance(chkmap._root_node._items[b'aab'], StaticTuple)
896
self.assertIsInstance(chkmap._root_node._items[b'aac'], LeafNode)
897
self.assertIsInstance(chkmap._root_node._items[b'aad'], LeafNode)
898
self.assertIsInstance(chkmap._root_node._items[b'aae'], LeafNode)
879
900
def test_unmap_pages_in_if_necessary(self):
880
901
store = self.get_chk_bytes()
881
902
chkmap = CHKMap(store, None)
882
903
# Should fit 2 keys per LeafNode
883
904
chkmap._root_node.set_maximum_size(30)
884
chkmap.map(('aaa',), 'val')
885
chkmap.map(('aab',), 'val')
886
chkmap.map(('aac',), 'val')
905
chkmap.map((b'aaa',), b'val')
906
chkmap.map((b'aab',), b'val')
907
chkmap.map((b'aac',), b'val')
887
908
self.assertEqualDiff("'' InternalNode\n"
888
909
" 'aaa' LeafNode\n"
889
910
" ('aaa',) 'val'\n"
895
916
root_key = chkmap._save()
896
917
# Save everything to the map, and start over
897
918
chkmap = CHKMap(store, root_key)
898
chkmap.map(('aad',), 'v')
919
chkmap.map((b'aad',), b'v')
899
920
# At this point, the previous nodes should not be paged in, but the
900
921
# newly added node would be
901
self.assertIsInstance(chkmap._root_node._items['aaa'], StaticTuple)
902
self.assertIsInstance(chkmap._root_node._items['aab'], StaticTuple)
903
self.assertIsInstance(chkmap._root_node._items['aac'], StaticTuple)
904
self.assertIsInstance(chkmap._root_node._items['aad'], LeafNode)
922
self.assertIsInstance(chkmap._root_node._items[b'aaa'], StaticTuple)
923
self.assertIsInstance(chkmap._root_node._items[b'aab'], StaticTuple)
924
self.assertIsInstance(chkmap._root_node._items[b'aac'], StaticTuple)
925
self.assertIsInstance(chkmap._root_node._items[b'aad'], LeafNode)
905
926
# Unmapping the new node will check the existing nodes to see if they
907
928
# Clear the page cache so we ensure we have to read all the children
908
929
chk_map.clear_cache()
909
chkmap.unmap(('aad',))
910
self.assertIsInstance(chkmap._root_node._items['aaa'], LeafNode)
911
self.assertIsInstance(chkmap._root_node._items['aab'], LeafNode)
912
self.assertIsInstance(chkmap._root_node._items['aac'], LeafNode)
930
chkmap.unmap((b'aad',))
931
self.assertIsInstance(chkmap._root_node._items[b'aaa'], LeafNode)
932
self.assertIsInstance(chkmap._root_node._items[b'aab'], LeafNode)
933
self.assertIsInstance(chkmap._root_node._items[b'aac'], LeafNode)
914
935
def test_unmap_pages_in_from_page_cache(self):
915
936
store = self.get_chk_bytes()
916
937
chkmap = CHKMap(store, None)
917
938
# Should fit 2 keys per LeafNode
918
939
chkmap._root_node.set_maximum_size(30)
919
chkmap.map(('aaa',), 'val')
920
chkmap.map(('aab',), 'val')
921
chkmap.map(('aac',), 'val')
940
chkmap.map((b'aaa',), b'val')
941
chkmap.map((b'aab',), b'val')
942
chkmap.map((b'aac',), b'val')
922
943
root_key = chkmap._save()
923
944
# Save everything to the map, and start over
924
945
chkmap = CHKMap(store, root_key)
925
chkmap.map(('aad',), 'val')
946
chkmap.map((b'aad',), b'val')
926
947
self.assertEqualDiff("'' InternalNode\n"
927
948
" 'aaa' LeafNode\n"
928
949
" ('aaa',) 'val'\n"
955
976
# Unmapping the new node will check the nodes from the page cache
956
977
# first, and not have to read in 'aaa'
957
chkmap.unmap(('aad',))
958
self.assertIsInstance(chkmap._root_node._items['aaa'], StaticTuple)
959
self.assertIsInstance(chkmap._root_node._items['aab'], LeafNode)
960
self.assertIsInstance(chkmap._root_node._items['aac'], LeafNode)
978
chkmap.unmap((b'aad',))
979
self.assertIsInstance(chkmap._root_node._items[b'aaa'], StaticTuple)
980
self.assertIsInstance(chkmap._root_node._items[b'aab'], LeafNode)
981
self.assertIsInstance(chkmap._root_node._items[b'aac'], LeafNode)
962
983
def test_unmap_uses_existing_items(self):
963
984
store = self.get_chk_bytes()
964
985
chkmap = CHKMap(store, None)
965
986
# Should fit 2 keys per LeafNode
966
987
chkmap._root_node.set_maximum_size(30)
967
chkmap.map(('aaa',), 'val')
968
chkmap.map(('aab',), 'val')
969
chkmap.map(('aac',), 'val')
988
chkmap.map((b'aaa',), b'val')
989
chkmap.map((b'aab',), b'val')
990
chkmap.map((b'aac',), b'val')
970
991
root_key = chkmap._save()
971
992
# Save everything to the map, and start over
972
993
chkmap = CHKMap(store, root_key)
973
chkmap.map(('aad',), 'val')
974
chkmap.map(('aae',), 'val')
975
chkmap.map(('aaf',), 'val')
994
chkmap.map((b'aad',), b'val')
995
chkmap.map((b'aae',), b'val')
996
chkmap.map((b'aaf',), b'val')
976
997
# At this point, the previous nodes should not be paged in, but the
977
998
# newly added node would be
978
self.assertIsInstance(chkmap._root_node._items['aaa'], StaticTuple)
979
self.assertIsInstance(chkmap._root_node._items['aab'], StaticTuple)
980
self.assertIsInstance(chkmap._root_node._items['aac'], StaticTuple)
981
self.assertIsInstance(chkmap._root_node._items['aad'], LeafNode)
982
self.assertIsInstance(chkmap._root_node._items['aae'], LeafNode)
983
self.assertIsInstance(chkmap._root_node._items['aaf'], LeafNode)
999
self.assertIsInstance(chkmap._root_node._items[b'aaa'], StaticTuple)
1000
self.assertIsInstance(chkmap._root_node._items[b'aab'], StaticTuple)
1001
self.assertIsInstance(chkmap._root_node._items[b'aac'], StaticTuple)
1002
self.assertIsInstance(chkmap._root_node._items[b'aad'], LeafNode)
1003
self.assertIsInstance(chkmap._root_node._items[b'aae'], LeafNode)
1004
self.assertIsInstance(chkmap._root_node._items[b'aaf'], LeafNode)
985
1006
# Unmapping a new node will see the other nodes that are already in
986
1007
# memory, and not need to page in anything else
987
chkmap.unmap(('aad',))
988
self.assertIsInstance(chkmap._root_node._items['aaa'], StaticTuple)
989
self.assertIsInstance(chkmap._root_node._items['aab'], StaticTuple)
990
self.assertIsInstance(chkmap._root_node._items['aac'], StaticTuple)
991
self.assertIsInstance(chkmap._root_node._items['aae'], LeafNode)
992
self.assertIsInstance(chkmap._root_node._items['aaf'], LeafNode)
1008
chkmap.unmap((b'aad',))
1009
self.assertIsInstance(chkmap._root_node._items[b'aaa'], StaticTuple)
1010
self.assertIsInstance(chkmap._root_node._items[b'aab'], StaticTuple)
1011
self.assertIsInstance(chkmap._root_node._items[b'aac'], StaticTuple)
1012
self.assertIsInstance(chkmap._root_node._items[b'aae'], LeafNode)
1013
self.assertIsInstance(chkmap._root_node._items[b'aaf'], LeafNode)
994
1015
def test_iter_changes_empty_ab(self):
995
1016
# Asking for changes between an empty dict to a dict with keys returns
997
1018
basis = self._get_map({}, maximum_size=10)
998
1019
target = self._get_map(
999
{('a',): 'content here', ('b',): 'more content'},
1020
{(b'a',): b'content here', (b'b',): b'more content'},
1000
1021
chk_bytes=basis._store, maximum_size=10)
1001
self.assertEqual([(('a',), None, 'content here'),
1002
(('b',), None, 'more content')],
1022
self.assertEqual([((b'a',), None, b'content here'),
1023
((b'b',), None, b'more content')],
1003
1024
sorted(list(target.iter_changes(basis))))
1005
1026
def test_iter_changes_ab_empty(self):
1006
1027
# Asking for changes between a dict with keys to an empty dict returns
1007
1028
# all the keys.
1008
basis = self._get_map({('a',): 'content here', ('b',): 'more content'},
1029
basis = self._get_map({(b'a',): b'content here', (b'b',): b'more content'},
1009
1030
maximum_size=10)
1010
1031
target = self._get_map({}, chk_bytes=basis._store, maximum_size=10)
1011
self.assertEqual([(('a',), 'content here', None),
1012
(('b',), 'more content', None)],
1032
self.assertEqual([((b'a',), b'content here', None),
1033
((b'b',), b'more content', None)],
1013
1034
sorted(list(target.iter_changes(basis))))
1015
1036
def test_iter_changes_empty_empty_is_empty(self):
1018
1039
self.assertEqual([], sorted(list(target.iter_changes(basis))))
1020
1041
def test_iter_changes_ab_ab_is_empty(self):
1021
basis = self._get_map({('a',): 'content here', ('b',): 'more content'},
1042
basis = self._get_map({(b'a',): b'content here', (b'b',): b'more content'},
1022
1043
maximum_size=10)
1023
1044
target = self._get_map(
1024
{('a',): 'content here', ('b',): 'more content'},
1045
{(b'a',): b'content here', (b'b',): b'more content'},
1025
1046
chk_bytes=basis._store, maximum_size=10)
1026
1047
self.assertEqual([], sorted(list(target.iter_changes(basis))))
1028
1049
def test_iter_changes_ab_ab_nodes_not_loaded(self):
1029
basis = self._get_map({('a',): 'content here', ('b',): 'more content'},
1050
basis = self._get_map({(b'a',): b'content here', (b'b',): b'more content'},
1030
1051
maximum_size=10)
1031
1052
target = self._get_map(
1032
{('a',): 'content here', ('b',): 'more content'},
1053
{(b'a',): b'content here', (b'b',): b'more content'},
1033
1054
chk_bytes=basis._store, maximum_size=10)
1034
1055
list(target.iter_changes(basis))
1035
1056
self.assertIsInstance(target._root_node, StaticTuple)
1036
1057
self.assertIsInstance(basis._root_node, StaticTuple)
1038
1059
def test_iter_changes_ab_ab_changed_values_shown(self):
1039
basis = self._get_map({('a',): 'content here', ('b',): 'more content'},
1060
basis = self._get_map({(b'a',): b'content here', (b'b',): b'more content'},
1040
1061
maximum_size=10)
1041
1062
target = self._get_map(
1042
{('a',): 'content here', ('b',): 'different content'},
1063
{(b'a',): b'content here', (b'b',): b'different content'},
1043
1064
chk_bytes=basis._store, maximum_size=10)
1044
1065
result = sorted(list(target.iter_changes(basis)))
1045
self.assertEqual([(('b',), 'more content', 'different content')],
1066
self.assertEqual([((b'b',), b'more content', b'different content')],
1048
1069
def test_iter_changes_mixed_node_length(self):
1081
1102
# aaa to be not loaded
1082
1103
# aaa not to be in result.
1083
basis_dict = {('aaa',): 'foo bar',
1084
('aab',): 'common altered a', ('b',): 'foo bar b'}
1104
basis_dict = {(b'aaa',): b'foo bar',
1105
(b'aab',): b'common altered a', (b'b',): b'foo bar b'}
1085
1106
# target splits at byte 1, at is target only
1086
target_dict = {('aaa',): 'foo bar',
1087
('aab',): 'common altered b', ('at',): 'foo bar t'}
1107
target_dict = {(b'aaa',): b'foo bar',
1108
(b'aab',): b'common altered b', (b'at',): b'foo bar t'}
1088
1109
basis = self._get_map(basis_dict, maximum_size=10)
1089
1110
target = self._get_map(target_dict, maximum_size=10,
1090
1111
chk_bytes=basis._store)
1091
1112
basis_get = basis._store.get_record_stream
1092
1113
def get_record_stream(keys, order, fulltext):
1093
if ('sha1:1adf7c0d1b9140ab5f33bb64c6275fa78b1580b7',) in keys:
1094
self.fail("'aaa' pointer was followed %r" % keys)
1114
if (b'sha1:1adf7c0d1b9140ab5f33bb64c6275fa78b1580b7',) in keys:
1115
raise AssertionError("'aaa' pointer was followed %r" % keys)
1095
1116
return basis_get(keys, order, fulltext)
1096
1117
basis._store.get_record_stream = get_record_stream
1097
1118
result = sorted(list(target.iter_changes(basis)))
1098
1119
for change in result:
1099
if change[0] == ('aaa',):
1120
if change[0] == (b'aaa',):
1100
1121
self.fail("Found unexpected change: %s" % change)
1102
1123
def test_iter_changes_unchanged_keys_in_multi_key_leafs_ignored(self):
1103
1124
# Within a leaf there are no hash's to exclude keys, make sure multi
1104
1125
# value leaf nodes are handled well.
1105
basis_dict = {('aaa',): 'foo bar',
1106
('aab',): 'common altered a', ('b',): 'foo bar b'}
1107
target_dict = {('aaa',): 'foo bar',
1108
('aab',): 'common altered b', ('at',): 'foo bar t'}
1126
basis_dict = {(b'aaa',): b'foo bar',
1127
(b'aab',): b'common altered a', (b'b',): b'foo bar b'}
1128
target_dict = {(b'aaa',): b'foo bar',
1129
(b'aab',): b'common altered b', (b'at',): b'foo bar t'}
1110
(('aab',), 'common altered a', 'common altered b'),
1111
(('at',), None, 'foo bar t'),
1112
(('b',), 'foo bar b', None),
1131
((b'aab',), b'common altered a', b'common altered b'),
1132
((b'at',), None, b'foo bar t'),
1133
((b'b',), b'foo bar b', None),
1114
1135
basis = self._get_map(basis_dict)
1115
1136
target = self._get_map(target_dict, chk_bytes=basis._store)
1124
1145
def test_iteritems_two_items(self):
1125
1146
chk_bytes = self.get_chk_bytes()
1126
1147
root_key = CHKMap.from_dict(chk_bytes,
1127
{"a":"content here", "b":"more content"})
1148
{(b"a", ): b"content here", (b"b", ): b"more content"})
1128
1149
chkmap = CHKMap(chk_bytes, root_key)
1129
self.assertEqual([(("a",), "content here"), (("b",), "more content")],
1150
self.assertEqual([((b"a",), b"content here"), ((b"b",), b"more content")],
1130
1151
sorted(list(chkmap.iteritems())))
1132
1153
def test_iteritems_selected_one_of_two_items(self):
1133
chkmap = self._get_map( {("a",):"content here", ("b",):"more content"})
1134
self.assertEqual({("a",): "content here"},
1135
self.to_dict(chkmap, [("a",)]))
1154
chkmap = self._get_map({(b"a",):b"content here", (b"b",):b"more content"})
1155
self.assertEqual({(b"a",): b"content here"},
1156
self.to_dict(chkmap, [(b"a",)]))
1137
1158
def test_iteritems_keys_prefixed_by_2_width_nodes(self):
1138
1159
chkmap = self._get_map(
1139
{("a","a"):"content here", ("a", "b",):"more content",
1140
("b", ""): 'boring content'},
1160
{(b"a", b"a"): b"content here", (b"a", b"b",):b"more content",
1161
(b"b", b""): b'boring content'},
1141
1162
maximum_size=10, key_width=2)
1142
1163
self.assertEqual(
1143
{("a", "a"): "content here", ("a", "b"): 'more content'},
1144
self.to_dict(chkmap, [("a",)]))
1164
{(b"a", b"a"): b"content here", (b"a", b"b"): b'more content'},
1165
self.to_dict(chkmap, [(b"a",)]))
1146
1167
def test_iteritems_keys_prefixed_by_2_width_nodes_hashed(self):
1147
search_key_func = chk_map.search_key_registry.get('hash-16-way')
1148
self.assertEqual('E8B7BE43\x00E8B7BE43',
1149
search_key_func(StaticTuple('a', 'a')))
1150
self.assertEqual('E8B7BE43\x0071BEEFF9',
1151
search_key_func(StaticTuple('a', 'b')))
1152
self.assertEqual('71BEEFF9\x0000000000',
1153
search_key_func(StaticTuple('b', '')))
1168
search_key_func = chk_map.search_key_registry.get(b'hash-16-way')
1169
self.assertEqual(b'E8B7BE43\x00E8B7BE43',
1170
search_key_func(StaticTuple(b'a', b'a')))
1171
self.assertEqual(b'E8B7BE43\x0071BEEFF9',
1172
search_key_func(StaticTuple(b'a', b'b')))
1173
self.assertEqual(b'71BEEFF9\x0000000000',
1174
search_key_func(StaticTuple(b'b', b'')))
1154
1175
chkmap = self._get_map(
1155
{("a","a"):"content here", ("a", "b",):"more content",
1156
("b", ""): 'boring content'},
1176
{(b"a", b"a"): b"content here", (b"a", b"b",): b"more content",
1177
(b"b", b""): b'boring content'},
1157
1178
maximum_size=10, key_width=2, search_key_func=search_key_func)
1158
1179
self.assertEqual(
1159
{("a", "a"): "content here", ("a", "b"): 'more content'},
1160
self.to_dict(chkmap, [("a",)]))
1180
{(b"a", b"a"): b"content here", (b"a", b"b"): b'more content'},
1181
self.to_dict(chkmap, [(b"a",)]))
1162
1183
def test_iteritems_keys_prefixed_by_2_width_one_leaf(self):
1163
1184
chkmap = self._get_map(
1164
{("a","a"):"content here", ("a", "b",):"more content",
1165
("b", ""): 'boring content'}, key_width=2)
1185
{(b"a", b"a"):b"content here", (b"a", b"b",): b"more content",
1186
(b"b", b""): b'boring content'}, key_width=2)
1166
1187
self.assertEqual(
1167
{("a", "a"): "content here", ("a", "b"): 'more content'},
1168
self.to_dict(chkmap, [("a",)]))
1188
{(b"a", b"a"): b"content here", (b"a", b"b"): b'more content'},
1189
self.to_dict(chkmap, [(b"a",)]))
1170
1191
def test___len__empty(self):
1171
1192
chkmap = self._get_map({})
1172
1193
self.assertEqual(0, len(chkmap))
1174
1195
def test___len__2(self):
1175
chkmap = self._get_map({("foo",):"bar", ("gam",):"quux"})
1196
chkmap = self._get_map({(b"foo",): b"bar", (b"gam",): b"quux"})
1176
1197
self.assertEqual(2, len(chkmap))
1178
1199
def test_max_size_100_bytes_new(self):
1179
1200
# When there is a 100 byte upper node limit, a tree is formed.
1180
chkmap = self._get_map({("k1"*50,):"v1", ("k2"*50,):"v2"}, maximum_size=100)
1201
chkmap = self._get_map({(b"k1"*50,):b"v1", (b"k2"*50,):b"v2"}, maximum_size=100)
1181
1202
# We expect three nodes:
1182
1203
# A root, with two children, and with two key prefixes - k1 to one, and
1183
1204
# k2 to the other as our node splitting is only just being developed.
1472
1493
def test_current_size_items(self):
1473
1494
node = LeafNode()
1474
1495
base_size = node._current_size()
1475
node.map(None, ("foo bar",), "baz")
1496
node.map(None, (b"foo bar",), b"baz")
1476
1497
self.assertEqual(base_size + 14, node._current_size())
1478
1499
def test_deserialise_empty(self):
1479
node = LeafNode.deserialise("chkleaf:\n10\n1\n0\n\n", ("sha1:1234",))
1500
node = LeafNode.deserialise(b"chkleaf:\n10\n1\n0\n\n", (b"sha1:1234",))
1480
1501
self.assertEqual(0, len(node))
1481
1502
self.assertEqual(10, node.maximum_size)
1482
self.assertEqual(("sha1:1234",), node.key())
1503
self.assertEqual((b"sha1:1234",), node.key())
1483
1504
self.assertIs(None, node._search_prefix)
1484
1505
self.assertIs(None, node._common_serialised_prefix)
1486
1507
def test_deserialise_items(self):
1487
1508
node = LeafNode.deserialise(
1488
"chkleaf:\n0\n1\n2\n\nfoo bar\x001\nbaz\nquux\x001\nblarh\n",
1509
b"chkleaf:\n0\n1\n2\n\nfoo bar\x001\nbaz\nquux\x001\nblarh\n",
1490
1511
self.assertEqual(2, len(node))
1491
self.assertEqual([(("foo bar",), "baz"), (("quux",), "blarh")],
1512
self.assertEqual([((b"foo bar",), b"baz"), ((b"quux",), b"blarh")],
1492
1513
sorted(node.iteritems(None)))
1494
1515
def test_deserialise_item_with_null_width_1(self):
1495
1516
node = LeafNode.deserialise(
1496
"chkleaf:\n0\n1\n2\n\nfoo\x001\nbar\x00baz\nquux\x001\nblarh\n",
1517
b"chkleaf:\n0\n1\n2\n\nfoo\x001\nbar\x00baz\nquux\x001\nblarh\n",
1498
1519
self.assertEqual(2, len(node))
1499
self.assertEqual([(("foo",), "bar\x00baz"), (("quux",), "blarh")],
1520
self.assertEqual([((b"foo",), b"bar\x00baz"), ((b"quux",), b"blarh")],
1500
1521
sorted(node.iteritems(None)))
1502
1523
def test_deserialise_item_with_null_width_2(self):
1503
1524
node = LeafNode.deserialise(
1504
"chkleaf:\n0\n2\n2\n\nfoo\x001\x001\nbar\x00baz\n"
1505
"quux\x00\x001\nblarh\n",
1525
b"chkleaf:\n0\n2\n2\n\nfoo\x001\x001\nbar\x00baz\n"
1526
b"quux\x00\x001\nblarh\n",
1507
1528
self.assertEqual(2, len(node))
1508
self.assertEqual([(("foo", "1"), "bar\x00baz"), (("quux", ""), "blarh")],
1529
self.assertEqual([((b"foo", b"1"), b"bar\x00baz"), ((b"quux", b""), b"blarh")],
1509
1530
sorted(node.iteritems(None)))
1511
1532
def test_iteritems_selected_one_of_two_items(self):
1512
1533
node = LeafNode.deserialise(
1513
"chkleaf:\n0\n1\n2\n\nfoo bar\x001\nbaz\nquux\x001\nblarh\n",
1534
b"chkleaf:\n0\n1\n2\n\nfoo bar\x001\nbaz\nquux\x001\nblarh\n",
1515
1536
self.assertEqual(2, len(node))
1516
self.assertEqual([(("quux",), "blarh")],
1517
sorted(node.iteritems(None, [("quux",), ("qaz",)])))
1537
self.assertEqual([((b"quux",), b"blarh")],
1538
sorted(node.iteritems(None, [(b"quux",), (b"qaz",)])))
1519
1540
def test_deserialise_item_with_common_prefix(self):
1520
1541
node = LeafNode.deserialise(
1521
"chkleaf:\n0\n2\n2\nfoo\x00\n1\x001\nbar\x00baz\n2\x001\nblarh\n",
1542
b"chkleaf:\n0\n2\n2\nfoo\x00\n1\x001\nbar\x00baz\n2\x001\nblarh\n",
1523
1544
self.assertEqual(2, len(node))
1524
self.assertEqual([(("foo", "1"), "bar\x00baz"), (("foo", "2"), "blarh")],
1545
self.assertEqual([((b"foo", b"1"), b"bar\x00baz"), ((b"foo", b"2"), b"blarh")],
1525
1546
sorted(node.iteritems(None)))
1526
1547
self.assertIs(chk_map._unknown, node._search_prefix)
1527
self.assertEqual('foo\x00', node._common_serialised_prefix)
1548
self.assertEqual(b'foo\x00', node._common_serialised_prefix)
1529
1550
def test_deserialise_multi_line(self):
1530
1551
node = LeafNode.deserialise(
1531
"chkleaf:\n0\n2\n2\nfoo\x00\n1\x002\nbar\nbaz\n2\x002\nblarh\n\n",
1552
b"chkleaf:\n0\n2\n2\nfoo\x00\n1\x002\nbar\nbaz\n2\x002\nblarh\n\n",
1533
1554
self.assertEqual(2, len(node))
1534
self.assertEqual([(("foo", "1"), "bar\nbaz"),
1535
(("foo", "2"), "blarh\n"),
1555
self.assertEqual([((b"foo", b"1"), b"bar\nbaz"),
1556
((b"foo", b"2"), b"blarh\n"),
1536
1557
], sorted(node.iteritems(None)))
1537
1558
self.assertIs(chk_map._unknown, node._search_prefix)
1538
self.assertEqual('foo\x00', node._common_serialised_prefix)
1559
self.assertEqual(b'foo\x00', node._common_serialised_prefix)
1540
1561
def test_key_new(self):
1541
1562
node = LeafNode()
1542
1563
self.assertEqual(None, node.key())
1544
1565
def test_key_after_map(self):
1545
node = LeafNode.deserialise("chkleaf:\n10\n1\n0\n\n", ("sha1:1234",))
1546
node.map(None, ("foo bar",), "baz quux")
1566
node = LeafNode.deserialise(b"chkleaf:\n10\n1\n0\n\n", (b"sha1:1234",))
1567
node.map(None, (b"foo bar",), b"baz quux")
1547
1568
self.assertEqual(None, node.key())
1549
1570
def test_key_after_unmap(self):
1550
1571
node = LeafNode.deserialise(
1551
"chkleaf:\n0\n1\n2\n\nfoo bar\x001\nbaz\nquux\x001\nblarh\n",
1553
node.unmap(None, ("foo bar",))
1572
b"chkleaf:\n0\n1\n2\n\nfoo bar\x001\nbaz\nquux\x001\nblarh\n",
1574
node.unmap(None, (b"foo bar",))
1554
1575
self.assertEqual(None, node.key())
1556
1577
def test_map_exceeding_max_size_only_entry_new(self):
1557
1578
node = LeafNode()
1558
1579
node.set_maximum_size(10)
1559
result = node.map(None, ("foo bar",), "baz quux")
1560
self.assertEqual(("foo bar", [("", node)]), result)
1580
result = node.map(None, (b"foo bar",), b"baz quux")
1581
self.assertEqual((b"foo bar", [(b"", node)]), result)
1561
1582
self.assertTrue(10 < node._current_size())
1563
1584
def test_map_exceeding_max_size_second_entry_early_difference_new(self):
1564
1585
node = LeafNode()
1565
1586
node.set_maximum_size(10)
1566
node.map(None, ("foo bar",), "baz quux")
1567
prefix, result = list(node.map(None, ("blue",), "red"))
1568
self.assertEqual("", prefix)
1587
node.map(None, (b"foo bar",), b"baz quux")
1588
prefix, result = list(node.map(None, (b"blue",), b"red"))
1589
self.assertEqual(b"", prefix)
1569
1590
self.assertEqual(2, len(result))
1570
split_chars = set([result[0][0], result[1][0]])
1571
self.assertEqual(set(["f", "b"]), split_chars)
1591
split_chars = {result[0][0], result[1][0]}
1592
self.assertEqual({b"f", b"b"}, split_chars)
1572
1593
nodes = dict(result)
1574
self.assertEqual({("foo bar",): "baz quux"}, self.to_dict(node, None))
1595
self.assertEqual({(b"foo bar",): b"baz quux"}, self.to_dict(node, None))
1575
1596
self.assertEqual(10, node.maximum_size)
1576
1597
self.assertEqual(1, node._key_width)
1578
self.assertEqual({("blue",): "red"}, self.to_dict(node, None))
1599
self.assertEqual({(b"blue",): b"red"}, self.to_dict(node, None))
1579
1600
self.assertEqual(10, node.maximum_size)
1580
1601
self.assertEqual(1, node._key_width)
1582
1603
def test_map_first(self):
1583
1604
node = LeafNode()
1584
result = node.map(None, ("foo bar",), "baz quux")
1585
self.assertEqual(("foo bar", [("", node)]), result)
1586
self.assertEqual({("foo bar",):"baz quux"}, self.to_dict(node, None))
1605
result = node.map(None, (b"foo bar",), b"baz quux")
1606
self.assertEqual((b"foo bar", [(b"", node)]), result)
1607
self.assertEqual({(b"foo bar",):b"baz quux"}, self.to_dict(node, None))
1587
1608
self.assertEqual(1, len(node))
1589
1610
def test_map_second(self):
1590
1611
node = LeafNode()
1591
node.map(None, ("foo bar",), "baz quux")
1592
result = node.map(None, ("bingo",), "bango")
1593
self.assertEqual(("", [("", node)]), result)
1594
self.assertEqual({("foo bar",):"baz quux", ("bingo",):"bango"},
1612
node.map(None, (b"foo bar",), b"baz quux")
1613
result = node.map(None, (b"bingo",), b"bango")
1614
self.assertEqual((b"", [(b"", node)]), result)
1615
self.assertEqual({(b"foo bar",): b"baz quux", (b"bingo",): b"bango"},
1595
1616
self.to_dict(node, None))
1596
1617
self.assertEqual(2, len(node))
1598
1619
def test_map_replacement(self):
1599
1620
node = LeafNode()
1600
node.map(None, ("foo bar",), "baz quux")
1601
result = node.map(None, ("foo bar",), "bango")
1602
self.assertEqual(("foo bar", [("", node)]), result)
1603
self.assertEqual({("foo bar",): "bango"},
1621
node.map(None, (b"foo bar",), b"baz quux")
1622
result = node.map(None, (b"foo bar",), b"bango")
1623
self.assertEqual((b"foo bar", [(b"", node)]), result)
1624
self.assertEqual({(b"foo bar",): b"bango"},
1604
1625
self.to_dict(node, None))
1605
1626
self.assertEqual(1, len(node))
1651
1672
def test_map_maintains_common_prefixes(self):
1652
1673
node = LeafNode()
1653
1674
node._key_width = 2
1654
node.map(None, ("foo bar", "baz"), "baz quux")
1655
self.assertEqual('foo bar\x00baz', node._search_prefix)
1656
self.assertEqual('foo bar\x00baz', node._common_serialised_prefix)
1657
node.map(None, ("foo bar", "bing"), "baz quux")
1658
self.assertEqual('foo bar\x00b', node._search_prefix)
1659
self.assertEqual('foo bar\x00b', node._common_serialised_prefix)
1660
node.map(None, ("fool", "baby"), "baz quux")
1661
self.assertEqual('foo', node._search_prefix)
1662
self.assertEqual('foo', node._common_serialised_prefix)
1663
node.map(None, ("foo bar", "baz"), "replaced")
1664
self.assertEqual('foo', node._search_prefix)
1665
self.assertEqual('foo', node._common_serialised_prefix)
1666
node.map(None, ("very", "different"), "value")
1667
self.assertEqual('', node._search_prefix)
1668
self.assertEqual('', node._common_serialised_prefix)
1675
node.map(None, (b"foo bar", b"baz"), b"baz quux")
1676
self.assertEqual(b'foo bar\x00baz', node._search_prefix)
1677
self.assertEqual(b'foo bar\x00baz', node._common_serialised_prefix)
1678
node.map(None, (b"foo bar", b"bing"), b"baz quux")
1679
self.assertEqual(b'foo bar\x00b', node._search_prefix)
1680
self.assertEqual(b'foo bar\x00b', node._common_serialised_prefix)
1681
node.map(None, (b"fool", b"baby"), b"baz quux")
1682
self.assertEqual(b'foo', node._search_prefix)
1683
self.assertEqual(b'foo', node._common_serialised_prefix)
1684
node.map(None, (b"foo bar", b"baz"), b"replaced")
1685
self.assertEqual(b'foo', node._search_prefix)
1686
self.assertEqual(b'foo', node._common_serialised_prefix)
1687
node.map(None, (b"very", b"different"), b"value")
1688
self.assertEqual(b'', node._search_prefix)
1689
self.assertEqual(b'', node._common_serialised_prefix)
1670
1691
def test_unmap_maintains_common_prefixes(self):
1671
1692
node = LeafNode()
1672
1693
node._key_width = 2
1673
node.map(None, ("foo bar", "baz"), "baz quux")
1674
node.map(None, ("foo bar", "bing"), "baz quux")
1675
node.map(None, ("fool", "baby"), "baz quux")
1676
node.map(None, ("very", "different"), "value")
1677
self.assertEqual('', node._search_prefix)
1678
self.assertEqual('', node._common_serialised_prefix)
1679
node.unmap(None, ("very", "different"))
1680
self.assertEqual("foo", node._search_prefix)
1681
self.assertEqual("foo", node._common_serialised_prefix)
1682
node.unmap(None, ("fool", "baby"))
1683
self.assertEqual('foo bar\x00b', node._search_prefix)
1684
self.assertEqual('foo bar\x00b', node._common_serialised_prefix)
1685
node.unmap(None, ("foo bar", "baz"))
1686
self.assertEqual('foo bar\x00bing', node._search_prefix)
1687
self.assertEqual('foo bar\x00bing', node._common_serialised_prefix)
1688
node.unmap(None, ("foo bar", "bing"))
1694
node.map(None, (b"foo bar", b"baz"), b"baz quux")
1695
node.map(None, (b"foo bar", b"bing"), b"baz quux")
1696
node.map(None, (b"fool", b"baby"), b"baz quux")
1697
node.map(None, (b"very", b"different"), b"value")
1698
self.assertEqual(b'', node._search_prefix)
1699
self.assertEqual(b'', node._common_serialised_prefix)
1700
node.unmap(None, (b"very", b"different"))
1701
self.assertEqual(b"foo", node._search_prefix)
1702
self.assertEqual(b"foo", node._common_serialised_prefix)
1703
node.unmap(None, (b"fool", b"baby"))
1704
self.assertEqual(b'foo bar\x00b', node._search_prefix)
1705
self.assertEqual(b'foo bar\x00b', node._common_serialised_prefix)
1706
node.unmap(None, (b"foo bar", b"baz"))
1707
self.assertEqual(b'foo bar\x00bing', node._search_prefix)
1708
self.assertEqual(b'foo bar\x00bing', node._common_serialised_prefix)
1709
node.unmap(None, (b"foo bar", b"bing"))
1689
1710
self.assertEqual(None, node._search_prefix)
1690
1711
self.assertEqual(None, node._common_serialised_prefix)
1738
1759
# def test_add_node_one_oversized_second_splits_errors(self):
1740
1761
def test__iter_nodes_no_key_filter(self):
1741
node = InternalNode('')
1743
child.set_maximum_size(100)
1744
child.map(None, ("foo",), "bar")
1745
node.add_node("f", child)
1747
child.set_maximum_size(100)
1748
child.map(None, ("bar",), "baz")
1749
node.add_node("b", child)
1762
node = InternalNode(b'')
1764
child.set_maximum_size(100)
1765
child.map(None, (b"foo",), b"bar")
1766
node.add_node(b"f", child)
1768
child.set_maximum_size(100)
1769
child.map(None, (b"bar",), b"baz")
1770
node.add_node(b"b", child)
1751
1772
for child, node_key_filter in node._iter_nodes(None, key_filter=None):
1752
1773
self.assertEqual(None, node_key_filter)
1754
1775
def test__iter_nodes_splits_key_filter(self):
1755
node = InternalNode('')
1757
child.set_maximum_size(100)
1758
child.map(None, ("foo",), "bar")
1759
node.add_node("f", child)
1761
child.set_maximum_size(100)
1762
child.map(None, ("bar",), "baz")
1763
node.add_node("b", child)
1776
node = InternalNode(b'')
1778
child.set_maximum_size(100)
1779
child.map(None, (b"foo",), b"bar")
1780
node.add_node(b"f", child)
1782
child.set_maximum_size(100)
1783
child.map(None, (b"bar",), b"baz")
1784
node.add_node(b"b", child)
1765
1786
# foo and bar both match exactly one leaf node, but 'cat' should not
1766
1787
# match any, and should not be placed in one.
1767
key_filter = (('foo',), ('bar',), ('cat',))
1788
key_filter = ((b'foo',), (b'bar',), (b'cat',))
1768
1789
for child, node_key_filter in node._iter_nodes(None,
1769
1790
key_filter=key_filter):
1770
1791
# each child could only match one key filter, so make sure it was
1794
1815
self.assertEqual(2, len(node_key_filter))
1796
1817
def make_fo_fa_node(self):
1797
node = InternalNode('f')
1799
child.set_maximum_size(100)
1800
child.map(None, ("foo",), "val")
1801
child.map(None, ("fob",), "val")
1802
node.add_node('fo', child)
1804
child.set_maximum_size(100)
1805
child.map(None, ("far",), "val")
1806
child.map(None, ("faz",), "val")
1807
node.add_node("fa", child)
1818
node = InternalNode(b'f')
1820
child.set_maximum_size(100)
1821
child.map(None, (b"foo",), b"val")
1822
child.map(None, (b"fob",), b"val")
1823
node.add_node(b'fo', child)
1825
child.set_maximum_size(100)
1826
child.map(None, (b"far",), b"val")
1827
child.map(None, (b"faz",), b"val")
1828
node.add_node(b"fa", child)
1810
1831
def test__iter_nodes_single_entry(self):
1811
1832
node = self.make_fo_fa_node()
1812
key_filter = [('foo',)]
1833
key_filter = [(b'foo',)]
1813
1834
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1814
1835
self.assertEqual(1, len(nodes))
1815
1836
self.assertEqual(key_filter, nodes[0][1])
1817
1838
def test__iter_nodes_single_entry_misses(self):
1818
1839
node = self.make_fo_fa_node()
1819
key_filter = [('bar',)]
1840
key_filter = [(b'bar',)]
1820
1841
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1821
1842
self.assertEqual(0, len(nodes))
1823
1844
def test__iter_nodes_mixed_key_width(self):
1824
1845
node = self.make_fo_fa_node()
1825
key_filter = [('foo', 'bar'), ('foo',), ('fo',), ('b',)]
1846
key_filter = [(b'foo', b'bar'), (b'foo',), (b'fo',), (b'b',)]
1826
1847
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1827
1848
self.assertEqual(1, len(nodes))
1828
1849
matches = key_filter[:]
1829
matches.remove(('b',))
1850
matches.remove((b'b',))
1830
1851
self.assertEqual(sorted(matches), sorted(nodes[0][1]))
1832
1853
def test__iter_nodes_match_all(self):
1833
1854
node = self.make_fo_fa_node()
1834
key_filter = [('foo', 'bar'), ('foo',), ('fo',), ('f',)]
1855
key_filter = [(b'foo', b'bar'), (b'foo',), (b'fo',), (b'f',)]
1835
1856
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1836
1857
self.assertEqual(2, len(nodes))
1838
1859
def test__iter_nodes_fixed_widths_and_misses(self):
1839
1860
node = self.make_fo_fa_node()
1840
1861
# foo and faa should both match one child, baz should miss
1841
key_filter = [('foo',), ('faa',), ('baz',)]
1862
key_filter = [(b'foo',), (b'faa',), (b'baz',)]
1842
1863
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1843
1864
self.assertEqual(2, len(nodes))
1844
1865
for node, matches in nodes:
1851
1872
def test_iteritems_two_children(self):
1852
1873
node = InternalNode()
1853
1874
leaf1 = LeafNode()
1854
leaf1.map(None, ('foo bar',), 'quux')
1875
leaf1.map(None, (b'foo bar',), b'quux')
1855
1876
leaf2 = LeafNode()
1856
leaf2.map(None, ('strange',), 'beast')
1857
node.add_node("f", leaf1)
1858
node.add_node("s", leaf2)
1859
self.assertEqual([(('foo bar',), 'quux'), (('strange',), 'beast')],
1877
leaf2.map(None, (b'strange',), b'beast')
1878
node.add_node(b"f", leaf1)
1879
node.add_node(b"s", leaf2)
1880
self.assertEqual([((b'foo bar',), b'quux'), ((b'strange',), b'beast')],
1860
1881
sorted(node.iteritems(None)))
1862
1883
def test_iteritems_two_children_partial(self):
1863
1884
node = InternalNode()
1864
1885
leaf1 = LeafNode()
1865
leaf1.map(None, ('foo bar',), 'quux')
1886
leaf1.map(None, (b'foo bar',), b'quux')
1866
1887
leaf2 = LeafNode()
1867
leaf2.map(None, ('strange',), 'beast')
1868
node.add_node("f", leaf1)
1888
leaf2.map(None, (b'strange',), b'beast')
1889
node.add_node(b"f", leaf1)
1869
1890
# This sets up a path that should not be followed - it will error if
1870
1891
# the code tries to.
1871
node._items['f'] = None
1872
node.add_node("s", leaf2)
1873
self.assertEqual([(('strange',), 'beast')],
1874
sorted(node.iteritems(None, [('strange',), ('weird',)])))
1892
node._items[b'f'] = None
1893
node.add_node(b"s", leaf2)
1894
self.assertEqual([((b'strange',), b'beast')],
1895
sorted(node.iteritems(None, [(b'strange',), (b'weird',)])))
1876
1897
def test_iteritems_two_children_with_hash(self):
1877
search_key_func = chk_map.search_key_registry.get('hash-255-way')
1898
search_key_func = chk_map.search_key_registry.get(b'hash-255-way')
1878
1899
node = InternalNode(search_key_func=search_key_func)
1879
1900
leaf1 = LeafNode(search_key_func=search_key_func)
1880
leaf1.map(None, StaticTuple('foo bar',), 'quux')
1901
leaf1.map(None, StaticTuple(b'foo bar',), b'quux')
1881
1902
leaf2 = LeafNode(search_key_func=search_key_func)
1882
leaf2.map(None, StaticTuple('strange',), 'beast')
1883
self.assertEqual('\xbeF\x014', search_key_func(StaticTuple('foo bar',)))
1884
self.assertEqual('\x85\xfa\xf7K', search_key_func(StaticTuple('strange',)))
1885
node.add_node("\xbe", leaf1)
1903
leaf2.map(None, StaticTuple(b'strange',), b'beast')
1904
self.assertEqual(b'\xbeF\x014', search_key_func(StaticTuple(b'foo bar',)))
1905
self.assertEqual(b'\x85\xfa\xf7K', search_key_func(StaticTuple(b'strange',)))
1906
node.add_node(b"\xbe", leaf1)
1886
1907
# This sets up a path that should not be followed - it will error if
1887
1908
# the code tries to.
1888
node._items['\xbe'] = None
1889
node.add_node("\x85", leaf2)
1890
self.assertEqual([(('strange',), 'beast')],
1891
sorted(node.iteritems(None, [StaticTuple('strange',),
1892
StaticTuple('weird',)])))
1909
node._items[b'\xbe'] = None
1910
node.add_node(b"\x85", leaf2)
1911
self.assertEqual([((b'strange',), b'beast')],
1912
sorted(node.iteritems(None, [StaticTuple(b'strange',),
1913
StaticTuple(b'weird',)])))
1894
1915
def test_iteritems_partial_empty(self):
1895
1916
node = InternalNode()
1896
self.assertEqual([], sorted(node.iteritems([('missing',)])))
1917
self.assertEqual([], sorted(node.iteritems([(b'missing',)])))
1898
1919
def test_map_to_new_child_new(self):
1899
chkmap = self._get_map({('k1',):'foo', ('k2',):'bar'}, maximum_size=10)
1920
chkmap = self._get_map({(b'k1',): b'foo', (b'k2',): b'bar'}, maximum_size=10)
1900
1921
chkmap._ensure_root()
1901
1922
node = chkmap._root_node
1902
1923
# Ensure test validity: nothing paged in below the root.
1903
1924
self.assertEqual(2,
1904
1925
len([value for value in node._items.values()
1905
if type(value) is StaticTuple]))
1926
if isinstance(value, StaticTuple)]))
1906
1927
# now, mapping to k3 should add a k3 leaf
1907
prefix, nodes = node.map(None, ('k3',), 'quux')
1908
self.assertEqual("k", prefix)
1909
self.assertEqual([("", node)], nodes)
1928
prefix, nodes = node.map(None, (b'k3',), b'quux')
1929
self.assertEqual(b"k", prefix)
1930
self.assertEqual([(b"", node)], nodes)
1910
1931
# check new child details
1911
child = node._items['k3']
1932
child = node._items[b'k3']
1912
1933
self.assertIsInstance(child, LeafNode)
1913
1934
self.assertEqual(1, len(child))
1914
self.assertEqual({('k3',): 'quux'}, self.to_dict(child, None))
1935
self.assertEqual({(b'k3',): b'quux'}, self.to_dict(child, None))
1915
1936
self.assertEqual(None, child._key)
1916
1937
self.assertEqual(10, child.maximum_size)
1917
1938
self.assertEqual(1, child._key_width)
1918
1939
# Check overall structure:
1919
1940
self.assertEqual(3, len(chkmap))
1920
self.assertEqual({('k1',): 'foo', ('k2',): 'bar', ('k3',): 'quux'},
1941
self.assertEqual({(b'k1',): b'foo', (b'k2',): b'bar', (b'k3',): b'quux'},
1921
1942
self.to_dict(chkmap))
1922
1943
# serialising should only serialise the new data - k3 and the internal
2183
2204
c_map = self.make_one_deep_map(chk_map._search_key_plain)
2184
2205
key1 = c_map.key()
2185
2206
c_map._dump_tree() # load everything
2186
key1_a = c_map._root_node._items['a'].key()
2187
key1_c = c_map._root_node._items['c'].key()
2188
c_map.map(('abb',), 'new abb content')
2207
key1_a = c_map._root_node._items[b'a'].key()
2208
key1_c = c_map._root_node._items[b'c'].key()
2209
c_map.map((b'abb',), b'new abb content')
2189
2210
key2 = c_map._save()
2190
key2_a = c_map._root_node._items['a'].key()
2191
key2_c = c_map._root_node._items['c'].key()
2211
key2_a = c_map._root_node._items[b'a'].key()
2212
key2_c = c_map._root_node._items[b'c'].key()
2192
2213
c_map = chk_map.CHKMap(self.get_chk_bytes(), key1,
2193
2214
chk_map._search_key_plain)
2194
c_map.map(('ccc',), 'new ccc content')
2215
c_map.map((b'ccc',), b'new ccc content')
2195
2216
key3 = c_map._save()
2196
key3_a = c_map._root_node._items['a'].key()
2197
key3_c = c_map._root_node._items['c'].key()
2217
key3_a = c_map._root_node._items[b'a'].key()
2218
key3_c = c_map._root_node._items[b'c'].key()
2198
2219
diff = self.get_difference([key2, key3], [key1],
2199
2220
chk_map._search_key_plain)
2200
2221
root_results = [record.key for record in diff._read_all_roots()]
2201
2222
self.assertEqual(sorted([key2, key3]), sorted(root_results))
2202
2223
# We should have queued up key2_a, and key3_c, but not key2_c or key3_c
2203
self.assertEqual([key2_a, key3_c], diff._new_queue)
2224
self.assertEqual({key2_a, key3_c}, set(diff._new_queue))
2204
2225
self.assertEqual([], diff._new_item_queue)
2205
2226
# And we should have queued up both a and c for the old set
2206
self.assertEqual([key1_a, key1_c], diff._old_queue)
2227
self.assertEqual({key1_a, key1_c}, set(diff._old_queue))
2208
2229
def test__read_all_roots_different_depths(self):
2209
2230
c_map = self.make_two_deep_map(chk_map._search_key_plain)
2210
2231
c_map._dump_tree() # load everything
2211
2232
key1 = c_map.key()
2212
key1_a = c_map._root_node._items['a'].key()
2213
key1_c = c_map._root_node._items['c'].key()
2214
key1_d = c_map._root_node._items['d'].key()
2233
key1_a = c_map._root_node._items[b'a'].key()
2234
key1_c = c_map._root_node._items[b'c'].key()
2235
key1_d = c_map._root_node._items[b'd'].key()
2216
2237
c_map2 = self.make_one_deep_two_prefix_map(chk_map._search_key_plain)
2217
2238
c_map2._dump_tree()
2218
2239
key2 = c_map2.key()
2219
key2_aa = c_map2._root_node._items['aa'].key()
2220
key2_ad = c_map2._root_node._items['ad'].key()
2240
key2_aa = c_map2._root_node._items[b'aa'].key()
2241
key2_ad = c_map2._root_node._items[b'ad'].key()
2222
2243
diff = self.get_difference([key2], [key1], chk_map._search_key_plain)
2223
2244
root_results = [record.key for record in diff._read_all_roots()]