LCOV - code coverage report
Current view: top level - sql/common - sql_mem.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 128 151 84.8 %
Date: 2024-04-25 20:03:45 Functions: 14 16 87.5 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #include "monetdb_config.h"
      14             : #include "sql_mem.h"
      15             : 
      16             : #define SA_BLOCK (64*1024)
      17             : 
      18             : sql_ref *
      19     3248377 : sql_ref_init(sql_ref *r)
      20             : {
      21     3248377 :         r->refcnt = 1;
      22     3248377 :         return r;
      23             : }
      24             : 
      25             : int
      26      579363 : sql_ref_inc(sql_ref *r)
      27             : {
      28      579363 :         assert(r->refcnt > 0);
      29      579363 :         return (++r->refcnt);
      30             : }
      31             : 
      32             : int
      33     1227425 : sql_ref_dec(sql_ref *r)
      34             : {
      35     1227425 :         assert(r->refcnt > 0);
      36     1227425 :         return (--r->refcnt);
      37             : }
      38             : 
      39             : typedef struct freed_t {
      40             :         struct freed_t *n;
      41             :         size_t sz;
      42             : } freed_t;
      43             : 
      44             : static void
      45       70362 : sa_destroy_freelist( freed_t *f )
      46             : {
      47       78546 :         while(f) {
      48        8184 :                 freed_t *n = f->n;
      49        8184 :                 GDKfree(f);
      50        8184 :                 f = n;
      51             :         }
      52       70362 : }
      53             : 
      54             : static void
      55      179628 : sa_free(sql_allocator *pa, void *blk)
      56             : {
      57      179628 :         assert(!pa->pa);
      58             :         size_t i;
      59             : 
      60    43515442 :         for(i = 0; i < pa->nr; i++) {
      61    43515442 :                 if (pa->blks[i] == blk)
      62             :                         break;
      63             :         }
      64      179628 :         assert (i < pa->nr);
      65     2177568 :         for (; i < pa->nr-1; i++)
      66     1997940 :                 pa->blks[i] = pa->blks[i+1];
      67      179628 :         pa->nr--;
      68             : 
      69      179628 :         size_t sz = GDKmallocated(blk);
      70      179628 :         if (sz > (SA_BLOCK + 32)) {
      71         100 :                 _DELETE(blk);
      72             :         } else {
      73      179528 :                 freed_t *f = blk;
      74      179528 :                 f->n = pa->freelist;
      75      179528 :                 f->sz = sz;
      76             : 
      77      179528 :                 pa->freelist = f;
      78             :         }
      79      179628 : }
      80             : 
      81             : static void *
      82      171344 : sa_use_freed(sql_allocator *pa, size_t sz)
      83             : {
      84      171344 :         (void)sz;
      85             : 
      86      171344 :         freed_t *f = pa->freelist;
      87      171344 :         pa->freelist = f->n;
      88      171344 :         return f;
      89             : }
      90             : 
      91             : sql_allocator *
      92      273101 : sa_create(sql_allocator *pa)
      93             : {
      94      273101 :         sql_allocator *sa = (pa)?SA_NEW(pa, sql_allocator):MNEW(sql_allocator);
      95      273099 :         if (sa == NULL)
      96             :                 return NULL;
      97      273099 :         eb_init(&sa->eb);
      98      273098 :         sa->pa = pa;
      99      273098 :         sa->size = 64;
     100      273098 :         sa->nr = 1;
     101      273098 :         sa->blks = pa?SA_NEW_ARRAY(pa, char*, sa->size):NEW_ARRAY(char*, sa->size);
     102      273098 :         sa->freelist = NULL;
     103      273098 :         if (sa->blks == NULL) {
     104           0 :                 if (!pa)
     105           0 :                         _DELETE(sa);
     106           0 :                 return NULL;
     107             :         }
     108      273098 :         sa->blks[0] = pa?SA_NEW_ARRAY(pa, char, SA_BLOCK):NEW_ARRAY(char, SA_BLOCK);
     109      273099 :         sa->usedmem = SA_BLOCK;
     110      273099 :         if (sa->blks[0] == NULL) {
     111           0 :                 if (!pa)
     112           0 :                         _DELETE(sa->blks);
     113           0 :                 if (!pa)
     114           0 :                         _DELETE(sa);
     115           0 :                 return NULL;
     116             :         }
     117      273099 :         sa->used = 0;
     118      273099 :         return sa;
     119             : }
     120             : 
     121     1828840 : sql_allocator *sa_reset( sql_allocator *sa )
     122             : {
     123     1828840 :         size_t i ;
     124             : 
     125     1882566 :         for (i = 1; i<sa->nr; i++) {
     126       53724 :                 if (!sa->pa)
     127           0 :                         _DELETE(sa->blks[i]);
     128             :                 else
     129       53724 :                         sa_free(sa->pa, sa->blks[i]);
     130             :         }
     131     1828842 :         sa->nr = 1;
     132     1828842 :         sa->used = 0;
     133     1828842 :         sa->usedmem = SA_BLOCK;
     134     1828842 :         return sa;
     135             : }
     136             : 
     137             : #undef sa_realloc
     138             : #undef sa_alloc
     139             : void *
     140          34 : sa_realloc( sql_allocator *sa, void *p, size_t sz, size_t oldsz )
     141             : {
     142          34 :         void *r = sa_alloc(sa, sz);
     143             : 
     144          34 :         if (r)
     145          34 :                 memcpy(r, p, oldsz);
     146          34 :         return r;
     147             : }
     148             : 
     149             : #define round16(sz) ((sz+15)&~15)
     150             : void *
     151   240205872 : sa_alloc( sql_allocator *sa, size_t sz )
     152             : {
     153   240205872 :         char *r;
     154   240205872 :         sz = round16(sz);
     155   240205872 :         if (sz > (SA_BLOCK-sa->used)) {
     156      491258 :                 if (sa->pa)
     157       53947 :                         r = SA_NEW_ARRAY(sa->pa,char,(sz > SA_BLOCK ? sz : SA_BLOCK));
     158      437311 :             else if (sz <= SA_BLOCK && sa->freelist) {
     159      171344 :                         r = sa_use_freed(sa, SA_BLOCK);
     160             :                 } else
     161      265967 :                         r = GDKmalloc(sz > SA_BLOCK ? sz : SA_BLOCK);
     162      491264 :                 if (r == NULL) {
     163           0 :                         if (sa->eb.enabled)
     164           0 :                                 eb_error(&sa->eb, "out of memory", 1000);
     165             :                         return NULL;
     166             :                 }
     167      491264 :                 if (sa->nr >= sa->size) {
     168         942 :                         char **tmp;
     169         942 :                         size_t osz = sa->size;
     170         942 :                         sa->size *=2;
     171         942 :                         if (sa->pa)
     172          20 :                                 tmp = SA_RENEW_ARRAY(sa->pa, char*, sa->blks, sa->size, osz);
     173             :                         else
     174         922 :                                 tmp = RENEW_ARRAY(char*, sa->blks, sa->size);
     175         942 :                         if (tmp == NULL) {
     176           0 :                                 sa->size /= 2; /* undo */
     177           0 :                                 if (sa->eb.enabled)
     178           0 :                                         eb_error(&sa->eb, "out of memory", 1000);
     179           0 :                                 if (!sa->pa)
     180           0 :                                         GDKfree(r);
     181           0 :                                 return NULL;
     182             :                         }
     183         942 :                         sa->blks = tmp;
     184             :                 }
     185      491264 :                 if (sz > SA_BLOCK) {
     186         214 :                         sa->blks[sa->nr] = sa->blks[sa->nr-1];
     187         214 :                         sa->blks[sa->nr-1] = r;
     188         214 :                         sa->nr ++;
     189         214 :                         sa->usedmem += sz;
     190             :                 } else {
     191      491050 :                         sa->blks[sa->nr] = r;
     192      491050 :                         sa->nr ++;
     193      491050 :                         sa->used = sz;
     194      491050 :                         sa->usedmem += SA_BLOCK;
     195             :                 }
     196             :         } else {
     197   239714614 :                 r = sa->blks[sa->nr-1] + sa->used;
     198   239714614 :                 sa->used += sz;
     199             :         }
     200             :         return r;
     201             : }
     202             : 
     203             : #undef sa_zalloc
     204    10004197 : void *sa_zalloc( sql_allocator *sa, size_t sz )
     205             : {
     206    10004197 :         void *r = sa_alloc(sa, sz);
     207             : 
     208    10004099 :         if (r)
     209    10004099 :                 memset(r, 0, sz);
     210    10004099 :         return r;
     211             : }
     212             : 
     213      196266 : void sa_destroy( sql_allocator *sa )
     214             : {
     215      196266 :         if (sa->pa) {
     216      125904 :                 sa_reset(sa);
     217      125904 :                 sa_free(sa->pa, sa->blks[0]);
     218      125904 :                 return;
     219             :         }
     220             : 
     221       70362 :         sa_destroy_freelist(sa->freelist);
     222      398406 :         for (size_t i = 0; i<sa->nr; i++) {
     223      328044 :                 GDKfree(sa->blks[i]);
     224             :         }
     225       70362 :         GDKfree(sa->blks);
     226       70362 :         GDKfree(sa);
     227             : }
     228             : 
     229             : #undef sa_strndup
     230    23365947 : char *sa_strndup( sql_allocator *sa, const char *s, size_t l)
     231             : {
     232    23365947 :         char *r = sa_alloc(sa, l+1);
     233             : 
     234    23365682 :         if (r) {
     235    23365682 :                 memcpy(r, s, l);
     236    23365682 :                 r[l] = 0;
     237             :         }
     238    23365682 :         return r;
     239             : }
     240             : 
     241             : #undef sa_strdup
     242    18124194 : char *sa_strdup( sql_allocator *sa, const char *s )
     243             : {
     244    18124194 :         return sa_strndup( sa, s, strlen(s));
     245             : }
     246             : 
     247       42020 : char *sa_strconcat( sql_allocator *sa, const char *s1, const char *s2 )
     248             : {
     249       42020 :         size_t l1 = strlen(s1);
     250       42020 :         size_t l2 = strlen(s2);
     251       42020 :         char *r = sa_alloc(sa, l1+l2+1);
     252             : 
     253       42020 :         if (l1)
     254       42020 :                 memcpy(r, s1, l1);
     255       42020 :         if (l2)
     256       42020 :                 memcpy(r+l1, s2, l2);
     257       42020 :         r[l1+l2] = 0;
     258       42020 :         return r;
     259             : }
     260             : 
     261           0 : size_t sa_size( sql_allocator *sa )
     262             : {
     263           0 :         return sa->usedmem;
     264             : }
     265             : 
     266             : void
     267           0 : c_delete( const void *p )
     268             : {
     269           0 :         void *xp = (void*)p;
     270             : 
     271           0 :         GDKfree(xp);
     272           0 : }

Generated by: LCOV version 1.14