• F
    Btrfs: more efficient push_leaf_right · 2ef1fed2
    Filipe David Borba Manana 提交于
    Currently when finding the leaf to insert a key into a btree, if the
    leaf doesn't have enough space to store the item we attempt to move
    off some items from our leaf to its right neighbor leaf, and if this
    fails to create enough free space in our leaf, we try to move off more
    items to the left neighbor leaf as well.
    
    When trying to move off items to the right neighbor leaf, if it has
    enough room to store the new key but not not enough room to move off
    at least one item from our target leaf, __push_leaf_right returns 1 and
    we have to attempt to move items to the left neighbor (push_leaf_left
    function) without touching the right neighbor leaf.
    For the case where the right leaf has enough room to store at least 1
    item from our leaf, we end up modifying (and dirtying) both our leaf
    and the right leaf. This is non-optimal for the case where the new key
    is greater than any key in our target leaf because it can be inserted at
    slot 0 of the right neighbor leaf and we don't need to touch our leaf
    at all nor to attempt to move off items to the left neighbor leaf.
    
    Therefore this change just selects the right neighbor leaf as our new
    target leaf if it has enough room for the new key without modifying our
    initial target leaf - we do this only if the new key is higher than any
    key in the initial target leaf.
    
    While running the following test, push_leaf_right was called by split_leaf
    4802 times. Out of those 4802 calls, for 2571 calls (53.5%) we hit this
    special case (right leaf has enough room and new key is higher than any key
    in the initial target leaf).
    
    Test:
    
      sysbench --test=fileio --file-num=512 --file-total-size=5G \
        --file-test-mode=[seqwr|rndwr] --num-threads=512 --file-block-size=8192 \
        --max-requests=100000 --file-io-mode=sync [prepare|run]
    
    Results:
    
    sequential writes
    
    Throughput before this change: 65.71Mb/sec (average of 10 runs)
    Throughput after this change:  66.58Mb/sec (average of 10 runs)
    
    random writes
    
    Throughput before this change: 10.75Mb/sec (average of 10 runs)
    Throughput after this change:  11.56Mb/sec (average of 10 runs)
    Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
    Reviewed-by: NLiu Bo <bo.li.liu@oracle.com>
    Signed-off-by: NJosef Bacik <jbacik@fb.com>
    Signed-off-by: NChris Mason <clm@fb.com>
    2ef1fed2
ctree.c 148.8 KB