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 "client_priv.h"
24
#include <mystrings/m_string.h>
25
#undef SAFEMALLOC // Speed things up
26
#include "completion_hash.h"
28
uint hashpjw(const char *arKey, uint nKeyLength)
32
for (i = 0; i < nKeyLength; i++) {
33
h = (h << 4) + arKey[i];
34
if ((g = (h & 0xF0000000))) {
42
int completion_hash_init(HashTable *ht, uint nSize)
44
ht->arBuckets = (Bucket **) my_malloc(nSize* sizeof(Bucket *),
45
MYF(MY_ZEROFILL | MY_WME));
52
init_alloc_root(&ht->mem_root, 8192, 0);
53
ht->pHashFunction = hashpjw;
54
ht->nTableSize = nSize;
60
int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength,
67
h = ht->pHashFunction(arKey, nKeyLength);
68
nIndex = h % ht->nTableSize;
70
if (nKeyLength <= 0) {
73
p = ht->arBuckets[nIndex];
76
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
77
if (!memcmp(p->arKey, arKey, nKeyLength)) {
80
if (!(n = (entry *) alloc_root(&ht->mem_root,sizeof(entry))))
93
if (!(p = (Bucket *) alloc_root(&ht->mem_root, sizeof(Bucket))))
97
p->nKeyLength = nKeyLength;
100
if (!(p->pData = (entry*) alloc_root(&ht->mem_root, sizeof(entry))))
107
p->pNext = ht->arBuckets[nIndex];
108
ht->arBuckets[nIndex] = p;
113
static Bucket *completion_hash_find(HashTable *ht, const char *arKey,
119
h = ht->pHashFunction(arKey, nKeyLength);
120
nIndex = h % ht->nTableSize;
122
p = ht->arBuckets[nIndex];
125
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
126
if (!memcmp(p->arKey, arKey, nKeyLength)) {
136
int completion_hash_exists(HashTable *ht, char *arKey, uint nKeyLength)
141
h = ht->pHashFunction(arKey, nKeyLength);
142
nIndex = h % ht->nTableSize;
144
p = ht->arBuckets[nIndex];
147
if ((p->h == h) && (p->nKeyLength == nKeyLength))
149
if (!strcmp(p->arKey, arKey)) {
158
Bucket *find_all_matches(HashTable *ht, const char *str, uint length,
163
b = completion_hash_find(ht,str,length);
168
*res_length = length;
173
Bucket *find_longest_match(HashTable *ht, char *str, uint length,
181
b = completion_hash_find(ht,str,length);
192
while (s[lm]!=0 && (b=completion_hash_find(ht,s,lm+1))) {
193
if (b->count<count) {
205
void completion_hash_clean(HashTable *ht)
207
free_root(&ht->mem_root,MYF(0));
208
memset(ht->arBuckets, 0, ht->nTableSize*sizeof(Bucket *));
212
void completion_hash_free(HashTable *ht)
214
completion_hash_clean(ht);
215
my_free(ht->arBuckets, MYF(0));
219
void add_word(HashTable *ht,char *str)
223
for (i=1; *pos; i++, pos++)
224
completion_hash_update(ht, str, i, str);