Fix two memory leaks in the collocator lookup
Every collocator lookup leaked a rocksdb iterator and 80 bytes of window sums:
CollocatorIterator takes the iterator that SeekIterator() gets from
DB::NewIterator(), but had no destructor, so the compiler generated one that
does not touch the raw pointer. The wrapper was deleted by its unique_ptr, the
iterator it wrapped was not, together with everything it pins.
get_collocators() allocated its fixed size sumWindow array with malloc() and
never freed it. It is a fixed size, so it lives on the stack now.
Measured with 20000 calls of get_collocators_as_json() on the test database:
3.63 kB per call before, no measurable growth at all afterwards. The 80 bytes
were per call regardless of the result size, which is what gave them away.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I1b1148ada81bd821784b8e327334fc3bafe29e1b
diff --git a/src/collocatordb.cc b/src/collocatordb.cc
index b46d536..30656fc 100644
--- a/src/collocatordb.cc
+++ b/src/collocatordb.cc
@@ -225,6 +225,10 @@
public:
explicit CollocatorIterator(Iterator *base_iterator) : base_iterator_(base_iterator) {}
+ /* Takes ownership of the iterator handed in by SeekIterator(). Without this
+ every seek leaked a rocksdb iterator and the resources it pins. */
+ ~CollocatorIterator() override { delete base_iterator_; }
+
void setPrefix(char *prefix) { memcpy(prefixc, prefix, sizeof(uint64_t)); }
void SeekToFirst() override { base_iterator_->SeekToFirst(); }
@@ -677,9 +681,9 @@
std::vector<Collocator> collocators;
uint64_t w2, last_w2 = 0xffffffffffffffff;
uint64_t maxv = 0, sum = 0;
- auto *sumWindow =
- static_cast<uint64_t *>(malloc(sizeof(uint64_t) * 2 * WINDOW_SIZE));
- memset(sumWindow, 0, sizeof(uint64_t) * 2 * WINDOW_SIZE);
+ /* fixed size, so it lives on the stack and cannot be leaked */
+ uint64_t sumWindow[2 * WINDOW_SIZE];
+ memset(sumWindow, 0, sizeof(sumWindow));
int true_window_size = 1;
int usedPositions = 0;