Skip to content

Commit 112df14

Browse files
authored
fix: reset next string table index on rollback
1 parent 24dd998 commit 112df14

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

ddtrace/internal/_encoding.pyx

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ from ddtrace.constants import ORIGIN_KEY
99

1010

1111
DEF MSGPACK_ARRAY_LENGTH_PREFIX_SIZE = 5
12+
DEF MSGPACK_STRING_TABLE_LENGTH_PREFIX_SIZE = 6
1213

1314

1415
cdef extern from "Python.h":
@@ -166,8 +167,9 @@ cdef class StringTable(object):
166167

167168
cdef reset(self):
168169
PyDict_Clear(self._table)
169-
self._next_id = 0
170-
assert self._index("") == 0
170+
PyDict_SetItem(self._table, "", 0)
171+
self.insert("")
172+
self._next_id = 1
171173

172174
def __len__(self):
173175
return PyLong_FromLong(self._next_id)
@@ -193,7 +195,8 @@ cdef class ListStringTable(StringTable):
193195
cdef class MsgpackStringTable(StringTable):
194196
cdef msgpack_packer pk
195197
cdef int max_size
196-
cdef int _sp
198+
cdef int _sp_len
199+
cdef stdint.uint32_t _sp_id
197200
cdef object _lock
198201
cdef size_t _reset_size
199202

@@ -203,8 +206,8 @@ cdef class MsgpackStringTable(StringTable):
203206
if self.pk.buf == NULL:
204207
raise MemoryError("Unable to allocate internal buffer.")
205208
self.max_size = max_size
206-
self.pk.length = 6
207-
self._sp = 0
209+
self.pk.length = MSGPACK_STRING_TABLE_LENGTH_PREFIX_SIZE
210+
self._sp_len = 0
208211
self._lock = threading.Lock()
209212
super(MsgpackStringTable, self).__init__()
210213

@@ -218,21 +221,30 @@ cdef class MsgpackStringTable(StringTable):
218221
cdef insert(self, object string):
219222
cdef int ret
220223

224+
if self.pk.length + len(string) > self.max_size:
225+
raise ValueError(
226+
"Cannot insert '%s': string table is full (current size: %d, max size: %d)." % (
227+
string, self.pk.length, self.max_size
228+
)
229+
)
230+
221231
ret = pack_text(&self.pk, string)
222232
if ret != 0:
223233
raise RuntimeError("Failed to add string to msgpack string table")
224234

225235
cdef savepoint(self):
226-
self._sp = self.pk.length
236+
self._sp_len = self.pk.length
237+
self._sp_id = self._next_id
227238

228239
cdef rollback(self):
229-
if self._sp > 0:
230-
self.pk.length = self._sp
240+
if self._sp_len > 0:
241+
self.pk.length = self._sp_len
242+
self._next_id = self._sp_id
231243

232244
cdef get_bytes(self):
233245
cdef int ret;
234246
cdef stdint.uint32_t l = self._next_id
235-
cdef int offset = 6 - array_prefix_size(l)
247+
cdef int offset = MSGPACK_STRING_TABLE_LENGTH_PREFIX_SIZE - array_prefix_size(l)
236248
cdef int old_pos = self.pk.length
237249

238250
with self._lock:
@@ -262,14 +274,20 @@ cdef class MsgpackStringTable(StringTable):
262274
if res != 0:
263275
raise RuntimeError("Failed to append raw bytes to msgpack string table")
264276

277+
cdef reset(self):
278+
StringTable.reset(self)
279+
assert self._next_id == 1
280+
281+
PyDict_SetItem(self._table, ORIGIN_KEY, 1)
282+
self._next_id = 2
283+
self.pk.length = self._reset_size
284+
self._sp_len = 0
265285

266286
cpdef flush(self):
267287
try:
268288
return self.get_bytes()
269289
finally:
270290
self.reset()
271-
self.pk.length = self._reset_size
272-
self._sp = 0
273291

274292

275293
cdef class BufferedEncoder(object):

tests/tracer/test_encoders.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ def test_msgpack_string_table():
414414
assert size == len(encoded)
415415
assert decode(encoded + b"\xc0") == [[b"", ORIGIN_KEY.encode(), b"foobar", b"foobaz"], None]
416416

417-
assert len(t) == 1
417+
assert len(t) == 2
418418
assert "foobar" not in t
419419

420420

0 commit comments

Comments
 (0)