Rev 3772: Add a --raw output for dump-btree. in http://bzr.arbash-meinel.com/branches/bzr/1.8-dev/dump_btree
John Arbash Meinel
john at arbash-meinel.com
Wed Oct 8 22:52:04 BST 2008
At http://bzr.arbash-meinel.com/branches/bzr/1.8-dev/dump_btree
------------------------------------------------------------
revno: 3772
revision-id: john at arbash-meinel.com-20081008215137-wu18nhhorncyon50
parent: john at arbash-meinel.com-20081008204023-z1u32sjby509wl12
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: dump_btree
timestamp: Wed 2008-10-08 16:51:37 -0500
message:
Add a --raw output for dump-btree.
This does the minimum it can, so that we can dump out the
raw bytes in a meaningful manner.
-------------- next part --------------
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2008-10-08 20:40:23 +0000
+++ b/bzrlib/builtins.py 2008-10-08 21:51:37 +0000
@@ -29,6 +29,7 @@
from bzrlib import (
bugtracker,
bundle,
+ btree_index,
bzrdir,
delta,
config,
@@ -269,24 +270,70 @@
# rather than only going through iter_all_entries. However, this is
# good enough for a start
hidden = True
+ encoding_type = 'exact'
takes_args = ['path']
-
- def run(self, path):
- from bzrlib import btree_index
-
+ takes_options = [Option('raw', help='Write the uncompressed bytes out,'
+ ' rather than the parsed tuples'),
+ ]
+
+ def run(self, path, raw=False):
dirname, basename = osutils.split(path)
t = transport.get_transport(dirname)
+ if raw:
+ self._dump_raw_bytes(t, basename)
+ else:
+ self._dump_entries(t, basename)
+
+ def _get_index_and_bytes(self, trans, basename):
+ """Create a BTreeGraphIndex and raw bytes."""
+ bt = btree_index.BTreeGraphIndex(trans, basename, None)
+ bytes = trans.get_bytes(basename)
+ bt._file = cStringIO.StringIO(bytes)
+ bt._size = len(bytes)
+ return bt, bytes
+
+ def _dump_raw_bytes(self, trans, basename):
+ import zlib
+
+ # We need to parse at least the root node.
+ # This is because the first page of every row starts with an
+ # uncompressed header.
+ bt, bytes = self._get_index_and_bytes(trans, basename)
+ root_node = bt._get_root_node()
+ for row_idx, row_start in enumerate(bt._row_offsets[:-1]):
+ if row_idx == 0:
+ self.outf.write('Root node:\n')
+ elif row_idx < len(bt._row_lengths):
+ self.outf.write('\nInternal Row %d:\n' % (row_idx,))
+ else:
+ self.outf.write('\nLeaf Row %d:\n' % (row_idx,))
+ # Should we do something to ensure all pages are 'back-to-back'?
+ # And we aren't skipping data in the middle?
+ for page_idx in xrange(0, bt._row_lengths[row_idx]):
+ start_idx = bt._row_offsets[row_idx] + page_idx
+ start_offset = start_idx * btree_index._PAGE_SIZE
+ finish_offset = min(start_offset + btree_index._PAGE_SIZE,
+ len(bytes))
+ page_bytes = bytes[start_offset:finish_offset]
+ if row_idx == 0 and page_idx == 0:
+ header_end, data = bt._parse_header_from_bytes(page_bytes)
+ self.outf.write(page_bytes[:header_end])
+ page_bytes = data
+ self.outf.write('\nPage %d (row: %d, offset: %d)\n'
+ % (start_idx, row_idx, page_idx))
+ decomp_bytes = zlib.decompress(page_bytes)
+ self.outf.write(decomp_bytes)
+ self.outf.write('\n')
+
+ def _dump_entries(self, trans, basename):
try:
- st = t.stat(basename)
+ st = trans.stat(basename)
except errors.TransportNotPossible:
# We can't stat, so we'll fake it because we have to do the 'get()'
# anyway.
- bt = btree_index.BTreeGraphIndex(t, basename, None)
- bytes = t.get_bytes(basename)
- bt._file = cStringIO.StringIO(bytes)
- bt._size = len(bytes)
+ bt, _ = self._get_index_and_bytes(trans, basename)
else:
- bt = btree_index.BTreeGraphIndex(t, basename, st.st_size)
+ bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
for node in bt.iter_all_entries():
# Node is made up of:
# (index, key, value, [references])
=== modified file 'bzrlib/tests/blackbox/test_dump_btree.py'
--- a/bzrlib/tests/blackbox/test_dump_btree.py 2008-10-08 20:40:23 +0000
+++ b/bzrlib/tests/blackbox/test_dump_btree.py 2008-10-08 21:51:37 +0000
@@ -59,3 +59,22 @@
"(('test', 'key2'), 'value2', ((('ref', 'entry2'),),))\n"
"(('test2', 'key3'), 'value3', ((('ref', 'entry3'),),))\n",
out)
+
+ def test_dump_btree_raw_smoke(self):
+ self.create_sample_btree_index()
+ out, err = self.run_bzr('dump-btree test.btree --raw')
+ self.assertEqualDiff(
+ 'Root node:\n'
+ 'B+Tree Graph Index 2\n'
+ 'node_ref_lists=1\n'
+ 'key_elements=2\n'
+ 'len=3\n'
+ 'row_lengths=1\n'
+ '\n'
+ 'Page 0 (row: 0, offset: 0)\n'
+ 'type=leaf\n'
+ 'test\0key1\0ref\0entry\0value\n'
+ 'test\0key2\0ref\0entry2\0value2\n'
+ 'test2\0key3\0ref\0entry3\0value3\n'
+ '\n',
+ out)
More information about the bazaar-commits
mailing list