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