Skip to content

Commit 6af7301

Browse files
Compact consumed data in ReadBuffer.feed() before size check
Previously compaction only happened on read operations. Now feed() also triggers compaction, ensuring consumed bytes are reclaimed before new data is appended. This keeps actual memory usage closer to what max_message_size implies. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d977c12 commit 6af7301

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

src/dqlitewire/buffer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def __init__(self, max_message_size: int = DEFAULT_MAX_MESSAGE_SIZE) -> None:
4848

4949
def feed(self, data: bytes) -> None:
5050
"""Add received data to the buffer."""
51+
self._maybe_compact()
5152
unconsumed = len(self._data) - self._pos + len(data)
5253
if unconsumed > self._max_message_size:
5354
raise DecodeError(f"Buffer size {unconsumed} exceeds maximum {self._max_message_size}")

tests/test_buffer.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,22 @@ def test_skip_message_waits_for_complete_normal_sized_message(self) -> None:
272272
# Buffer position should not have changed
273273
assert buf.available() == 24 # 8 header + 16 partial body
274274

275+
def test_feed_compacts_consumed_data(self) -> None:
276+
"""feed() should compact consumed data before extending the buffer.
277+
278+
When _pos is past the compaction threshold, feed() should compact
279+
the buffer to reclaim consumed bytes before adding new data.
280+
"""
281+
buf = ReadBuffer(max_message_size=65536)
282+
# Simulate a state where data was consumed but not yet compacted
283+
# (e.g., by external manipulation or edge case in read patterns)
284+
buf._data = bytearray(b"\x00" * 5000)
285+
buf._pos = 4500 # 4500 consumed, 500 remaining
286+
# feed() should compact (since _pos > 4096) before extending
287+
buf.feed(b"\x01" * 100)
288+
assert buf._pos == 0
289+
assert len(buf._data) == 600 # 500 remaining + 100 new
290+
275291
def test_buffer_compaction(self) -> None:
276292
buf = ReadBuffer()
277293
# Feed a lot of small messages to trigger compaction

0 commit comments

Comments
 (0)