Skip to content

Commit c372c21

Browse files
committedOct 3, 2018
Replace FastReadBuffer object with a struct+inline functions
1 parent 5c31700 commit c372c21

22 files changed

+208
-196
lines changed
 

‎buffer.pxd

-41
Original file line numberDiff line numberDiff line change
@@ -142,44 +142,3 @@ cdef class ReadBuffer:
142142

143143
@staticmethod
144144
cdef ReadBuffer new_message_parser(object data)
145-
146-
147-
@cython.no_gc_clear
148-
@cython.final
149-
@cython.freelist(_BUFFER_FREELIST_SIZE)
150-
cdef class FastReadBuffer:
151-
152-
cdef:
153-
const char* buf
154-
ssize_t len
155-
156-
cdef inline const char* read(self, ssize_t n) except NULL:
157-
cdef const char *result
158-
159-
if n > self.len:
160-
self._raise_ins_err(n, self.len)
161-
162-
result = self.buf
163-
self.buf += n
164-
self.len -= n
165-
166-
return result
167-
168-
cdef inline const char* read_all(self):
169-
cdef const char *result
170-
result = self.buf
171-
self.buf += self.len
172-
self.len = 0
173-
return result
174-
175-
cdef inline FastReadBuffer slice_from(self, FastReadBuffer source,
176-
ssize_t len):
177-
self.buf = source.read(len)
178-
self.len = len
179-
return self
180-
181-
cdef _raise_ins_err(self, ssize_t n, ssize_t len)
182-
183-
@staticmethod
184-
cdef inline FastReadBuffer new():
185-
return FastReadBuffer.__new__(FastReadBuffer)

‎buffer.pyx

-11
Original file line numberDiff line numberDiff line change
@@ -658,14 +658,3 @@ cdef class ReadBuffer:
658658
buf._current_message_len_unread = buf._len0
659659

660660
return buf
661-
662-
663-
@cython.no_gc_clear
664-
@cython.final
665-
@cython.freelist(_BUFFER_FREELIST_SIZE)
666-
cdef class FastReadBuffer:
667-
668-
cdef _raise_ins_err(self, ssize_t n, ssize_t len):
669-
raise exceptions.BufferError(
670-
'insufficient data in buffer: requested {}, remaining {}'.
671-
format(n, self.len))

‎codecs/__init__.pxd

+38-38
Original file line numberDiff line numberDiff line change
@@ -16,128 +16,128 @@ ctypedef object (*encode_func)(CodecContext settings,
1616
object obj)
1717

1818
ctypedef object (*decode_func)(CodecContext settings,
19-
FastReadBuffer buf)
19+
FRBuffer *buf)
2020

2121

2222
# Datetime
2323
cdef date_encode(CodecContext settings, WriteBuffer buf, obj)
24-
cdef date_decode(CodecContext settings, FastReadBuffer buf)
24+
cdef date_decode(CodecContext settings, FRBuffer * buf)
2525
cdef date_encode_tuple(CodecContext settings, WriteBuffer buf, obj)
26-
cdef date_decode_tuple(CodecContext settings, FastReadBuffer buf)
26+
cdef date_decode_tuple(CodecContext settings, FRBuffer * buf)
2727
cdef timestamp_encode(CodecContext settings, WriteBuffer buf, obj)
28-
cdef timestamp_decode(CodecContext settings, FastReadBuffer buf)
28+
cdef timestamp_decode(CodecContext settings, FRBuffer * buf)
2929
cdef timestamp_encode_tuple(CodecContext settings, WriteBuffer buf, obj)
30-
cdef timestamp_decode_tuple(CodecContext settings, FastReadBuffer buf)
30+
cdef timestamp_decode_tuple(CodecContext settings, FRBuffer * buf)
3131
cdef timestamptz_encode(CodecContext settings, WriteBuffer buf, obj)
32-
cdef timestamptz_decode(CodecContext settings, FastReadBuffer buf)
32+
cdef timestamptz_decode(CodecContext settings, FRBuffer * buf)
3333
cdef time_encode(CodecContext settings, WriteBuffer buf, obj)
34-
cdef time_decode(CodecContext settings, FastReadBuffer buf)
34+
cdef time_decode(CodecContext settings, FRBuffer * buf)
3535
cdef time_encode_tuple(CodecContext settings, WriteBuffer buf, obj)
36-
cdef time_decode_tuple(CodecContext settings, FastReadBuffer buf)
36+
cdef time_decode_tuple(CodecContext settings, FRBuffer * buf)
3737
cdef timetz_encode(CodecContext settings, WriteBuffer buf, obj)
38-
cdef timetz_decode(CodecContext settings, FastReadBuffer buf)
38+
cdef timetz_decode(CodecContext settings, FRBuffer * buf)
3939
cdef timetz_encode_tuple(CodecContext settings, WriteBuffer buf, obj)
40-
cdef timetz_decode_tuple(CodecContext settings, FastReadBuffer buf)
40+
cdef timetz_decode_tuple(CodecContext settings, FRBuffer * buf)
4141
cdef interval_encode(CodecContext settings, WriteBuffer buf, obj)
42-
cdef interval_decode(CodecContext settings, FastReadBuffer buf)
42+
cdef interval_decode(CodecContext settings, FRBuffer * buf)
4343
cdef interval_encode_tuple(CodecContext settings, WriteBuffer buf, tuple obj)
44-
cdef interval_decode_tuple(CodecContext settings, FastReadBuffer buf)
44+
cdef interval_decode_tuple(CodecContext settings, FRBuffer * buf)
4545

4646

4747
# Bits
4848
cdef bits_encode(CodecContext settings, WriteBuffer wbuf, obj)
49-
cdef bits_decode(CodecContext settings, FastReadBuffer buf)
49+
cdef bits_decode(CodecContext settings, FRBuffer * buf)
5050

5151

5252
# Bools
5353
cdef bool_encode(CodecContext settings, WriteBuffer buf, obj)
54-
cdef bool_decode(CodecContext settings, FastReadBuffer buf)
54+
cdef bool_decode(CodecContext settings, FRBuffer * buf)
5555

5656

5757
# Geometry
5858
cdef box_encode(CodecContext settings, WriteBuffer wbuf, obj)
59-
cdef box_decode(CodecContext settings, FastReadBuffer buf)
59+
cdef box_decode(CodecContext settings, FRBuffer * buf)
6060
cdef line_encode(CodecContext settings, WriteBuffer wbuf, obj)
61-
cdef line_decode(CodecContext settings, FastReadBuffer buf)
61+
cdef line_decode(CodecContext settings, FRBuffer * buf)
6262
cdef lseg_encode(CodecContext settings, WriteBuffer wbuf, obj)
63-
cdef lseg_decode(CodecContext settings, FastReadBuffer buf)
63+
cdef lseg_decode(CodecContext settings, FRBuffer * buf)
6464
cdef point_encode(CodecContext settings, WriteBuffer wbuf, obj)
65-
cdef point_decode(CodecContext settings, FastReadBuffer buf)
65+
cdef point_decode(CodecContext settings, FRBuffer * buf)
6666
cdef path_encode(CodecContext settings, WriteBuffer wbuf, obj)
67-
cdef path_decode(CodecContext settings, FastReadBuffer buf)
67+
cdef path_decode(CodecContext settings, FRBuffer * buf)
6868
cdef poly_encode(CodecContext settings, WriteBuffer wbuf, obj)
69-
cdef poly_decode(CodecContext settings, FastReadBuffer buf)
69+
cdef poly_decode(CodecContext settings, FRBuffer * buf)
7070
cdef circle_encode(CodecContext settings, WriteBuffer wbuf, obj)
71-
cdef circle_decode(CodecContext settings, FastReadBuffer buf)
71+
cdef circle_decode(CodecContext settings, FRBuffer * buf)
7272

7373

7474
# Hstore
7575
cdef hstore_encode(CodecContext settings, WriteBuffer buf, obj)
76-
cdef hstore_decode(CodecContext settings, FastReadBuffer buf)
76+
cdef hstore_decode(CodecContext settings, FRBuffer * buf)
7777

7878

7979
# Ints
8080
cdef int2_encode(CodecContext settings, WriteBuffer buf, obj)
81-
cdef int2_decode(CodecContext settings, FastReadBuffer buf)
81+
cdef int2_decode(CodecContext settings, FRBuffer * buf)
8282
cdef int4_encode(CodecContext settings, WriteBuffer buf, obj)
83-
cdef int4_decode(CodecContext settings, FastReadBuffer buf)
83+
cdef int4_decode(CodecContext settings, FRBuffer * buf)
8484
cdef uint4_encode(CodecContext settings, WriteBuffer buf, obj)
85-
cdef uint4_decode(CodecContext settings, FastReadBuffer buf)
85+
cdef uint4_decode(CodecContext settings, FRBuffer * buf)
8686
cdef int8_encode(CodecContext settings, WriteBuffer buf, obj)
87-
cdef int8_decode(CodecContext settings, FastReadBuffer buf)
87+
cdef int8_decode(CodecContext settings, FRBuffer * buf)
8888

8989

9090
# Floats
9191
cdef float4_encode(CodecContext settings, WriteBuffer buf, obj)
92-
cdef float4_decode(CodecContext settings, FastReadBuffer buf)
92+
cdef float4_decode(CodecContext settings, FRBuffer * buf)
9393
cdef float8_encode(CodecContext settings, WriteBuffer buf, obj)
94-
cdef float8_decode(CodecContext settings, FastReadBuffer buf)
94+
cdef float8_decode(CodecContext settings, FRBuffer * buf)
9595

9696

9797
# JSON
9898
cdef jsonb_encode(CodecContext settings, WriteBuffer buf, obj)
99-
cdef jsonb_decode(CodecContext settings, FastReadBuffer buf)
99+
cdef jsonb_decode(CodecContext settings, FRBuffer * buf)
100100

101101

102102
# Text
103103
cdef as_pg_string_and_size(
104104
CodecContext settings, obj, char **cstr, ssize_t *size)
105105
cdef text_encode(CodecContext settings, WriteBuffer buf, obj)
106-
cdef text_decode(CodecContext settings, FastReadBuffer buf)
106+
cdef text_decode(CodecContext settings, FRBuffer * buf)
107107

108108
# Bytea
109109
cdef bytea_encode(CodecContext settings, WriteBuffer wbuf, obj)
110-
cdef bytea_decode(CodecContext settings, FastReadBuffer buf)
110+
cdef bytea_decode(CodecContext settings, FRBuffer * buf)
111111

112112

113113
# UUID
114114
cdef uuid_encode(CodecContext settings, WriteBuffer wbuf, obj)
115-
cdef uuid_decode(CodecContext settings, FastReadBuffer buf)
115+
cdef uuid_decode(CodecContext settings, FRBuffer * buf)
116116

117117

118118
# Numeric
119119
cdef numeric_encode_text(CodecContext settings, WriteBuffer buf, obj)
120-
cdef numeric_decode_text(CodecContext settings, FastReadBuffer buf)
120+
cdef numeric_decode_text(CodecContext settings, FRBuffer * buf)
121121
cdef numeric_encode_binary(CodecContext settings, WriteBuffer buf, obj)
122-
cdef numeric_decode_binary(CodecContext settings, FastReadBuffer buf)
122+
cdef numeric_decode_binary(CodecContext settings, FRBuffer * buf)
123123

124124

125125
# Void
126126
cdef void_encode(CodecContext settings, WriteBuffer buf, obj)
127-
cdef void_decode(CodecContext settings, FastReadBuffer buf)
127+
cdef void_decode(CodecContext settings, FRBuffer * buf)
128128

129129

130130
# tid
131131
cdef tid_encode(CodecContext settings, WriteBuffer buf, obj)
132-
cdef tid_decode(CodecContext settings, FastReadBuffer buf)
132+
cdef tid_decode(CodecContext settings, FRBuffer * buf)
133133

134134

135135
# Network
136-
cdef net_decode(CodecContext settings, FastReadBuffer buf)
136+
cdef net_decode(CodecContext settings, FRBuffer * buf)
137137
cdef cidr_encode(CodecContext settings, WriteBuffer buf, obj)
138138
cdef inet_encode(CodecContext settings, WriteBuffer buf, obj)
139139

140140

141141
# txid
142142
cdef txid_snapshot_encode(CodecContext settings, WriteBuffer buf, obj)
143-
cdef txid_snapshot_decode(CodecContext settings, FastReadBuffer buf)
143+
cdef txid_snapshot_decode(CodecContext settings, FRBuffer * buf)

‎codecs/bits.pyx

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ cdef bits_encode(CodecContext settings, WriteBuffer wbuf, obj):
4141
cpython.PyBuffer_Release(&pybuf)
4242

4343

44-
cdef bits_decode(CodecContext settings, FastReadBuffer buf):
44+
cdef bits_decode(CodecContext settings, FRBuffer *buf):
4545
cdef:
46-
int32_t bitlen = hton.unpack_int32(buf.read(4))
46+
int32_t bitlen = hton.unpack_int32(frb_read(buf, 4))
4747
ssize_t buf_len = buf.len
4848

49-
bytes_ = cpython.PyBytes_FromStringAndSize(buf.read_all(), buf_len)
49+
bytes_ = cpython.PyBytes_FromStringAndSize(frb_read_all(buf), buf_len)
5050
return BitString.frombytes(bytes_, bitlen)

‎codecs/bytea.pyx

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ cdef bytea_encode(CodecContext settings, WriteBuffer wbuf, obj):
2929
cpython.PyBuffer_Release(&pybuf)
3030

3131

32-
cdef bytea_decode(CodecContext settings, FastReadBuffer buf):
32+
cdef bytea_decode(CodecContext settings, FRBuffer *buf):
3333
cdef ssize_t buf_len = buf.len
34-
return cpython.PyBytes_FromStringAndSize(buf.read_all(), buf_len)
34+
return cpython.PyBytes_FromStringAndSize(frb_read_all(buf), buf_len)

‎codecs/datetime.pyx

+25-25
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ cdef inline _encode_time(WriteBuffer buf, int64_t seconds,
7878
buf.write_int64(ts)
7979

8080

81-
cdef inline int32_t _decode_time(FastReadBuffer buf, int64_t *seconds,
81+
cdef inline int32_t _decode_time(FRBuffer *buf, int64_t *seconds,
8282
int32_t *microseconds):
83-
cdef int64_t ts = hton.unpack_int64(buf.read(8))
83+
cdef int64_t ts = hton.unpack_int64(frb_read(buf, 8))
8484

8585
if ts == pg_time64_infinity:
8686
return 1
@@ -122,8 +122,8 @@ cdef date_encode_tuple(CodecContext settings, WriteBuffer buf, obj):
122122
buf.write_int32(pg_ordinal)
123123

124124

125-
cdef date_decode(CodecContext settings, FastReadBuffer buf):
126-
cdef int32_t pg_ordinal = hton.unpack_int32(buf.read(4))
125+
cdef date_decode(CodecContext settings, FRBuffer *buf):
126+
cdef int32_t pg_ordinal = hton.unpack_int32(frb_read(buf, 4))
127127

128128
if pg_ordinal == pg_date_infinity:
129129
return infinity_date
@@ -133,8 +133,8 @@ cdef date_decode(CodecContext settings, FastReadBuffer buf):
133133
return date_from_ordinal(pg_ordinal + pg_date_offset_ord)
134134

135135

136-
cdef date_decode_tuple(CodecContext settings, FastReadBuffer buf):
137-
cdef int32_t pg_ordinal = hton.unpack_int32(buf.read(4))
136+
cdef date_decode_tuple(CodecContext settings, FRBuffer *buf):
137+
cdef int32_t pg_ordinal = hton.unpack_int32(frb_read(buf, 4))
138138

139139
return (pg_ordinal,)
140140

@@ -175,7 +175,7 @@ cdef timestamp_encode_tuple(CodecContext settings, WriteBuffer buf, obj):
175175
buf.write_int64(microseconds)
176176

177177

178-
cdef timestamp_decode(CodecContext settings, FastReadBuffer buf):
178+
cdef timestamp_decode(CodecContext settings, FRBuffer *buf):
179179
cdef:
180180
int64_t seconds = 0
181181
int32_t microseconds = 0
@@ -192,9 +192,9 @@ cdef timestamp_decode(CodecContext settings, FastReadBuffer buf):
192192
timedelta(0, seconds, microseconds))
193193

194194

195-
cdef timestamp_decode_tuple(CodecContext settings, FastReadBuffer buf):
195+
cdef timestamp_decode_tuple(CodecContext settings, FRBuffer *buf):
196196
cdef:
197-
int64_t ts = hton.unpack_int64(buf.read(8))
197+
int64_t ts = hton.unpack_int64(frb_read(buf, 8))
198198

199199
return (ts,)
200200

@@ -236,7 +236,7 @@ cdef timestamptz_encode(CodecContext settings, WriteBuffer buf, obj):
236236
_encode_time(buf, seconds, microseconds)
237237

238238

239-
cdef timestamptz_decode(CodecContext settings, FastReadBuffer buf):
239+
cdef timestamptz_decode(CodecContext settings, FRBuffer *buf):
240240
cdef:
241241
int64_t seconds = 0
242242
int32_t microseconds = 0
@@ -279,7 +279,7 @@ cdef time_encode_tuple(CodecContext settings, WriteBuffer buf, obj):
279279
buf.write_int64(microseconds)
280280

281281

282-
cdef time_decode(CodecContext settings, FastReadBuffer buf):
282+
cdef time_decode(CodecContext settings, FRBuffer *buf):
283283
cdef:
284284
int64_t seconds = 0
285285
int32_t microseconds = 0
@@ -295,9 +295,9 @@ cdef time_decode(CodecContext settings, FastReadBuffer buf):
295295
return datetime.time(hours, min, sec, microseconds)
296296

297297

298-
cdef time_decode_tuple(CodecContext settings, FastReadBuffer buf):
298+
cdef time_decode_tuple(CodecContext settings, FRBuffer *buf):
299299
cdef:
300-
int64_t ts = hton.unpack_int64(buf.read(8))
300+
int64_t ts = hton.unpack_int64(frb_read(buf, 8))
301301

302302
return (ts,)
303303

@@ -342,17 +342,17 @@ cdef timetz_encode_tuple(CodecContext settings, WriteBuffer buf, obj):
342342
buf.write_int32(offset_sec)
343343

344344

345-
cdef timetz_decode(CodecContext settings, FastReadBuffer buf):
345+
cdef timetz_decode(CodecContext settings, FRBuffer *buf):
346346
time = time_decode(settings, buf)
347-
cdef int32_t offset = <int32_t>(hton.unpack_int32(buf.read(4)) / 60)
347+
cdef int32_t offset = <int32_t>(hton.unpack_int32(frb_read(buf, 4)) / 60)
348348
# See the comment in the `timetz_encode` method.
349349
return time.replace(tzinfo=datetime.timezone(timedelta(minutes=-offset)))
350350

351351

352-
cdef timetz_decode_tuple(CodecContext settings, FastReadBuffer buf):
352+
cdef timetz_decode_tuple(CodecContext settings, FRBuffer *buf):
353353
cdef:
354-
int64_t microseconds = hton.unpack_int64(buf.read(8))
355-
int32_t offset_sec = hton.unpack_int32(buf.read(4))
354+
int64_t microseconds = hton.unpack_int64(frb_read(buf, 8))
355+
int32_t offset_sec = hton.unpack_int32(frb_read(buf, 4))
356356

357357
return (microseconds, offset_sec)
358358

@@ -391,7 +391,7 @@ cdef interval_encode_tuple(CodecContext settings, WriteBuffer buf,
391391
buf.write_int32(months)
392392

393393

394-
cdef interval_decode(CodecContext settings, FastReadBuffer buf):
394+
cdef interval_decode(CodecContext settings, FRBuffer *buf):
395395
cdef:
396396
int32_t days
397397
int32_t months
@@ -401,8 +401,8 @@ cdef interval_decode(CodecContext settings, FastReadBuffer buf):
401401

402402
_decode_time(buf, &seconds, &microseconds)
403403

404-
days = hton.unpack_int32(buf.read(4))
405-
months = hton.unpack_int32(buf.read(4))
404+
days = hton.unpack_int32(frb_read(buf, 4))
405+
months = hton.unpack_int32(frb_read(buf, 4))
406406

407407
if months < 0:
408408
years = -<int32_t>(-months // 12)
@@ -415,14 +415,14 @@ cdef interval_decode(CodecContext settings, FastReadBuffer buf):
415415
seconds=seconds, microseconds=microseconds)
416416

417417

418-
cdef interval_decode_tuple(CodecContext settings, FastReadBuffer buf):
418+
cdef interval_decode_tuple(CodecContext settings, FRBuffer *buf):
419419
cdef:
420420
int32_t days
421421
int32_t months
422422
int64_t microseconds
423423

424-
microseconds = hton.unpack_int64(buf.read(8))
425-
days = hton.unpack_int32(buf.read(4))
426-
months = hton.unpack_int32(buf.read(4))
424+
microseconds = hton.unpack_int64(frb_read(buf, 8))
425+
days = hton.unpack_int32(frb_read(buf, 4))
426+
months = hton.unpack_int32(frb_read(buf, 4))
427427

428428
return (months, days, microseconds)

‎codecs/float.pyx

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ cdef float4_encode(CodecContext settings, WriteBuffer buf, obj):
1818
buf.write_float(fval)
1919

2020

21-
cdef float4_decode(CodecContext settings, FastReadBuffer buf):
22-
cdef float f = hton.unpack_float(buf.read(4))
21+
cdef float4_decode(CodecContext settings, FRBuffer *buf):
22+
cdef float f = hton.unpack_float(frb_read(buf, 4))
2323
return cpython.PyFloat_FromDouble(f)
2424

2525

@@ -29,6 +29,6 @@ cdef float8_encode(CodecContext settings, WriteBuffer buf, obj):
2929
buf.write_double(dval)
3030

3131

32-
cdef float8_decode(CodecContext settings, FastReadBuffer buf):
33-
cdef double f = hton.unpack_double(buf.read(8))
32+
cdef float8_decode(CodecContext settings, FRBuffer *buf):
33+
cdef double f = hton.unpack_double(frb_read(buf, 8))
3434
return cpython.PyFloat_FromDouble(f)

‎codecs/geometry.pyx

+28-28
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ cdef inline _encode_points(WriteBuffer wbuf, object points):
1616
wbuf.write_double(point[1])
1717

1818

19-
cdef inline _decode_points(FastReadBuffer buf):
19+
cdef inline _decode_points(FRBuffer *buf):
2020
cdef:
21-
int32_t npts = hton.unpack_int32(buf.read(4))
21+
int32_t npts = hton.unpack_int32(frb_read(buf, 4))
2222
pts = cpython.PyTuple_New(npts)
2323
int32_t i
2424
object point
2525
double x
2626
double y
2727

2828
for i in range(npts):
29-
x = hton.unpack_double(buf.read(8))
30-
y = hton.unpack_double(buf.read(8))
29+
x = hton.unpack_double(frb_read(buf, 8))
30+
y = hton.unpack_double(frb_read(buf, 8))
3131
point = Point(x, y)
3232
cpython.Py_INCREF(point)
3333
cpython.PyTuple_SET_ITEM(pts, i, point)
@@ -40,12 +40,12 @@ cdef box_encode(CodecContext settings, WriteBuffer wbuf, obj):
4040
_encode_points(wbuf, (obj[0], obj[1]))
4141

4242

43-
cdef box_decode(CodecContext settings, FastReadBuffer buf):
43+
cdef box_decode(CodecContext settings, FRBuffer *buf):
4444
cdef:
45-
double high_x = hton.unpack_double(buf.read(8))
46-
double high_y = hton.unpack_double(buf.read(8))
47-
double low_x = hton.unpack_double(buf.read(8))
48-
double low_y = hton.unpack_double(buf.read(8))
45+
double high_x = hton.unpack_double(frb_read(buf, 8))
46+
double high_y = hton.unpack_double(frb_read(buf, 8))
47+
double low_x = hton.unpack_double(frb_read(buf, 8))
48+
double low_y = hton.unpack_double(frb_read(buf, 8))
4949

5050
return Box(Point(high_x, high_y), Point(low_x, low_y))
5151

@@ -57,11 +57,11 @@ cdef line_encode(CodecContext settings, WriteBuffer wbuf, obj):
5757
wbuf.write_double(obj[2])
5858

5959

60-
cdef line_decode(CodecContext settings, FastReadBuffer buf):
60+
cdef line_decode(CodecContext settings, FRBuffer *buf):
6161
cdef:
62-
double A = hton.unpack_double(buf.read(8))
63-
double B = hton.unpack_double(buf.read(8))
64-
double C = hton.unpack_double(buf.read(8))
62+
double A = hton.unpack_double(frb_read(buf, 8))
63+
double B = hton.unpack_double(frb_read(buf, 8))
64+
double C = hton.unpack_double(frb_read(buf, 8))
6565

6666
return Line(A, B, C)
6767

@@ -71,12 +71,12 @@ cdef lseg_encode(CodecContext settings, WriteBuffer wbuf, obj):
7171
_encode_points(wbuf, (obj[0], obj[1]))
7272

7373

74-
cdef lseg_decode(CodecContext settings, FastReadBuffer buf):
74+
cdef lseg_decode(CodecContext settings, FRBuffer *buf):
7575
cdef:
76-
double p1_x = hton.unpack_double(buf.read(8))
77-
double p1_y = hton.unpack_double(buf.read(8))
78-
double p2_x = hton.unpack_double(buf.read(8))
79-
double p2_y = hton.unpack_double(buf.read(8))
76+
double p1_x = hton.unpack_double(frb_read(buf, 8))
77+
double p1_y = hton.unpack_double(frb_read(buf, 8))
78+
double p2_x = hton.unpack_double(frb_read(buf, 8))
79+
double p2_y = hton.unpack_double(frb_read(buf, 8))
8080

8181
return LineSegment((p1_x, p1_y), (p2_x, p2_y))
8282

@@ -87,10 +87,10 @@ cdef point_encode(CodecContext settings, WriteBuffer wbuf, obj):
8787
wbuf.write_double(obj[1])
8888

8989

90-
cdef point_decode(CodecContext settings, FastReadBuffer buf):
90+
cdef point_decode(CodecContext settings, FRBuffer *buf):
9191
cdef:
92-
double x = hton.unpack_double(buf.read(8))
93-
double y = hton.unpack_double(buf.read(8))
92+
double x = hton.unpack_double(frb_read(buf, 8))
93+
double y = hton.unpack_double(frb_read(buf, 8))
9494

9595
return Point(x, y)
9696

@@ -121,9 +121,9 @@ cdef path_encode(CodecContext settings, WriteBuffer wbuf, obj):
121121
_encode_points(wbuf, obj)
122122

123123

124-
cdef path_decode(CodecContext settings, FastReadBuffer buf):
124+
cdef path_decode(CodecContext settings, FRBuffer *buf):
125125
cdef:
126-
int8_t is_closed = <int8_t>buf.read(1)[0]
126+
int8_t is_closed = <int8_t>(frb_read(buf, 1)[0])
127127

128128
return Path(*_decode_points(buf), is_closed=is_closed == 1)
129129

@@ -145,7 +145,7 @@ cdef poly_encode(CodecContext settings, WriteBuffer wbuf, obj):
145145
_encode_points(wbuf, obj)
146146

147147

148-
cdef poly_decode(CodecContext settings, FastReadBuffer buf):
148+
cdef poly_decode(CodecContext settings, FRBuffer *buf):
149149
return Polygon(*_decode_points(buf))
150150

151151

@@ -156,10 +156,10 @@ cdef circle_encode(CodecContext settings, WriteBuffer wbuf, obj):
156156
wbuf.write_double(obj[1])
157157

158158

159-
cdef circle_decode(CodecContext settings, FastReadBuffer buf):
159+
cdef circle_decode(CodecContext settings, FRBuffer *buf):
160160
cdef:
161-
double center_x = hton.unpack_double(buf.read(8))
162-
double center_y = hton.unpack_double(buf.read(8))
163-
double radius = hton.unpack_double(buf.read(8))
161+
double center_x = hton.unpack_double(frb_read(buf, 8))
162+
double center_y = hton.unpack_double(frb_read(buf, 8))
163+
double radius = hton.unpack_double(frb_read(buf, 8))
164164

165165
return Circle((center_x, center_y), radius)

‎codecs/hstore.pyx

+6-6
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ cdef hstore_encode(CodecContext settings, WriteBuffer buf, obj):
4040
buf.write_buffer(item_buf)
4141

4242

43-
cdef hstore_decode(CodecContext settings, FastReadBuffer buf):
43+
cdef hstore_decode(CodecContext settings, FRBuffer *buf):
4444
cdef:
4545
dict result
4646
uint32_t elem_count
@@ -51,22 +51,22 @@ cdef hstore_decode(CodecContext settings, FastReadBuffer buf):
5151

5252
result = {}
5353

54-
elem_count = <uint32_t>hton.unpack_int32(buf.read(4))
54+
elem_count = <uint32_t>hton.unpack_int32(frb_read(buf, 4))
5555
if elem_count == 0:
5656
return result
5757

5858
for i in range(elem_count):
59-
elem_len = hton.unpack_int32(buf.read(4))
59+
elem_len = hton.unpack_int32(frb_read(buf, 4))
6060
if elem_len < 0:
6161
raise ValueError('null value not allowed in hstore key')
6262

63-
k = decode_pg_string(settings, buf.read(elem_len), elem_len)
63+
k = decode_pg_string(settings, frb_read(buf, elem_len), elem_len)
6464

65-
elem_len = hton.unpack_int32(buf.read(4))
65+
elem_len = hton.unpack_int32(frb_read(buf, 4))
6666
if elem_len < 0:
6767
v = None
6868
else:
69-
v = decode_pg_string(settings, buf.read(elem_len), elem_len)
69+
v = decode_pg_string(settings, frb_read(buf, elem_len), elem_len)
7070

7171
result[k] = v
7272

‎codecs/int.pyx

+10-10
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ cdef bool_encode(CodecContext settings, WriteBuffer buf, obj):
1414
buf.write_byte(b'\x01' if obj is True else b'\x00')
1515

1616

17-
cdef bool_decode(CodecContext settings, FastReadBuffer buf):
18-
return buf.read(1)[0] is b'\x01'
17+
cdef bool_decode(CodecContext settings, FRBuffer *buf):
18+
return frb_read(buf, 1)[0] is b'\x01'
1919

2020

2121
cdef int2_encode(CodecContext settings, WriteBuffer buf, obj):
@@ -34,8 +34,8 @@ cdef int2_encode(CodecContext settings, WriteBuffer buf, obj):
3434
buf.write_int16(<int16_t>val)
3535

3636

37-
cdef int2_decode(CodecContext settings, FastReadBuffer buf):
38-
return cpython.PyLong_FromLong(hton.unpack_int16(buf.read(2)))
37+
cdef int2_decode(CodecContext settings, FRBuffer *buf):
38+
return cpython.PyLong_FromLong(hton.unpack_int16(frb_read(buf, 2)))
3939

4040

4141
cdef int4_encode(CodecContext settings, WriteBuffer buf, obj):
@@ -55,8 +55,8 @@ cdef int4_encode(CodecContext settings, WriteBuffer buf, obj):
5555
buf.write_int32(<int32_t>val)
5656

5757

58-
cdef int4_decode(CodecContext settings, FastReadBuffer buf):
59-
return cpython.PyLong_FromLong(hton.unpack_int32(buf.read(4)))
58+
cdef int4_decode(CodecContext settings, FRBuffer *buf):
59+
return cpython.PyLong_FromLong(hton.unpack_int32(frb_read(buf, 4)))
6060

6161

6262
cdef uint4_encode(CodecContext settings, WriteBuffer buf, obj):
@@ -76,9 +76,9 @@ cdef uint4_encode(CodecContext settings, WriteBuffer buf, obj):
7676
buf.write_int32(<int32_t>val)
7777

7878

79-
cdef uint4_decode(CodecContext settings, FastReadBuffer buf):
79+
cdef uint4_decode(CodecContext settings, FRBuffer *buf):
8080
return cpython.PyLong_FromUnsignedLong(
81-
<uint32_t>hton.unpack_int32(buf.read(4)))
81+
<uint32_t>hton.unpack_int32(frb_read(buf, 4)))
8282

8383

8484
cdef int8_encode(CodecContext settings, WriteBuffer buf, obj):
@@ -98,5 +98,5 @@ cdef int8_encode(CodecContext settings, WriteBuffer buf, obj):
9898
buf.write_int64(<int64_t>val)
9999

100100

101-
cdef int8_decode(CodecContext settings, FastReadBuffer buf):
102-
return cpython.PyLong_FromLongLong(hton.unpack_int64(buf.read(8)))
101+
cdef int8_decode(CodecContext settings, FRBuffer *buf):
102+
return cpython.PyLong_FromLongLong(hton.unpack_int64(frb_read(buf, 8)))

‎codecs/json.pyx

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ cdef jsonb_encode(CodecContext settings, WriteBuffer buf, obj):
2020
buf.write_cstr(str, size)
2121

2222

23-
cdef jsonb_decode(CodecContext settings, FastReadBuffer buf):
24-
cdef uint8_t format = <uint8_t>buf.read(1)[0]
23+
cdef jsonb_decode(CodecContext settings, FRBuffer *buf):
24+
cdef uint8_t format = <uint8_t>(frb_read(buf, 1)[0])
2525

2626
if format != 1:
2727
raise ValueError('unexpected JSONB format: {}'.format(format))

‎codecs/misc.pyx

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ cdef void_encode(CodecContext settings, WriteBuffer buf, obj):
1010
buf.write_int32(0)
1111

1212

13-
cdef void_decode(CodecContext settings, FastReadBuffer buf):
13+
cdef void_decode(CodecContext settings, FRBuffer *buf):
1414
# Do nothing; void will be passed as NULL so this function
1515
# will never be called.
1616
pass

‎codecs/network.pyx

+6-6
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ cdef inline _net_encode(WriteBuffer buf, int8_t family, uint32_t bits,
5959
buf.write_cstr(addrbytes, addrlen)
6060

6161

62-
cdef net_decode(CodecContext settings, FastReadBuffer buf):
62+
cdef net_decode(CodecContext settings, FRBuffer *buf):
6363
cdef:
64-
int32_t family = <int32_t>buf.read(1)[0]
65-
uint8_t bits = <uint8_t>buf.read(1)[0]
66-
int32_t is_cidr = <int32_t>buf.read(1)[0]
67-
int32_t addrlen = <int32_t>buf.read(1)[0]
64+
int32_t family = <int32_t>frb_read(buf, 1)[0]
65+
uint8_t bits = <uint8_t>frb_read(buf, 1)[0]
66+
int32_t is_cidr = <int32_t>frb_read(buf, 1)[0]
67+
int32_t addrlen = <int32_t>frb_read(buf, 1)[0]
6868
bytes addr
6969
uint8_t max_prefix_len = _ip_max_prefix_len(family)
7070

@@ -85,7 +85,7 @@ cdef net_decode(CodecContext settings, FastReadBuffer buf):
8585
'cidr' if is_cidr else 'inet'
8686
))
8787

88-
addr = cpython.PyBytes_FromStringAndSize(buf.read(addrlen), addrlen)
88+
addr = cpython.PyBytes_FromStringAndSize(frb_read(buf, addrlen), addrlen)
8989

9090
if is_cidr or bits != max_prefix_len:
9191
return _ipnet(addr).supernet(new_prefix=cpython.PyLong_FromLong(bits))

‎codecs/numeric.pyx

+8-8
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ cdef numeric_encode_text(CodecContext settings, WriteBuffer buf, obj):
2424
text_encode(settings, buf, str(obj))
2525

2626

27-
cdef numeric_decode_text(CodecContext settings, FastReadBuffer buf):
27+
cdef numeric_decode_text(CodecContext settings, FRBuffer *buf):
2828
return _Dec(text_decode(settings, buf))
2929

3030

@@ -129,12 +129,12 @@ cdef numeric_encode_binary(CodecContext settings, WriteBuffer buf, obj):
129129
# For this reason the below code is pure overhead and is ~25% slower
130130
# than the simple text decoder above. That said, we need the binary
131131
# decoder to support binary COPY with numeric values.
132-
cdef numeric_decode_binary(CodecContext settings, FastReadBuffer buf):
132+
cdef numeric_decode_binary(CodecContext settings, FRBuffer *buf):
133133
cdef:
134-
uint16_t num_pgdigits = <uint16_t>hton.unpack_int16(buf.read(2))
135-
int16_t weight = hton.unpack_int16(buf.read(2))
136-
uint16_t sign = <uint16_t>hton.unpack_int16(buf.read(2))
137-
uint16_t dscale = <uint16_t>hton.unpack_int16(buf.read(2))
134+
uint16_t num_pgdigits = <uint16_t>hton.unpack_int16(frb_read(buf, 2))
135+
int16_t weight = hton.unpack_int16(frb_read(buf, 2))
136+
uint16_t sign = <uint16_t>hton.unpack_int16(frb_read(buf, 2))
137+
uint16_t dscale = <uint16_t>hton.unpack_int16(frb_read(buf, 2))
138138
int16_t pgdigit0
139139
ssize_t i
140140
int16_t pgdigit
@@ -161,7 +161,7 @@ cdef numeric_decode_binary(CodecContext settings, FastReadBuffer buf):
161161
# Zero
162162
return _Dec('0e-' + str(dscale))
163163

164-
pgdigit0 = hton.unpack_int16(buf.read(2))
164+
pgdigit0 = hton.unpack_int16(frb_read(buf, 2))
165165
if weight >= 0:
166166
if pgdigit0 < 10:
167167
front_padding = 3
@@ -211,7 +211,7 @@ cdef numeric_decode_binary(CodecContext settings, FastReadBuffer buf):
211211
bufptr = _unpack_digit(bufptr, pgdigit0)
212212

213213
for i in range(1, num_pgdigits):
214-
pgdigit = hton.unpack_int16(buf.read(2))
214+
pgdigit = hton.unpack_int16(frb_read(buf, 2))
215215
bufptr = _unpack_digit(bufptr, pgdigit)
216216

217217
if dscale:

‎codecs/text.pyx

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,6 @@ cdef inline decode_pg_string(CodecContext settings, const char* data,
4343
return settings.get_text_codec().decode(bytes)
4444

4545

46-
cdef text_decode(CodecContext settings, FastReadBuffer buf):
46+
cdef text_decode(CodecContext settings, FRBuffer *buf):
4747
cdef ssize_t buf_len = buf.len
48-
return decode_pg_string(settings, buf.read_all(), buf_len)
48+
return decode_pg_string(settings, frb_read_all(buf), buf_len)

‎codecs/tid.pyx

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ cdef tid_encode(CodecContext settings, WriteBuffer buf, obj):
4040
buf.write_int16(<int16_t>offset)
4141

4242

43-
cdef tid_decode(CodecContext settings, FastReadBuffer buf):
43+
cdef tid_decode(CodecContext settings, FRBuffer *buf):
4444
cdef:
4545
uint32_t block
4646
uint16_t offset
4747

48-
block = <uint32_t>hton.unpack_int32(buf.read(4))
49-
offset = <uint16_t>hton.unpack_int16(buf.read(2))
48+
block = <uint32_t>hton.unpack_int32(frb_read(buf, 4))
49+
offset = <uint16_t>hton.unpack_int16(frb_read(buf, 2))
5050

5151
return (block, offset)

‎codecs/txid.pyx

+5-5
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ cdef txid_snapshot_encode(CodecContext settings, WriteBuffer buf, obj):
3939
buf.write_buffer(xip_buf)
4040

4141

42-
cdef txid_snapshot_decode(CodecContext settings, FastReadBuffer buf):
42+
cdef txid_snapshot_decode(CodecContext settings, FRBuffer *buf):
4343
cdef:
4444
int32_t nxip
4545
int64_t xmin
@@ -48,13 +48,13 @@ cdef txid_snapshot_decode(CodecContext settings, FastReadBuffer buf):
4848
int32_t i
4949
object xip
5050

51-
nxip = hton.unpack_int32(buf.read(4))
52-
xmin = hton.unpack_int64(buf.read(8))
53-
xmax = hton.unpack_int64(buf.read(8))
51+
nxip = hton.unpack_int32(frb_read(buf, 4))
52+
xmin = hton.unpack_int64(frb_read(buf, 8))
53+
xmax = hton.unpack_int64(frb_read(buf, 8))
5454

5555
xip_tup = cpython.PyTuple_New(nxip)
5656
for i in range(nxip):
57-
xip = cpython.PyLong_FromLongLong(hton.unpack_int64(buf.read(8)))
57+
xip = cpython.PyLong_FromLongLong(hton.unpack_int64(frb_read(buf, 8)))
5858
cpython.Py_INCREF(xip)
5959
cpython.PyTuple_SET_ITEM(xip_tup, i, xip)
6060

‎codecs/uuid.pyx

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ cdef uuid_encode(CodecContext settings, WriteBuffer wbuf, obj):
1818
bytea_encode(settings, wbuf, obj.bytes)
1919

2020

21-
cdef uuid_decode(CodecContext settings, FastReadBuffer buf):
21+
cdef uuid_decode(CodecContext settings, FRBuffer *buf):
2222
return _UUID(bytes=bytea_decode(settings, buf))

‎frb.pxd

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright (C) 2016-present the asyncpg authors and contributors
2+
# <see AUTHORS file>
3+
#
4+
# This module is part of asyncpg and is released under
5+
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
6+
7+
8+
cdef:
9+
10+
struct FRBuffer:
11+
const char* buf
12+
ssize_t len
13+
14+
inline ssize_t frb_get_len(FRBuffer *frb):
15+
return frb.len
16+
17+
inline void frb_set_len(FRBuffer *frb, ssize_t new_len):
18+
frb.len = new_len
19+
20+
inline void frb_init(FRBuffer *frb, const char *buf, ssize_t len):
21+
frb.buf = buf
22+
frb.len = len
23+
24+
inline const char* frb_read(FRBuffer *frb, ssize_t n) except NULL:
25+
cdef const char *result
26+
27+
if n > frb.len:
28+
frb_check(frb, n)
29+
30+
result = frb.buf
31+
frb.buf += n
32+
frb.len -= n
33+
34+
return result
35+
36+
inline const char* frb_read_all(FRBuffer *frb):
37+
cdef const char *result
38+
result = frb.buf
39+
frb.buf += frb.len
40+
frb.len = 0
41+
return result
42+
43+
inline FRBuffer *frb_slice_from(FRBuffer *frb,
44+
FRBuffer* source, ssize_t len):
45+
frb.buf = frb_read(source, len)
46+
frb.len = len
47+
return frb
48+
49+
object frb_check(FRBuffer *frb, ssize_t n)

‎frb.pyx

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (C) 2016-present the asyncpg authors and contributors
2+
# <see AUTHORS file>
3+
#
4+
# This module is part of asyncpg and is released under
5+
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
6+
7+
8+
cdef object frb_check(FRBuffer *frb, ssize_t n):
9+
if n > frb.len:
10+
raise AssertionError(
11+
f'insufficient data in buffer: requested {n} '
12+
f'remaining {frb.len}')

‎pgproto.pxd

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ from libc.stdint cimport int16_t, int32_t, uint16_t, uint32_t, int64_t, uint64_t
1212

1313

1414
include "./consts.pxi"
15+
include "./frb.pxd"
1516
include "./buffer.pxd"
1617

1718

‎pgproto.pyx

+2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ from libc.stdint cimport int8_t, uint8_t, int16_t, uint16_t, \
1717

1818

1919
from . cimport hton
20+
2021
from .debug cimport PG_DEBUG
2122

2223

2324
include "./consts.pxi"
25+
include "./frb.pyx"
2426
include "./buffer.pyx"
2527

2628
include "./codecs/context.pyx"

0 commit comments

Comments
 (0)
Please sign in to comment.