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

feat: Implement allocator trait with example implementations #66

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

pzittlau
Copy link
Contributor

@pzittlau pzittlau commented Jan 15, 2025

This pull request introduces the ability to select different memory allocation strategies for segments within the database. It adds several allocator implementations and a few benchmarks to compare their performance.

Motivation:

  • Performance Optimization: By providing different allocation strategies, users can choose the allocator that best suits their workload, potentially leading to improved performance.
  • Flexibility: The pluggable architecture allows for easy addition of new allocation strategies in the future.
  • Benchmarking and Analysis: The included benchmark suite provides a way to objectively compare the performance characteristics of different allocators.

Key changes:

  • Pluggable Allocators:

    • Implemented a generic Allocator trait to define the interface for segment allocators.
    • Added the following allocator implementations:
      • FirstFit: Allocates the first available block large enough.
      • NextFit: Starts searching for free space from the position of the last allocation.
      • BestFitSimple: Allocates the smallest available block that fits the request.
      • WorstFitSimple: Allocates the largest available block.
      • SegmentAllocator: The original allocator, now available as one of the choices.
    • Introduced an AllocatorType enum to configure which allocator to use.
    • Updated the Handler to store Box<dyn Allocator> instances, allowing for dynamic selection of allocators.
    • Added an allocator field to DatabaseConfiguration to specify the desired allocation strategy.
  • Benchmarks:

    • Added a new benchmark suite in benches/allocator.rs to evaluate the performance of different allocators.
    • The benchmark uses both uniform and Zipfian distributions for allocation sizes to simulate different workload patterns.
    • It measures the performance of allocation and deallocation operations.
    • Added the zipf crate as a dependency for generating Zipfian distributions.
  • Refactoring:

    • Refactored the original SegmentAllocator implementation into its own file and made it one of the selectable options.
    • Moved all allocator-related code into the src/allocator/ directory.

Usage:

To select a specific allocator, modify the allocator field in your DatabaseConfiguration:

let config = DatabaseConfiguration {
    // ... other configurations
    allocator: AllocatorType::BestFitSimple,
    // ...
};

Proposal

Lastly I propose making the NextFit allocator the default one for now. As per the provided benchmarks it's way faster (~100x on my machine) than the original SegmentAllocator.

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