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 : #include "sql_string.h" 16 : #include "sql_keyword.h" 17 : 18 : #define HASH_SIZE 32768 19 : #define HASH_MASK (HASH_SIZE-1) 20 : 21 : static int keywords_init_done = 0; 22 : static keyword *keywords[HASH_SIZE]; 23 : 24 : static int 25 13758162 : keyword_key(char *k, int *l) 26 : { 27 13758162 : char *s = k; 28 13758162 : unsigned int h = 1; 29 : 30 82673448 : while (*k) { 31 68915286 : h <<= 5; 32 68915286 : h += (*k - 'a'); 33 68915286 : k++; 34 : } 35 13758162 : *l = (int) (k - s); 36 13758162 : h <<= 4; 37 13758162 : h += *l; 38 13758162 : return (int) ((h & 0x80000000) ? ~h + 1 : h); 39 : } 40 : 41 : int 42 145609 : keywords_insert(char *k, int token) 43 : { 44 145609 : keyword *kw = MNEW(keyword); 45 145609 : if(kw) { 46 145609 : int len = 0; 47 145609 : int bucket = keyword_key(k = toLower(k), &len) & HASH_MASK; 48 : #ifndef NDEBUG 49 : /* no duplicate keywords */ 50 145609 : keyword *kw2; 51 179040 : for (kw2 = keywords[bucket]; kw2; kw2 = kw2->next) 52 33431 : assert(strcmp(kw2->keyword, k) != 0); 53 : #endif 54 : 55 145609 : *kw = (keyword) { 56 : .keyword = k, 57 : .len = len, 58 : .token = token, 59 : .next = keywords[bucket], 60 : }; 61 145609 : keywords[bucket] = kw; 62 145609 : return 0; 63 : } else { 64 : return -1; 65 : } 66 : } 67 : 68 : keyword * 69 13612545 : find_keyword(char *text) 70 : { 71 13612545 : int len = 0; 72 13612545 : int bucket = keyword_key(mkLower(text), &len) & HASH_MASK; 73 13612547 : keyword *k = keywords[bucket]; 74 : 75 16467032 : while (k) { 76 11208848 : if (len == k->len && strcmp(k->keyword, text) == 0) 77 8354363 : return k; 78 : 79 2854485 : k = k->next; 80 : } 81 : return NULL; 82 : } 83 : 84 : int 85 10194 : keyword_exists(char *text) 86 : { 87 10194 : if (find_keyword(text)) { 88 6918 : return 1; 89 : } 90 : return 0; 91 : } 92 : 93 : void 94 331 : keyword_init(void) 95 : { 96 331 : int i; 97 : 98 331 : if (keywords_init_done) 99 : return; 100 331 : keywords_init_done = 1; 101 : 102 10846539 : for (i = 0; i < HASH_SIZE; i++) 103 10846208 : keywords[i] = NULL; 104 : } 105 : 106 : void 107 330 : keyword_exit(void) 108 : { 109 330 : int i; 110 : 111 330 : if (keywords_init_done == 0) 112 : return; 113 330 : keywords_init_done = 0; 114 : 115 10813770 : for (i = 0; i < HASH_SIZE; i++) { 116 10813440 : keyword *k = keywords[i]; 117 : 118 10813440 : while (k) { 119 145171 : keyword *l = k; 120 : 121 145171 : k = k->next; 122 145171 : _DELETE(l->keyword); 123 : 124 10958611 : _DELETE(l); 125 : } 126 : } 127 : }