source dump of claude code
at main 84 lines 1.9 kB view raw
1/** 2 * A fixed-size circular buffer that automatically evicts the oldest items 3 * when the buffer is full. Useful for maintaining a rolling window of data. 4 */ 5export class CircularBuffer<T> { 6 private buffer: T[] 7 private head = 0 8 private size = 0 9 10 constructor(private capacity: number) { 11 this.buffer = new Array(capacity) 12 } 13 14 /** 15 * Add an item to the buffer. If the buffer is full, 16 * the oldest item will be evicted. 17 */ 18 add(item: T): void { 19 this.buffer[this.head] = item 20 this.head = (this.head + 1) % this.capacity 21 if (this.size < this.capacity) { 22 this.size++ 23 } 24 } 25 26 /** 27 * Add multiple items to the buffer at once. 28 */ 29 addAll(items: T[]): void { 30 for (const item of items) { 31 this.add(item) 32 } 33 } 34 35 /** 36 * Get the most recent N items from the buffer. 37 * Returns fewer items if the buffer contains less than N items. 38 */ 39 getRecent(count: number): T[] { 40 const result: T[] = [] 41 const start = this.size < this.capacity ? 0 : this.head 42 const available = Math.min(count, this.size) 43 44 for (let i = 0; i < available; i++) { 45 const index = (start + this.size - available + i) % this.capacity 46 result.push(this.buffer[index]!) 47 } 48 49 return result 50 } 51 52 /** 53 * Get all items currently in the buffer, in order from oldest to newest. 54 */ 55 toArray(): T[] { 56 if (this.size === 0) return [] 57 58 const result: T[] = [] 59 const start = this.size < this.capacity ? 0 : this.head 60 61 for (let i = 0; i < this.size; i++) { 62 const index = (start + i) % this.capacity 63 result.push(this.buffer[index]!) 64 } 65 66 return result 67 } 68 69 /** 70 * Clear all items from the buffer. 71 */ 72 clear(): void { 73 this.buffer.length = 0 74 this.head = 0 75 this.size = 0 76 } 77 78 /** 79 * Get the current number of items in the buffer. 80 */ 81 length(): number { 82 return this.size 83 } 84}