LCOV - code coverage report
Current view: top level - monetdb5/mal - mal_namespace.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 59 71 83.1 %
Date: 2024-04-25 20:03:45 Functions: 7 8 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             : /*
      14             :  * (author) M.L. Kersten
      15             :  */
      16             : #include "monetdb_config.h"
      17             : #include "mal_type.h"
      18             : #include "mal_namespace.h"
      19             : #include "mal_exception.h"
      20             : #include "mal_private.h"
      21             : 
      22             : #define MAXIDENTIFIERS 4096
      23             : #define HASHMASK  4095
      24             : 
      25             : MT_Lock mal_namespaceLock = MT_LOCK_INITIALIZER(mal_namespaceLock);
      26             : 
      27             : /* taken from gdk_atoms */
      28             : static inline size_t __attribute__((__pure__))
      29    90527242 :                 nme_hash(const char *key, size_t len)
      30             : {
      31    90527242 :         size_t y = 0;
      32             : 
      33   777315058 :         for (size_t i = 0; i < len && key[i]; i++) {
      34   686787816 :                 y += key[i];
      35   686787816 :                 y += (y << 10);
      36   686787816 :                 y ^= (y >> 6);
      37             :         }
      38    90527242 :         y += (y << 3);
      39    90527242 :         y ^= (y >> 11);
      40    90527242 :         y += (y << 15);
      41    90527242 :         return y & HASHMASK;
      42             : }
      43             : 
      44             : typedef struct NAME {
      45             :         struct NAME *next;
      46             :         char nme[IDLENGTH + 1];
      47             :         unsigned short length;
      48             : } *NamePtr;
      49             : 
      50             : static NamePtr hash[MAXIDENTIFIERS];
      51             : const char *optimizerRef;
      52             : const char *totalRef;
      53             : 
      54             : static struct namespace {
      55             :         struct namespace *next;
      56             :         int count;
      57             :         struct NAME data[4096];
      58             : } namespace1, *namespace = &namespace1;
      59             : 
      60             : void
      61         336 : initNamespace(void)
      62             : {
      63         336 :         optimizerRef = putName("optimizer");
      64         336 :         totalRef = putName("total");
      65         336 : }
      66             : 
      67             : void
      68         334 : mal_namespace_reset(void)
      69             : {
      70         334 :         struct namespace *ns;
      71             : 
      72             :         /* assume we are at the end of the server session */
      73         334 :         MT_lock_set(&mal_namespaceLock);
      74         334 :         memset(hash, 0, sizeof(hash));
      75         668 :         while (namespace) {
      76         334 :                 ns = namespace->next;
      77         334 :                 if (namespace != &namespace1)
      78           0 :                         GDKfree(namespace);
      79         334 :                 namespace = ns;
      80             :         }
      81         334 :         namespace1.count = 0;
      82         334 :         namespace1.next = NULL;
      83         334 :         namespace = &namespace1;
      84         334 :         MT_lock_unset(&mal_namespaceLock);
      85         334 : }
      86             : 
      87             : /*
      88             :  * Before a name is being stored we should check for its occurrence first.
      89             :  * The administration is initialized incrementally.
      90             :  * Beware, the routine getName relies on data structure maintenance that
      91             :  * is conflict free.
      92             :  */
      93             : 
      94             : static const char *
      95    90527586 : findName(const char *nme, size_t len, bool allocate)
      96             : {
      97    90527586 :         NamePtr *n, m;
      98    90527586 :         size_t key;
      99             : 
     100    90527586 :         assert(len == 0 || nme != NULL);
     101    90527586 :         if (len == 0 || nme == NULL)
     102             :                 return NULL;
     103    90527586 :         if (len > IDLENGTH) {
     104             :                 len = IDLENGTH;
     105             :         }
     106    90527586 :         key = nme_hash(nme, len);
     107    90527586 :         MT_lock_set(&mal_namespaceLock);
     108    96089894 :         for (n = &hash[key]; *n; n = &(*n)->next) {
     109    95755804 :                 if (len == (*n)->length && strncmp(nme, (*n)->nme, len) == 0) {
     110    90203751 :                         MT_lock_unset(&mal_namespaceLock);
     111    90203202 :                         return (*n)->nme;
     112             :                 }
     113             :         }
     114             :         /* item not found */
     115      334090 :         if (!allocate) {
     116           0 :                 MT_lock_unset(&mal_namespaceLock);
     117           0 :                 return NULL;
     118             :         }
     119      334090 :         if (namespace == NULL || namespace->count == 4096) {
     120           0 :                 struct namespace *ns = GDKmalloc(sizeof(struct namespace));
     121           0 :                 if (ns == NULL) {
     122           0 :                         MT_lock_unset(&mal_namespaceLock);
     123           0 :                         return NULL;
     124             :                 }
     125           0 :                 ns->next = namespace;
     126           0 :                 ns->count = 0;
     127           0 :                 namespace = ns;
     128             :         }
     129      334090 :         m = &namespace->data[namespace->count++];
     130      334090 :         strncpy(m->nme, nme, len);
     131      334090 :         m->nme[len] = 0;
     132      334090 :         m->length = (unsigned short) len;
     133      334090 :         m->next = *n;
     134      334090 :         *n = m;
     135      334090 :         MT_lock_unset(&mal_namespaceLock);
     136      334090 :         return m->nme;
     137             : }
     138             : 
     139             : const char *
     140    34443334 : getName(const char *nme)
     141             : {
     142    34443334 :         if (nme != NULL)
     143    33298952 :                 nme = findName(nme, strlen(nme), false);
     144    34445527 :         return nme;
     145             : }
     146             : 
     147             : const char *
     148           0 : getNameLen(const char *nme, size_t len)
     149             : {
     150           0 :         return findName(nme, len, false);
     151             : }
     152             : 
     153             : const char *
     154    57216025 : putName(const char *nme)
     155             : {
     156    57216025 :         if (nme != NULL)
     157    57216025 :                 nme = findName(nme, strlen(nme), true);
     158    57217822 :         return nme;
     159             : }
     160             : 
     161             : const char *
     162       18237 : putNameLen(const char *nme, size_t len)
     163             : {
     164       18237 :         return findName(nme, len, true);
     165             : }

Generated by: LCOV version 1.14