refactor RingBuffer

This commit is contained in:
Schluffe
2026-08-24 22:26:08 +02:00
parent e041b5fdfc
commit 13d462fc43
4 changed files with 47 additions and 17 deletions
+2
View File
@@ -1,2 +1,4 @@
node_modules
dist
tsconfig.tsbuildinfo
+20
View File
@@ -0,0 +1,20 @@
import { expect, test } from "vitest";
import { claim, createRingBuffer } from "./RingBuffer.ts";
test("RingBuffer", () => {
expect(() => createRingBuffer(3, () => ({}))).toThrow(
"size must be a power of two",
);
const pooled = createRingBuffer(4, () => ({}));
expect(pooled.size).toBe(4);
expect(pooled.cursor).toBe(0);
expect(pooled.buffer.length).toBe(4);
for (let i = 0; i < 8; i++) {
expect(claim(pooled)).toBe(pooled.buffer[i % 4]);
}
expect(pooled.cursor).toBe(0);
});
+25 -16
View File
@@ -1,25 +1,34 @@
export default class RingBuffer<T> {
export type Pooled<T> = {
size: number;
mask: number;
cursor: number;
buffer: Array<T>;
};
constructor(size: number, blueprint: T) {
if ((size & (size - 1)) !== 0) {
throw new Error("size must be a power of two");
}
this.size = size;
this.mask = size - 1;
this.cursor = 0;
this.buffer = [];
for (let i = 0; i < size; i++) {
this.buffer.push(structuredClone(blueprint));
}
export function createRingBuffer<T extends object>(
size: number,
create: () => T,
): Pooled<T> {
if ((size & (size - 1)) !== 0) {
throw new Error("size must be a power of two");
}
next(): T {
return this.buffer[this.cursor++ & this.mask];
const buffer = new Array<T>(size);
for (let i = 0; i < size; i++) {
buffer[i] = create();
}
return {
size,
mask: size - 1,
cursor: 0,
buffer,
};
}
export function claim<T>(pooled: Pooled<T>): T {
const slot = pooled.buffer[pooled.cursor];
pooled.cursor = (pooled.cursor + 1) & pooled.mask;
return slot;
}
File diff suppressed because one or more lines are too long