LCOV - code coverage report
Current view: top level - sql/common - sql_mem.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 114 136 83.8 %
Date: 2021-10-13 02:24:04 Functions: 14 16 87.5 %

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

Generated by: LCOV version 1.14