@@ -338,6 +338,7 @@ cdef class ReadBuffer:
338
338
cdef:
339
339
ssize_t nread
340
340
341
+ self ._ensure_first_buf()
341
342
while True :
342
343
if self ._pos0 + nbytes > self ._len0:
343
344
nread = self ._len0 - self ._pos0
@@ -579,6 +580,10 @@ cdef class ReadBuffer:
579
580
cdef:
580
581
const char * cbuf
581
582
ssize_t cbuf_len
583
+ int32_t msg_len
584
+ ssize_t new_pos0
585
+ ssize_t pos_delta
586
+ int32_t done
582
587
583
588
while True :
584
589
buf.write_byte(mtype)
@@ -590,10 +595,44 @@ cdef class ReadBuffer:
590
595
else :
591
596
buf.write_bytes(self .consume_message())
592
597
598
+ # Fast path: exhaust buf0 as efficiently as possible
599
+ self ._ensure_first_buf()
600
+ if self ._pos0 + 5 <= self ._len0:
601
+ cbuf = cpython.PyBytes_AS_STRING(self ._buf0)
602
+ new_pos0 = self ._pos0
603
+
604
+ done = 0
605
+ while new_pos0 + 5 <= self ._len0:
606
+ if (cbuf + new_pos0)[0 ] != mtype:
607
+ done = 1
608
+ break
609
+ msg_len = hton.unpack_int32(cbuf + new_pos0 + 1 ) + 1
610
+ if new_pos0 + msg_len > self ._len0:
611
+ break
612
+ new_pos0 += msg_len
613
+
614
+ if new_pos0 != self ._pos0:
615
+ if PG_DEBUG:
616
+ assert self ._pos0 < new_pos0 <= self ._len0
617
+
618
+ pos_delta = new_pos0 - self ._pos0
619
+ buf.write_cstr(
620
+ cbuf + self ._pos0,
621
+ pos_delta)
622
+
623
+ self ._pos0 = new_pos0
624
+ self ._length -= pos_delta
625
+
626
+ if PG_DEBUG:
627
+ assert self ._length >= 0
628
+
629
+ if done:
630
+ # The next message is of a different type.
631
+ return
632
+
633
+ # Back to slow path
593
634
if not self .take_message_type(mtype):
594
- break
595
-
596
- return buf
635
+ return
597
636
598
637
cdef bytearray consume_messages(self , char mtype):
599
638
""" Consume consecutive messages of the same type."""
@@ -613,6 +652,7 @@ cdef class ReadBuffer:
613
652
buf = cpythonx.PyByteArray_AsString(result)
614
653
615
654
while self .take_message_type(mtype):
655
+ self ._ensure_first_buf()
616
656
nbytes = self ._current_message_len_unread
617
657
self ._read_into(buf, nbytes)
618
658
buf += nbytes
0 commit comments