Skip to content

Commit 686e024

Browse files
sundbShooterIT
andcommitted
Use z*_usable family to calculate the usable size of ar
Co-authored-by: Yuan Wang <[email protected]>
1 parent 8bad726 commit 686e024

1 file changed

Lines changed: 48 additions & 66 deletions

File tree

src/sparsearray.c

Lines changed: 48 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,28 @@
4747
* answer. When ar is NULL (e.g. during arFree) tracking is skipped.
4848
* -------------------------------------------------------------------------- */
4949

50-
static inline void arTrackAlloc(redisArray *ar, void *ptr) {
51-
if (ar) ar->alloc_size += zmalloc_size(ptr);
50+
static inline void *arAllocAndTrack(redisArray *ar, size_t size) {
51+
size_t usable;
52+
void *ptr = zmalloc_usable(size, &usable);
53+
if (ar) ar->alloc_size += usable;
54+
return ptr;
55+
}
56+
static inline void *arCallocAndTrack(redisArray *ar, size_t size) {
57+
size_t usable;
58+
void *ptr = zcalloc_usable(size, &usable);
59+
if (ar) ar->alloc_size += usable;
60+
return ptr;
5261
}
53-
static inline void arTrackFree(redisArray *ar, void *ptr) {
54-
if (ar) ar->alloc_size -= zmalloc_size(ptr);
62+
static inline void arFreeAndTrack(redisArray *ar, void *ptr) {
63+
size_t usable;
64+
zfree_usable(ptr, &usable);
65+
if (ar) ar->alloc_size -= usable;
5566
}
56-
static inline void arTrackRealloc(redisArray *ar, size_t old_size, void *ptr) {
57-
if (ar) ar->alloc_size += zmalloc_size(ptr) - old_size;
67+
static inline void *arReallocAndTrack(redisArray *ar, void *ptr, size_t size) {
68+
size_t usable, old_usable;
69+
void *newptr = zrealloc_usable(ptr, size, &usable, &old_usable);
70+
if (ar) ar->alloc_size += usable - old_usable;
71+
return newptr;
5872
}
5973

6074
/* Track a tagged value entering/leaving the array (arString bookkeeping). */
@@ -213,8 +227,7 @@ arSlice *arSliceDenseNew(redisArray *ar, uint32_t rel_idx, uint32_t slice_size)
213227
offset = slice_size - winsize;
214228
}
215229

216-
arSlice *s = zmalloc(arDenseAllocSize(winsize));
217-
arTrackAlloc(ar, s);
230+
arSlice *s = arAllocAndTrack(ar, arDenseAllocSize(winsize));
218231
s->encoding = AR_SLICE_DENSE;
219232
s->count = 0;
220233
s->layout.dense.offset = offset;
@@ -242,8 +255,7 @@ void arSparseSetupPointers(arSlice *s) {
242255
/* Create a new sparse slice */
243256
arSlice *arSliceSparseNew(redisArray *ar) {
244257
uint32_t cap = (ArraySparseKMax < 4) ? ArraySparseKMax : 4;
245-
arSlice *s = zmalloc(arSparseAllocSize(cap));
246-
arTrackAlloc(ar, s);
258+
arSlice *s = arAllocAndTrack(ar, arSparseAllocSize(cap));
247259
s->encoding = AR_SLICE_SPARSE;
248260
s->count = 0;
249261
s->layout.sparse.cap = cap;
@@ -269,8 +281,7 @@ void arSliceFree(redisArray *ar, arSlice *s) {
269281
arFreePtr(values[i]);
270282
}
271283
}
272-
arTrackFree(ar, s);
273-
zfree(s);
284+
arFreeAndTrack(ar, s);
274285
}
275286

276287
/* Grow dense slice to accommodate rel_idx (right growth) */
@@ -295,9 +306,7 @@ arSlice *arSliceDenseGrowRight(redisArray *ar, arSlice *s, uint32_t rel_idx, uin
295306
* the dense allocation without relocating existing items ourselves. */
296307
if (new_offset == s->layout.dense.offset) {
297308
uint32_t old_winsize = s->layout.dense.winsize;
298-
size_t old_size = zmalloc_size(s);
299-
arSlice *ns = zrealloc(s, arDenseAllocSize(new_winsize));
300-
arTrackRealloc(ar, old_size, ns);
309+
arSlice *ns = arReallocAndTrack(ar, s, arDenseAllocSize(new_winsize));
301310
ns->layout.dense.winsize = new_winsize;
302311
ns->layout.dense.items = (void **)(ns + 1);
303312

@@ -308,8 +317,7 @@ arSlice *arSliceDenseGrowRight(redisArray *ar, arSlice *s, uint32_t rel_idx, uin
308317
}
309318

310319
/* Data copy path: offset moved, so we allocate a new slice and copy. */
311-
arSlice *ns = zmalloc(arDenseAllocSize(new_winsize));
312-
arTrackAlloc(ar, ns);
320+
arSlice *ns = arAllocAndTrack(ar, arDenseAllocSize(new_winsize));
313321
ns->encoding = AR_SLICE_DENSE;
314322
ns->count = s->count;
315323
ns->layout.dense.offset = new_offset;
@@ -324,8 +332,7 @@ arSlice *arSliceDenseGrowRight(redisArray *ar, arSlice *s, uint32_t rel_idx, uin
324332
serverAssert(shift + s->layout.dense.winsize <= new_winsize);
325333
memcpy(ns->layout.dense.items + shift, s->layout.dense.items, s->layout.dense.winsize * sizeof(void *));
326334

327-
arTrackFree(ar, s);
328-
zfree(s);
335+
arFreeAndTrack(ar, s);
329336
return ns;
330337
}
331338

@@ -348,8 +355,7 @@ arSlice *arSliceDenseGrowLeft(redisArray *ar, arSlice *s, uint32_t rel_idx, uint
348355
if (new_offset < 0) new_offset = 0;
349356
if (new_winsize == slice_size) new_offset = 0;
350357

351-
arSlice *ns = zmalloc(arDenseAllocSize(new_winsize));
352-
arTrackAlloc(ar, ns);
358+
arSlice *ns = arAllocAndTrack(ar, arDenseAllocSize(new_winsize));
353359
ns->encoding = AR_SLICE_DENSE;
354360
ns->count = s->count;
355361
ns->layout.dense.offset = (uint32_t)new_offset;
@@ -363,8 +369,7 @@ arSlice *arSliceDenseGrowLeft(redisArray *ar, arSlice *s, uint32_t rel_idx, uint
363369
serverAssert(shift + s->layout.dense.winsize <= new_winsize);
364370
memcpy(ns->layout.dense.items + shift, s->layout.dense.items, s->layout.dense.winsize * sizeof(void *));
365371

366-
arTrackFree(ar, s);
367-
zfree(s);
372+
arFreeAndTrack(ar, s);
368373
return ns;
369374
}
370375

@@ -401,8 +406,7 @@ uint32_t arSparseFindPos(arSlice *s, uint16_t rel_idx, int *found) {
401406
/* Promote sparse slice to dense. */
402407
arSlice *arSparsePromote(redisArray *ar, arSlice *s, uint32_t slice_size) {
403408
if (s->count == 0) {
404-
arTrackFree(ar, s);
405-
zfree(s);
409+
arFreeAndTrack(ar, s);
406410
return arSliceDenseNew(ar, 0, slice_size);
407411
}
408412

@@ -425,8 +429,7 @@ arSlice *arSparsePromote(redisArray *ar, arSlice *s, uint32_t slice_size) {
425429
offset = slice_size - winsize;
426430
}
427431

428-
arSlice *d = zmalloc(arDenseAllocSize(winsize));
429-
arTrackAlloc(ar, d);
432+
arSlice *d = arAllocAndTrack(ar, arDenseAllocSize(winsize));
430433
d->encoding = AR_SLICE_DENSE;
431434
d->count = s->count;
432435
d->layout.dense.offset = offset;
@@ -443,8 +446,7 @@ arSlice *arSparsePromote(redisArray *ar, arSlice *s, uint32_t slice_size) {
443446
d->layout.dense.items[offsets[i] - offset] = values[i];
444447
}
445448

446-
arTrackFree(ar, s);
447-
zfree(s);
449+
arFreeAndTrack(ar, s);
448450
return d;
449451
}
450452

@@ -468,8 +470,7 @@ arSlice *arDenseMaybeDemote(redisArray *ar, arSlice *d) {
468470
if (dense_bytes < sparse_bytes * 5 / 4) return d;
469471

470472
/* Demote it. */
471-
arSlice *s = zmalloc(arSparseAllocSize(ArraySparseKMin));
472-
arTrackAlloc(ar, s);
473+
arSlice *s = arAllocAndTrack(ar, arSparseAllocSize(ArraySparseKMin));
473474
s->encoding = AR_SLICE_SPARSE;
474475
s->count = 0;
475476
s->layout.sparse.cap = ArraySparseKMin;
@@ -486,8 +487,7 @@ arSlice *arDenseMaybeDemote(redisArray *ar, arSlice *d) {
486487
}
487488
}
488489

489-
arTrackFree(ar, d);
490-
zfree(d);
490+
arFreeAndTrack(ar, d);
491491
return s;
492492
}
493493

@@ -584,9 +584,7 @@ arSlice **arSuperDirEnsureSlot(redisArray *ar, uint64_t slice_id) {
584584
if (ar->sdir_len >= ar->sdir_cap) {
585585
/* Grow superdir array */
586586
uint32_t new_cap = ar->sdir_cap ? ar->sdir_cap * 2 : 4;
587-
size_t old_size = ar->superdir ? zmalloc_size(ar->superdir) : 0;
588-
ar->superdir = zrealloc(ar->superdir, new_cap * sizeof(arSDirEntry));
589-
arTrackRealloc(ar, old_size, ar->superdir);
587+
ar->superdir = arReallocAndTrack(ar, ar->superdir, new_cap * sizeof(arSDirEntry));
590588
ar->sdir_cap = new_cap;
591589
}
592590

@@ -599,8 +597,7 @@ arSlice **arSuperDirEnsureSlot(redisArray *ar, uint64_t slice_id) {
599597
/* Initialize new entry */
600598
ar->superdir[pos].block_id = block_id;
601599
ar->superdir[pos].count = 0;
602-
ar->superdir[pos].slots = zcalloc(AR_SUPER_BLOCK_SLOTS * sizeof(arSlice *));
603-
arTrackAlloc(ar, ar->superdir[pos].slots);
600+
ar->superdir[pos].slots = arCallocAndTrack(ar, AR_SUPER_BLOCK_SLOTS * sizeof(arSlice *));
604601
ar->sdir_len++;
605602
}
606603

@@ -622,8 +619,7 @@ arSDirEntry *arSuperDirGetEntry(redisArray *ar, uint64_t slice_id) {
622619
* Frees the slice-pointer table, compacts remaining entries (keeping order by
623620
* block_id), and decrements ar->sdir_len. */
624621
void arSuperDirRemoveBlock(redisArray *ar, uint32_t pos) {
625-
arTrackFree(ar, ar->superdir[pos].slots);
626-
zfree(ar->superdir[pos].slots);
622+
arFreeAndTrack(ar, ar->superdir[pos].slots);
627623
if (pos < ar->sdir_len - 1) {
628624
memmove(ar->superdir + pos, ar->superdir + pos + 1,
629625
(ar->sdir_len - pos - 1) * sizeof(arSDirEntry));
@@ -636,14 +632,12 @@ void arSuperDirRemoveBlock(redisArray *ar, uint32_t pos) {
636632
void arPromoteToSuperDir(redisArray *ar) {
637633
ar->sdir_cap = 4;
638634
ar->sdir_len = 0;
639-
ar->superdir = zmalloc(ar->sdir_cap * sizeof(arSDirEntry));
640-
arTrackAlloc(ar, ar->superdir);
635+
ar->superdir = arAllocAndTrack(ar, ar->sdir_cap * sizeof(arSDirEntry));
641636

642637
/* Copy existing flat dir content into block 0 */
643638
if (ar->dir_alloc > 0) {
644639
ar->superdir[0].block_id = 0;
645-
ar->superdir[0].slots = zcalloc(AR_SUPER_BLOCK_SLOTS * sizeof(arSlice *));
646-
arTrackAlloc(ar, ar->superdir[0].slots);
640+
ar->superdir[0].slots = arCallocAndTrack(ar, AR_SUPER_BLOCK_SLOTS * sizeof(arSlice *));
647641
ar->superdir[0].count = 0;
648642
ar->sdir_len = 1;
649643

@@ -655,8 +649,7 @@ void arPromoteToSuperDir(redisArray *ar) {
655649
}
656650

657651
/* Free old flat directory */
658-
if (ar->dir) arTrackFree(ar, ar->dir);
659-
zfree(ar->dir);
652+
if (ar->dir) arFreeAndTrack(ar, ar->dir);
660653
ar->dir = NULL;
661654
ar->dir_alloc = 0;
662655
}
@@ -687,9 +680,7 @@ void arDirGrow(redisArray *ar, uint64_t slice_id) {
687680
new_alloc <<= 1;
688681
}
689682

690-
size_t old_size = ar->dir ? zmalloc_size(ar->dir) : 0;
691-
arSlice **new_dir = zrealloc(ar->dir, new_alloc * sizeof(arSlice *));
692-
arTrackRealloc(ar, old_size, new_dir);
683+
arSlice **new_dir = arReallocAndTrack(ar, ar->dir, new_alloc * sizeof(arSlice *));
693684

694685
/* Zero-fill new slots */
695686
memset(new_dir + ar->dir_alloc, 0, (new_alloc - ar->dir_alloc) * sizeof(arSlice *));
@@ -711,9 +702,7 @@ void arDirMaybeShrink(redisArray *ar) {
711702
while (new_alloc <= ar->dir_highest_used) new_alloc <<= 1;
712703
if (new_alloc >= ar->dir_alloc) return;
713704

714-
size_t old_size = zmalloc_size(ar->dir);
715-
ar->dir = zrealloc(ar->dir, new_alloc * sizeof(arSlice *));
716-
arTrackRealloc(ar, old_size, ar->dir);
705+
ar->dir = arReallocAndTrack(ar, ar->dir, new_alloc * sizeof(arSlice *));
717706
ar->dir_alloc = new_alloc;
718707
}
719708

@@ -1120,8 +1109,7 @@ void arFree(redisArray *ar) {
11201109
arSlice *arSliceDup(redisArray *dup_ar, arSlice *s) {
11211110
if (s->encoding == AR_SLICE_DENSE) {
11221111
size_t sz = arDenseAllocSize(s->layout.dense.winsize);
1123-
arSlice *nd = zmalloc(sz);
1124-
arTrackAlloc(dup_ar, nd);
1112+
arSlice *nd = arAllocAndTrack(dup_ar, sz);
11251113
memcpy(nd, s, sizeof(arSlice));
11261114
nd->layout.dense.items = (void **)(nd + 1);
11271115
memcpy(nd->layout.dense.items, s->layout.dense.items,
@@ -1137,8 +1125,7 @@ arSlice *arSliceDup(redisArray *dup_ar, arSlice *s) {
11371125
return nd;
11381126
} else {
11391127
size_t sz = arSparseAllocSize(s->layout.sparse.cap);
1140-
arSlice *nsp = zmalloc(sz);
1141-
arTrackAlloc(dup_ar, nsp);
1128+
arSlice *nsp = arAllocAndTrack(dup_ar, sz);
11421129
memcpy(nsp, s, sizeof(arSlice));
11431130
arSparseSetupPointers(nsp);
11441131
memcpy(nsp->layout.sparse.offsets, s->layout.sparse.offsets,
@@ -1174,17 +1161,15 @@ redisArray *arDup(redisArray *ar) {
11741161
if (ar->superdir) {
11751162
/* Superdir mode */
11761163
dup->dir = NULL;
1177-
dup->superdir = zmalloc(ar->sdir_cap * sizeof(arSDirEntry));
1178-
arTrackAlloc(dup, dup->superdir);
1164+
dup->superdir = arAllocAndTrack(dup, ar->sdir_cap * sizeof(arSDirEntry));
11791165

11801166
for (uint32_t i = 0; i < ar->sdir_len; i++) {
11811167
arSDirEntry *src = ar->superdir + i;
11821168
arSDirEntry *dst = dup->superdir + i;
11831169

11841170
dst->block_id = src->block_id;
11851171
dst->count = src->count;
1186-
dst->slots = zcalloc(AR_SUPER_BLOCK_SLOTS * sizeof(arSlice *));
1187-
arTrackAlloc(dup, dst->slots);
1172+
dst->slots = arCallocAndTrack(dup, AR_SUPER_BLOCK_SLOTS * sizeof(arSlice *));
11881173

11891174
for (uint32_t j = 0; j < AR_SUPER_BLOCK_SLOTS; j++) {
11901175
if (src->slots[j]) {
@@ -1195,8 +1180,7 @@ redisArray *arDup(redisArray *ar) {
11951180
} else if (ar->dir_alloc > 0) {
11961181
/* Flat mode */
11971182
dup->superdir = NULL;
1198-
dup->dir = zmalloc(ar->dir_alloc * sizeof(arSlice *));
1199-
arTrackAlloc(dup, dup->dir);
1183+
dup->dir = arAllocAndTrack(dup, ar->dir_alloc * sizeof(arSlice *));
12001184
memset(dup->dir, 0, ar->dir_alloc * sizeof(arSlice *));
12011185

12021186
for (uint64_t i = 0; i < ar->dir_alloc; i++) {
@@ -1329,8 +1313,7 @@ void arSet(redisArray *ar, uint64_t idx, void *v) {
13291313
* point in growing more than kmax, so we clamp to kmax. */
13301314
uint32_t new_cap = s->layout.sparse.cap * 2;
13311315
if (new_cap > ArraySparseKMax) new_cap = ArraySparseKMax;
1332-
arSlice *ns = zmalloc(arSparseAllocSize(new_cap));
1333-
arTrackAlloc(ar, ns);
1316+
arSlice *ns = arAllocAndTrack(ar, arSparseAllocSize(new_cap));
13341317
ns->encoding = AR_SLICE_SPARSE;
13351318
ns->count = s->count;
13361319
ns->layout.sparse.cap = new_cap;
@@ -1344,8 +1327,7 @@ void arSet(redisArray *ar, uint64_t idx, void *v) {
13441327
memcpy(new_offsets,old_offsets,s->count * sizeof(uint16_t));
13451328
memcpy(new_values,old_values,s->count * sizeof(void *));
13461329

1347-
arTrackFree(ar, s);
1348-
zfree(s);
1330+
arFreeAndTrack(ar, s);
13491331
s = ns;
13501332
arSetSlice(ar, slice_id, s);
13511333
offsets = new_offsets;

0 commit comments

Comments
 (0)