Level 1 A byte ring buffer that overwrites
Build RingBuffer(capacity): a fixed block of capacity bytes with a write position and a read position that move forward independently and wrap around. Writing never blocks or fails: if the writer laps the reader, the oldest unread bytes are silently overwritten.
write(data: bytes) -> None: append all ofdata. If that makes more thancapacitybytes unread, the oldest unread bytes are lost (overwritten), so at mostcapacityunread bytes remain: the lastcapacitybytes ever written. (A single write longer thancapacitykeeps only its own tail.)read(n: int) -> bytes: remove and return up tonof the oldest unread bytes (fewer, possiblyb"", if fewer are unread).available() -> int: how many unread bytes there are.dropped() -> int: the total number of bytes that were overwritten before anyone read them.
rb = RingBuffer(5)
rb.write(b"abc")
rb.read(2) # b"ab"
rb.write(b"defgh") # unread would be "cdefgh" (6 > 5): "c" is overwritten
rb.available() # 5
rb.dropped() # 1
rb.read(10) # b"defgh"
rb.write(b"123456789")
rb.read(10) # b"56789" (dropped() is now 5)
Constraints: 1 <= capacity <= 2^20. The buffer is used for streaming, so each call must cost O(len(data)) or O(n), not O(capacity): no rebuilding or shifting the whole buffer per call.
Show hint
Keep a bytearray(capacity) and two ever-increasing counters, written and read_pos (total bytes ever written / consumed). A byte's slot is position % capacity, so a write or read is at most two slice copies (before and after the wrap). After a write, if written - read_pos > capacity, move read_pos up to written - capacity and add the difference to dropped.