Rev 4414: Add a shortcut for the case when we are searching for a single full-width key. in http://bazaar.launchpad.net/~jameinel/bzr/1.16-chkmap-updates
John Arbash Meinel
john at arbash-meinel.com
Fri Jun 5 16:02:01 BST 2009
At http://bazaar.launchpad.net/~jameinel/bzr/1.16-chkmap-updates
------------------------------------------------------------
revno: 4414
revision-id: john at arbash-meinel.com-20090605150139-osvqaqcv0bk55cuc
parent: pqm at pqm.ubuntu.com-20090605081039-abvojdsxjbg5i4ff
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 1.16-chkmap-updates
timestamp: Fri 2009-06-05 10:01:39 -0500
message:
Add a shortcut for the case when we are searching for a single full-width key.
This saves approx 14.0s => 12.5s for 'initial commit' of a MySQL tree.
Mostly it is about improving 'InternalNode.map()' performance for a very large 'apply_delta'.
Needs further testing to ensure it handles edge cases.
Also, we could probably tweak the generic code path a bit as well.
We could probably split the lookups into full-width matches versus sub-matches,
and then combine keys based on the search prefixes being identical, etc.
-------------- next part --------------
=== modified file 'bzrlib/chk_map.py'
--- a/bzrlib/chk_map.py 2009-05-13 21:59:57 +0000
+++ b/bzrlib/chk_map.py 2009-06-05 15:01:39 +0000
@@ -955,13 +955,40 @@
# prefix is the key in self._items to use, key_filter is the key_filter
# entries that would match this node
keys = {}
+ shortcut = False
if key_filter is None:
+ # yielding all nodes, yield whatever we have, and queue up a read
+ # for whatever we are missing
+ shortcut = True
for prefix, node in self._items.iteritems():
- if type(node) == tuple:
+ if type(node) is tuple:
keys[node] = (prefix, None)
else:
yield node, None
- else:
+ elif len(key_filter) == 1:
+ # We are looking for a single item
+ # Sometimes it is a set, sometimes it is a list
+ key = list(key_filter)[0]
+ search_key = self._search_prefix_filter(key)
+ if len(search_key) == self._node_width:
+ # This item will match exactly, so just do a dict lookup, and
+ # see what we can return
+ shortcut = True
+ try:
+ node = self._items[search_key]
+ except KeyError:
+ # A given key can only match 1 child node, if it isn't
+ # there, then we can just return nothing
+ return
+ else:
+ if type(node) is tuple:
+ keys[node] = (search_key, [key])
+ else:
+ # This is loaded, and the only thing that can match,
+ # return
+ yield node, [key]
+ return
+ if not shortcut:
# XXX defaultdict ?
prefix_to_keys = {}
length_filters = {}
@@ -971,6 +998,8 @@
len(search_key), set())
length_filter.add(search_key)
prefix_to_keys.setdefault(search_key, []).append(key)
+ if len(length_filters) > 1:
+ import pdb; pdb.set_trace()
length_filters = length_filters.items()
for prefix, node in self._items.iteritems():
node_key_filter = []
More information about the bazaar-commits
mailing list