https://github.com/raezil/atomicarena
https://github.com/raezil/atomicarena
golang library memoryarena
Last synced: 5 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/raezil/atomicarena
- Owner: Raezil
- Created: 2025-04-23T19:13:44.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-04-23T20:01:50.000Z (6 months ago)
- Last Synced: 2025-04-23T20:27:03.049Z (6 months ago)
- Topics: golang, library, memoryarena
- Language: Go
- Homepage:
- Size: 15.6 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# AtomicArena
[](https://goreportcard.com/report/github.com/Raezil/atomicarena)
`AtomicArena` is a lock-free, thread-safe generic arena allocator for Go. It provides a fixed-capacity container of atomic pointers, allowing you to allocate objects of any type **T** up to a maximum element count without locks or garbage collection overhead.
## Features
- **Generic**: Works with any Go type `T` whose size is known at compile time.
- **Lock-Free**: Uses atomic operations (`atomic.Uintptr`, `atomic.Pointer[T]`) for high concurrency without mutexes.
- **Fixed Capacity**: Pre-allocates a buffer for `maxElems` objects to avoid slice growth and dynamic allocations after initialization.
- **Resettable**: Clear the arena in constant time, reusing all slots immediately.
- **Bulk Allocation**: Easily append multiple values at once using `AppendSlice`.
## Installation
```bash
go get github.com/Raezil/atomicarena
```
## Usage
```go
package main
import (
"fmt"
"github.com/Raezil/atomicarena"
)
func main() {
// Create an arena for 100 integers
arena := atomicarena.NewAtomicArena[int](100)
// Allocate a single value
ptr, err := arena.Alloc(42)
if err != nil {
panic(err)
}
fmt.Println("Allocated:", *ptr)
// Bulk allocate a slice of values
inputs := []int{1, 2, 3, 4, 5}
ptrs, err := arena.AppendSlice(inputs)
if err != nil {
panic(err)
}
for i, p := range ptrs {
fmt.Printf("Value %d allocated: %d\n", i, *p)
}
// Reset to reuse all slots
arena.Reset()
}
```
## API
### `NewAtomicArena[T any](maxElems uintptr) *AtomicArena[T]`
Creates a new arena capable of holding up to `maxElems` values of type `T`.
### `(a *AtomicArena[T]) Alloc(obj T) (*T, error)`
Atomically reserves a slot and stores `obj`. Returns an error if capacity is exhausted.
### `(a *AtomicArena[T]) AppendSlice(objs []T) ([]*T, error)`
Atomically reserves slots for each element in `objs`, storing them in the arena. Returns a slice of pointers to the stored values in the same order. If there is insufficient capacity to store all elements, no values are stored and an error is returned.
### `(a *AtomicArena[T]) Reset(release bool)`
Clears all allocations, setting the element count back to zero.
If release is true, Reset additionally zeroes out the raw storage (memset-style) before resetting the count and pointers.
## Example: Structs
```go
// Define a struct
type Point struct { X, Y float64 }
// Arena for 10 points
a := atomicarena.NewAtomicArena[Point](10)
// Allocate two points
p1, _ := a.Alloc(Point{1, 2})
p2, _ := a.Alloc(Point{3, 4})
fmt.Println(*p1, *p2)
```
## Testing
A comprehensive test suite covers:
- Allocating basic types (`int`, `string`, etc.) and structs
- Bulk allocations via `AppendSlice`
- Error on exceeding `maxElems`
- `Reset()` correctness
- High-concurrency allocations (data-race free)
Run tests with:
```bash
go test --bench=. --cover --race
```

