Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blockstore: Allocate rocksdb keys more efficiently #3603

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

steviez
Copy link

@steviez steviez commented Nov 13, 2024

Problem

The Blockstore stores different data types in different columns. More so, the key type might vary column to column. For example, the key type for a SlotMeta is just a Slot as shown here:

/// Returns the SlotMeta of the specified slot.
pub fn meta(&self, slot: Slot) -> Result<Option<SlotMeta>> {
self.meta_cf.get(slot)
}

Under the hood, rocksdb just wants a &[u8] for the key. So, we have a function for turning the type (Slot from our example) into a Vec<u8>:

fn key(index: Self::Index) -> Vec<u8>;

Thus, we'll perform an extra allocation to transform the key into a byte array for every get/put operation.

Summary of Changes

  • Refactor all key conversion to occur in LedgerColumn
  • Add a KEY_LEN field to Column trait
  • Replace instances of C::key() (which allocates a Vec) to the following form (which will get allocated on the stack since K is known at compile time):
        let mut key_buffer = [0u8; K];
        C::serialize_key(&mut key_buffer, key);
  • Add MultiGetBytes helper to only perform one Vec allocation for multi_get() calls, instead of one Vec per key + Vec to hold all keys

Performance

This item isn't the worst offender in the flamegraphs. But after adding in a temporary counter, I see that tip-of-master is calling C::key() ~18.5k times per second on mnb. Each of those calls is allocating a Vec, so shaving all those heap allocations is a win

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant