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