197
197
self._ensure_root()
198
198
res = self._dump_tree_node(self._root_node, prefix='', indent='',
199
199
include_keys=include_keys)
200
res.append('') # Give a trailing '\n'
201
return '\n'.join(res)
200
res.append(b'') # Give a trailing '\n'
201
return b'\n'.join(res)
203
203
def _dump_tree_node(self, node, prefix, indent, include_keys=True):
204
204
"""For this node and all children, generate a string representation."""
209
209
node_key = node.key()
210
210
if node_key is not None:
211
key_str = ' %s' % (node_key[0],)
211
key_str = b' %s' % (node_key[0],)
214
result.append('%s%r %s%s' % (indent, prefix, node.__class__.__name__,
214
result.append(b'%s%r %s%s' % (indent, prefix, node.__class__.__name__,
216
216
if isinstance(node, InternalNode):
217
217
# Trigger all child nodes to get loaded
218
218
list(node._iter_nodes(self._store))
223
223
for key, value in sorted(viewitems(node._items)):
224
224
# Don't use prefix nor indent here to line up when used in
225
225
# tests in conjunction with assertEqualDiff
226
result.append(' %r %r' % (tuple(key), value))
226
result.append(b' %r %r' % (tuple(key), value))
786
786
# TODO: Should probably be done without actually joining the key, but
787
787
# then that can be done via the C extension
788
788
return (len(self._serialise_key(key)) + 1
789
+ len(str(value.count('\n'))) + 1
789
+ len(str(value.count(b'\n'))) + 1
790
790
+ len(value) + 1)
792
792
def _search_key(self, key):
853
853
# may get a '\00' node anywhere, but won't have keys of
854
854
# different lengths.
855
855
if len(prefix) < split_at:
856
prefix += '\x00'*(split_at - len(prefix))
856
prefix += b'\x00'*(split_at - len(prefix))
857
857
if prefix not in result:
858
858
node = LeafNode(search_key_func=self._search_key_func)
859
859
node.set_maximum_size(self._maximum_size)
889
889
raise AssertionError('%r must be known' % self._search_prefix)
890
890
return self._search_prefix, [("", self)]
892
_serialise_key = '\x00'.join
892
_serialise_key = b'\x00'.join
894
894
def serialise(self, store):
895
895
"""Serialise the LeafNode to store.
897
897
:param store: A VersionedFiles honouring the CHK extensions.
898
898
:return: An iterable of the keys inserted by this operation.
900
lines = ["chkleaf:\n"]
901
lines.append("%d\n" % self._maximum_size)
902
lines.append("%d\n" % self._key_width)
903
lines.append("%d\n" % self._len)
900
lines = [b"chkleaf:\n"]
901
lines.append(b"%d\n" % self._maximum_size)
902
lines.append(b"%d\n" % self._key_width)
903
lines.append(b"%d\n" % self._len)
904
904
if self._common_serialised_prefix is None:
906
906
if len(self._items) != 0:
907
907
raise AssertionError('If _common_serialised_prefix is None'
908
908
' we should have no items')
910
lines.append('%s\n' % (self._common_serialised_prefix,))
910
lines.append(b'%s\n' % (self._common_serialised_prefix,))
911
911
prefix_len = len(self._common_serialised_prefix)
912
912
for key, value in sorted(viewitems(self._items)):
913
913
# Always add a final newline
914
value_lines = osutils.chunks_to_lines([value + '\n'])
915
serialized = "%s\x00%s\n" % (self._serialise_key(key),
914
value_lines = osutils.chunks_to_lines([value + b'\n'])
915
serialized = b"%s\x00%d\n" % (self._serialise_key(key),
916
916
len(value_lines))
917
917
if not serialized.startswith(self._common_serialised_prefix):
918
918
raise AssertionError('We thought the common prefix was %r'
921
921
lines.append(serialized[prefix_len:])
922
922
lines.extend(value_lines)
923
923
sha1, _, _ = store.add_lines((None,), (), lines)
924
self._key = StaticTuple("sha1:" + sha1,).intern()
925
bytes = ''.join(lines)
926
if len(bytes) != self._current_size():
924
self._key = StaticTuple(b"sha1:" + sha1,).intern()
925
data = b''.join(lines)
926
if len(data) != self._current_size():
927
927
raise AssertionError('Invalid _current_size')
928
_get_cache()[self._key] = bytes
928
_get_cache()[self._key] = data
929
929
return [self._key]
1305
1305
for key in node.serialise(store):
1307
lines = ["chknode:\n"]
1308
lines.append("%d\n" % self._maximum_size)
1309
lines.append("%d\n" % self._key_width)
1310
lines.append("%d\n" % self._len)
1307
lines = [b"chknode:\n"]
1308
lines.append(b"%d\n" % self._maximum_size)
1309
lines.append(b"%d\n" % self._key_width)
1310
lines.append(b"%d\n" % self._len)
1311
1311
if self._search_prefix is None:
1312
1312
raise AssertionError("_search_prefix should not be None")
1313
lines.append('%s\n' % (self._search_prefix,))
1313
lines.append(b'%s\n' % (self._search_prefix,))
1314
1314
prefix_len = len(self._search_prefix)
1315
1315
for prefix, node in sorted(viewitems(self._items)):
1316
1316
if isinstance(node, StaticTuple):
1319
1319
key = node._key[0]
1320
serialised = "%s\x00%s\n" % (prefix, key)
1320
serialised = b"%s\x00%s\n" % (prefix, key)
1321
1321
if not serialised.startswith(self._search_prefix):
1322
1322
raise AssertionError("prefixes mismatch: %s must start with %s"
1323
1323
% (serialised, self._search_prefix))
1324
1324
lines.append(serialised[prefix_len:])
1325
1325
sha1, _, _ = store.add_lines((None,), (), lines)
1326
self._key = StaticTuple("sha1:" + sha1,).intern()
1327
_get_cache()[self._key] = ''.join(lines)
1326
self._key = StaticTuple(b"sha1:" + sha1,).intern()
1327
_get_cache()[self._key] = b''.join(lines)
1328
1328
yield self._key
1330
1330
def _search_key(self, key):
1331
1331
"""Return the serialised key for key in this node."""
1332
1332
# search keys are fixed width. All will be self._node_width wide, so we
1333
1333
# pad as necessary.
1334
return (self._search_key_func(key) + '\x00'*self._node_width)[:self._node_width]
1334
return (self._search_key_func(key) + b'\x00'*self._node_width)[:self._node_width]
1336
1336
def _search_prefix_filter(self, key):
1337
1337
"""Serialise key for use as a prefix filter in iteritems."""
1450
1450
return new_leaf
1453
def _deserialise(bytes, key, search_key_func):
1453
def _deserialise(data, key, search_key_func):
1454
1454
"""Helper for repositorydetails - convert bytes to a node."""
1455
if bytes.startswith("chkleaf:\n"):
1456
node = LeafNode.deserialise(bytes, key, search_key_func=search_key_func)
1457
elif bytes.startswith("chknode:\n"):
1458
node = InternalNode.deserialise(bytes, key,
1455
if data.startswith(b"chkleaf:\n"):
1456
node = LeafNode.deserialise(data, key, search_key_func=search_key_func)
1457
elif data.startswith(b"chknode:\n"):
1458
node = InternalNode.deserialise(data, key,
1459
1459
search_key_func=search_key_func)
1461
1461
raise AssertionError("Unknown node type.")