Hone logo
Hone
Problems

Go Bump Allocator Implementation

This challenge requires you to implement a simple memory allocator in Go known as a "bump allocator." A bump allocator is a very basic and efficient memory allocation strategy where memory is allocated by simply advancing a pointer. This makes allocation extremely fast but deallocation can be more complex, often requiring a full reset of the allocator. This is useful in scenarios where temporary allocations are frequent and garbage collection overhead needs to be minimized.

Problem Description

Your task is to create a BumpAllocator struct in Go that manages a contiguous block of memory. The allocator should support two primary operations:

  1. Alloc(size int): Allocate a block of memory of the given size bytes. It should return a pointer to the allocated memory and an error if allocation fails (e.g., not enough memory).
  2. Reset(): Deallocate all memory currently managed by the allocator, effectively resetting it to its initial state.

Key Requirements:

  • The BumpAllocator should internally manage a byte slice representing the memory pool.
  • When Alloc is called, it should return a pointer to a contiguous chunk of memory within the pool.
  • Alloc should advance an internal pointer (or index) to track the next available allocation point.
  • The allocator should prevent allocations that would exceed the total capacity of its memory pool.
  • Reset should make all previously allocated memory available again.

Expected Behavior:

  • Consecutive calls to Alloc with increasing sizes should successfully allocate memory, returning pointers to sequential blocks.
  • An attempt to allocate more memory than what remains in the pool should return an error.
  • Calling Reset should allow for new allocations to occur from the beginning of the memory pool again, as if it were newly initialized.

Edge Cases to Consider:

  • Allocating zero bytes: Should ideally be handled gracefully, perhaps by returning a nil pointer or an error depending on interpretation. For this challenge, returning an error is preferred.
  • Allocating exactly the remaining capacity.
  • Calling Reset on an empty allocator.
  • Concurrent access (though not strictly required for this challenge, consider the implications).

Examples

Example 1:

Allocator initialized with 100 bytes capacity.

Alloc(10 bytes) -> returns pointer to first 10 bytes, no error.
Alloc(20 bytes) -> returns pointer to next 20 bytes, no error.
Alloc(70 bytes) -> returns pointer to next 70 bytes, no error.

State after allocations:
Memory pool: [10 bytes][20 bytes][70 bytes]
Used: 100 bytes
Remaining: 0 bytes

Example 2:

Allocator initialized with 100 bytes capacity.

Alloc(50 bytes) -> returns pointer to first 50 bytes, no error.
Alloc(60 bytes) -> returns an error (e.g., "out of memory").

State after failed allocation:
Memory pool: [50 bytes][...remaining 50 bytes...]
Used: 50 bytes
Remaining: 50 bytes

Example 3:

Allocator initialized with 100 bytes capacity.

Alloc(50 bytes) -> returns pointer to first 50 bytes, no error.
Reset() -> all memory is deallocated.
Alloc(30 bytes) -> returns pointer to first 30 bytes, no error.
Alloc(70 bytes) -> returns pointer to next 70 bytes, no error.

State after reset and new allocations:
Memory pool: [30 bytes][70 bytes]
Used: 100 bytes
Remaining: 0 bytes

Constraints

  • The BumpAllocator must be initialized with a specific capacity (an int representing bytes).
  • The size parameter for Alloc must be a non-negative int.
  • The total memory managed by the allocator will not exceed 1MB for typical test cases.
  • Alloc operations should ideally be O(1) in time complexity.

Notes

  • Consider using make([]byte, capacity) to create the underlying memory pool.
  • You'll need to maintain an offset or pointer to track the current allocation position within the byte slice.
  • When returning a pointer from Alloc, you can return a []byte slice or a pointer to the first byte of the allocated segment. For simplicity, returning a []byte slice is acceptable.
  • Think about how to handle the error condition for insufficient memory. Go's built-in errors package is suitable.
  • For this challenge, you do not need to implement deallocation of individual blocks, only the Reset functionality.
Loading editor...
go