refactor RingBuffer
This commit is contained in:
@@ -1,2 +1,4 @@
|
||||
node_modules
|
||||
dist
|
||||
tsconfig.tsbuildinfo
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
+20
-11
@@ -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) {
|
||||
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");
|
||||
}
|
||||
|
||||
this.size = size;
|
||||
this.mask = size - 1;
|
||||
this.cursor = 0;
|
||||
this.buffer = [];
|
||||
|
||||
const buffer = new Array<T>(size);
|
||||
for (let i = 0; i < size; i++) {
|
||||
this.buffer.push(structuredClone(blueprint));
|
||||
}
|
||||
buffer[i] = create();
|
||||
}
|
||||
|
||||
next(): T {
|
||||
return this.buffer[this.cursor++ & this.mask];
|
||||
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
Reference in New Issue
Block a user