Write writes data to the ring buffer. If the buffer would overflow, it evicts the oldest data to make room for new data.
(data []byte)
| 37 | // Write writes data to the ring buffer. If the buffer would overflow, |
| 38 | // it evicts the oldest data to make room for new data. |
| 39 | func (rb *ringBuffer) Write(data []byte) { |
| 40 | if len(data) == 0 { |
| 41 | return |
| 42 | } |
| 43 | |
| 44 | capacity := len(rb.buffer) |
| 45 | |
| 46 | // If data is larger than capacity, only keep the last capacity bytes |
| 47 | if len(data) > capacity { |
| 48 | data = data[len(data)-capacity:] |
| 49 | // Clear buffer and write new data |
| 50 | rb.start = 0 |
| 51 | rb.end = -1 // Will be set properly below |
| 52 | } |
| 53 | |
| 54 | // Calculate how much we need to evict to fit new data |
| 55 | spaceNeeded := len(data) |
| 56 | availableSpace := capacity - rb.Size() |
| 57 | |
| 58 | if spaceNeeded > availableSpace { |
| 59 | bytesToEvict := spaceNeeded - availableSpace |
| 60 | rb.evict(bytesToEvict) |
| 61 | } |
| 62 | |
| 63 | // Buffer has data, write after current end |
| 64 | writePos := (rb.end + 1) % capacity |
| 65 | if writePos+len(data) <= capacity { |
| 66 | // No wrap needed - single copy |
| 67 | copy(rb.buffer[writePos:], data) |
| 68 | rb.end = (rb.end + len(data)) % capacity |
| 69 | } else { |
| 70 | // Need to wrap around - two copies |
| 71 | firstChunk := capacity - writePos |
| 72 | copy(rb.buffer[writePos:], data[:firstChunk]) |
| 73 | copy(rb.buffer[0:], data[firstChunk:]) |
| 74 | rb.end = len(data) - firstChunk - 1 |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | // evict removes the specified number of bytes from the beginning of the buffer. |
| 79 | func (rb *ringBuffer) evict(count int) { |