1
/* Copyright (C) 2000 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/* Quick & light hash implementation for tab completion purposes
18
* by Andi Gutmans <andi@zend.com>
19
* and Zeev Suraski <zeev@zend.com>
20
* Small portability changes by Monty. Changed also to use my_malloc/my_free
23
#include <my_global.h>
25
#undef SAFEMALLOC // Speed things up
27
#include "completion_hash.h"
29
uint hashpjw(const char *arKey, uint nKeyLength)
33
for (i = 0; i < nKeyLength; i++) {
34
h = (h << 4) + arKey[i];
35
if ((g = (h & 0xF0000000))) {
43
int completion_hash_init(HashTable *ht, uint nSize)
45
ht->arBuckets = (Bucket **) my_malloc(nSize* sizeof(Bucket *),
46
MYF(MY_ZEROFILL | MY_WME));
53
init_alloc_root(&ht->mem_root, 8192, 0);
54
ht->pHashFunction = hashpjw;
55
ht->nTableSize = nSize;
61
int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength,
68
h = ht->pHashFunction(arKey, nKeyLength);
69
nIndex = h % ht->nTableSize;
71
if (nKeyLength <= 0) {
74
p = ht->arBuckets[nIndex];
77
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
78
if (!memcmp(p->arKey, arKey, nKeyLength)) {
81
if (!(n = (entry *) alloc_root(&ht->mem_root,sizeof(entry))))
94
if (!(p = (Bucket *) alloc_root(&ht->mem_root, sizeof(Bucket))))
98
p->nKeyLength = nKeyLength;
101
if (!(p->pData = (entry*) alloc_root(&ht->mem_root, sizeof(entry))))
108
p->pNext = ht->arBuckets[nIndex];
109
ht->arBuckets[nIndex] = p;
114
static Bucket *completion_hash_find(HashTable *ht, const char *arKey,
120
h = ht->pHashFunction(arKey, nKeyLength);
121
nIndex = h % ht->nTableSize;
123
p = ht->arBuckets[nIndex];
126
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
127
if (!memcmp(p->arKey, arKey, nKeyLength)) {
137
int completion_hash_exists(HashTable *ht, char *arKey, uint nKeyLength)
142
h = ht->pHashFunction(arKey, nKeyLength);
143
nIndex = h % ht->nTableSize;
145
p = ht->arBuckets[nIndex];
148
if ((p->h == h) && (p->nKeyLength == nKeyLength))
150
if (!strcmp(p->arKey, arKey)) {
159
Bucket *find_all_matches(HashTable *ht, const char *str, uint length,
164
b = completion_hash_find(ht,str,length);
169
*res_length = length;
174
Bucket *find_longest_match(HashTable *ht, char *str, uint length,
182
b = completion_hash_find(ht,str,length);
193
while (s[lm]!=0 && (b=completion_hash_find(ht,s,lm+1))) {
194
if (b->count<count) {
206
void completion_hash_clean(HashTable *ht)
208
free_root(&ht->mem_root,MYF(0));
209
bzero((char*) ht->arBuckets,ht->nTableSize*sizeof(Bucket *));
213
void completion_hash_free(HashTable *ht)
215
completion_hash_clean(ht);
216
my_free(ht->arBuckets, MYF(0));
220
void add_word(HashTable *ht,char *str)
224
for (i=1; *pos; i++, pos++)
225
completion_hash_update(ht, str, i, str);