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:
Alloc(size int): Allocate a block of memory of the givensizebytes. It should return a pointer to the allocated memory and an error if allocation fails (e.g., not enough memory).Reset(): Deallocate all memory currently managed by the allocator, effectively resetting it to its initial state.
Key Requirements:
- The
BumpAllocatorshould internally manage a byte slice representing the memory pool. - When
Allocis called, it should return a pointer to a contiguous chunk of memory within the pool. Allocshould 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.
Resetshould make all previously allocated memory available again.
Expected Behavior:
- Consecutive calls to
Allocwith 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
Resetshould 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
Reseton 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
BumpAllocatormust be initialized with a specific capacity (anintrepresenting bytes). - The
sizeparameter forAllocmust be a non-negativeint. - The total memory managed by the allocator will not exceed 1MB for typical test cases.
Allocoperations 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[]byteslice or a pointer to the first byte of the allocated segment. For simplicity, returning a[]byteslice is acceptable. - Think about how to handle the error condition for insufficient memory. Go's built-in
errorspackage is suitable. - For this challenge, you do not need to implement deallocation of individual blocks, only the
Resetfunctionality.