520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
1 |
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
|
2 |
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
|
3 |
*
|
|
1999.6.1
by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file |
4 |
* Copyright (C) 2008 Sun Microsystems, Inc.
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
5 |
*
|
6 |
* This program is free software; you can redistribute it and/or modify
|
|
7 |
* it under the terms of the GNU General Public License as published by
|
|
8 |
* the Free Software Foundation; version 2 of the License.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
* GNU General Public License for more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License
|
|
16 |
* along with this program; if not, write to the Free Software
|
|
17 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18 |
*/
|
|
19 |
||
20 |
/* The hash functions used for saving keys */
|
|
1
by brian
clean slate |
21 |
/* One of key_length or key_length_offset must be given */
|
22 |
/* Key length of 0 isn't allowed */
|
|
23 |
||
1241.9.1
by Monty Taylor
Removed global.h. Fixed all the headers. |
24 |
#include "config.h" |
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
25 |
#include "drizzled/my_hash.h" |
26 |
#include "drizzled/charset.h" |
|
1241.9.61
by Monty Taylor
No more mystrings in drizzled/ |
27 |
#include "drizzled/charset_info.h" |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
28 |
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
29 |
namespace drizzled |
30 |
{
|
|
31 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
32 |
const uint32_t NO_RECORD= UINT32_MAX; |
33 |
||
34 |
const int LOWFIND= 1; |
|
35 |
const int LOWUSED= 2; |
|
36 |
const int HIGHFIND= 4; |
|
37 |
const int HIGHUSED= 8; |
|
1
by brian
clean slate |
38 |
|
39 |
typedef struct st_hash_info { |
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
40 |
/* index to next key */
|
41 |
uint32_t next; |
|
42 |
/* data for current entry */
|
|
43 |
unsigned char *data; |
|
1
by brian
clean slate |
44 |
} HASH_LINK; |
45 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
46 |
static uint32_t hash_mask(uint32_t hashnr, uint32_t buffmax, |
47 |
uint32_t maxlength); |
|
48 |
static void movelink(HASH_LINK *array, uint32_t pos, |
|
49 |
uint32_t next_link, uint32_t newlink); |
|
481
by Brian Aker
Remove all of uchar. |
50 |
static int hashcmp(const HASH *hash, HASH_LINK *pos, const unsigned char *key, |
1
by brian
clean slate |
51 |
size_t length); |
52 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
53 |
static uint32_t calc_hash(const HASH *hash, const unsigned char *key, |
54 |
size_t length) |
|
1
by brian
clean slate |
55 |
{
|
290
by Brian Aker
Update for ulong change over. |
56 |
uint32_t nr1=1, nr2=4; |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
57 |
hash->charset->coll->hash_sort(hash->charset, key,length, &nr1, &nr2); |
1
by brian
clean slate |
58 |
return nr1; |
59 |
}
|
|
60 |
||
146
by Brian Aker
my_bool cleanup. |
61 |
bool
|
482
by Brian Aker
Remove uint. |
62 |
_hash_init(HASH *hash,uint32_t growth_size, const CHARSET_INFO * const charset, |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
63 |
uint32_t size, size_t key_offset, size_t key_length, |
64 |
hash_get_key get_key, |
|
598.1.1
by Super-User
Fixed solaris build crap. |
65 |
hash_free_key free_element, uint32_t flags) |
1
by brian
clean slate |
66 |
{
|
67 |
hash->records=0; |
|
68 |
if (my_init_dynamic_array_ci(&hash->array, sizeof(HASH_LINK), size, |
|
69 |
growth_size)) |
|
70 |
{
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
71 |
/* Allow call to hash_free */
|
72 |
hash->free=0; |
|
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
73 |
return true; |
1
by brian
clean slate |
74 |
}
|
75 |
hash->key_offset=key_offset; |
|
76 |
hash->key_length=key_length; |
|
77 |
hash->blength=1; |
|
78 |
hash->get_key=get_key; |
|
79 |
hash->free=free_element; |
|
80 |
hash->flags=flags; |
|
81 |
hash->charset=charset; |
|
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
82 |
return false; |
1
by brian
clean slate |
83 |
}
|
84 |
||
85 |
||
86 |
/*
|
|
87 |
Call hash->free on all elements in hash.
|
|
88 |
||
89 |
SYNOPSIS
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
90 |
hash_free_elements()
|
91 |
hash hash table
|
|
1
by brian
clean slate |
92 |
|
93 |
NOTES:
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
94 |
Sets records to 0
|
1
by brian
clean slate |
95 |
*/
|
96 |
||
97 |
static inline void hash_free_elements(HASH *hash) |
|
98 |
{
|
|
99 |
if (hash->free) |
|
100 |
{
|
|
101 |
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*); |
|
102 |
HASH_LINK *end= data + hash->records; |
|
103 |
while (data < end) |
|
104 |
(*hash->free)((data++)->data); |
|
105 |
}
|
|
106 |
hash->records=0; |
|
107 |
}
|
|
108 |
||
109 |
||
110 |
/*
|
|
111 |
Free memory used by hash.
|
|
112 |
||
113 |
SYNOPSIS
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
114 |
hash_free()
|
115 |
hash the hash to delete elements of
|
|
1
by brian
clean slate |
116 |
|
117 |
NOTES: Hash can't be reused without calling hash_init again.
|
|
118 |
*/
|
|
119 |
||
120 |
void hash_free(HASH *hash) |
|
121 |
{
|
|
122 |
hash_free_elements(hash); |
|
123 |
hash->free= 0; |
|
124 |
delete_dynamic(&hash->array); |
|
125 |
}
|
|
126 |
||
127 |
/* some helper functions */
|
|
128 |
||
129 |
/*
|
|
481
by Brian Aker
Remove all of uchar. |
130 |
This function is char* instead of unsigned char* as HPUX11 compiler can't
|
1
by brian
clean slate |
131 |
handle inline functions that are not defined as native types
|
132 |
*/
|
|
133 |
||
134 |
static inline char* |
|
481
by Brian Aker
Remove all of uchar. |
135 |
hash_key(const HASH *hash, const unsigned char *record, size_t *length, |
146
by Brian Aker
my_bool cleanup. |
136 |
bool first) |
1
by brian
clean slate |
137 |
{
|
138 |
if (hash->get_key) |
|
139 |
return (char*) (*hash->get_key)(record,length,first); |
|
140 |
*length=hash->key_length; |
|
141 |
return (char*) record+hash->key_offset; |
|
142 |
}
|
|
143 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
144 |
/* Calculate pos according to keys */
|
1
by brian
clean slate |
145 |
|
482
by Brian Aker
Remove uint. |
146 |
static uint32_t hash_mask(uint32_t hashnr,uint32_t buffmax,uint32_t maxlength) |
1
by brian
clean slate |
147 |
{
|
148 |
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1)); |
|
149 |
return (hashnr & ((buffmax >> 1) -1)); |
|
150 |
}
|
|
151 |
||
482
by Brian Aker
Remove uint. |
152 |
static uint32_t hash_rec_mask(const HASH *hash, HASH_LINK *pos, |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
153 |
uint32_t buffmax, uint32_t maxlength) |
1
by brian
clean slate |
154 |
{
|
155 |
size_t length; |
|
481
by Brian Aker
Remove all of uchar. |
156 |
unsigned char *key= (unsigned char*) hash_key(hash,pos->data,&length,0); |
1
by brian
clean slate |
157 |
return hash_mask(calc_hash(hash,key,length),buffmax,maxlength); |
158 |
}
|
|
159 |
||
160 |
||
161 |
||
162 |
static
|
|
163 |
inline
|
|
481
by Brian Aker
Remove all of uchar. |
164 |
unsigned int rec_hashnr(HASH *hash,const unsigned char *record) |
1
by brian
clean slate |
165 |
{
|
166 |
size_t length; |
|
481
by Brian Aker
Remove all of uchar. |
167 |
unsigned char *key= (unsigned char*) hash_key(hash,record,&length,0); |
1
by brian
clean slate |
168 |
return calc_hash(hash,key,length); |
169 |
}
|
|
170 |
||
171 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
172 |
unsigned char* hash_search(const HASH *hash, const unsigned char *key, |
173 |
size_t length) |
|
1
by brian
clean slate |
174 |
{
|
175 |
HASH_SEARCH_STATE state; |
|
176 |
return hash_first(hash, key, length, &state); |
|
177 |
}
|
|
178 |
||
179 |
/*
|
|
180 |
Search after a record based on a key
|
|
181 |
||
182 |
NOTE
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
183 |
Assigns the number of the found record to HASH_SEARCH_STATE state
|
1
by brian
clean slate |
184 |
*/
|
185 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
186 |
unsigned char* hash_first(const HASH *hash, const unsigned char *key, |
187 |
size_t length, |
|
188 |
HASH_SEARCH_STATE *current_record) |
|
1
by brian
clean slate |
189 |
{
|
190 |
HASH_LINK *pos; |
|
482
by Brian Aker
Remove uint. |
191 |
uint32_t flag,idx; |
1
by brian
clean slate |
192 |
|
193 |
flag=1; |
|
194 |
if (hash->records) |
|
195 |
{
|
|
196 |
idx=hash_mask(calc_hash(hash,key,length ? length : hash->key_length), |
|
1138
by Brian Aker
Merge of Joe Daly's work |
197 |
hash->blength,hash->records); |
1
by brian
clean slate |
198 |
do
|
199 |
{
|
|
200 |
pos= dynamic_element(&hash->array,idx,HASH_LINK*); |
|
201 |
if (!hashcmp(hash,pos,key,length)) |
|
202 |
{
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
203 |
*current_record= idx; |
204 |
return (pos->data); |
|
1
by brian
clean slate |
205 |
}
|
206 |
if (flag) |
|
207 |
{
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
208 |
/* Reset flag */
|
209 |
flag=0; |
|
1138
by Brian Aker
Merge of Joe Daly's work |
210 |
if (hash_rec_mask(hash,pos,hash->blength,hash->records) != idx) |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
211 |
/* Wrong link */
|
212 |
break; |
|
1
by brian
clean slate |
213 |
}
|
214 |
}
|
|
215 |
while ((idx=pos->next) != NO_RECORD); |
|
216 |
}
|
|
217 |
*current_record= NO_RECORD; |
|
51.3.13
by Jay Pipes
Phase 1 removal of DBUG in mysys |
218 |
return(0); |
1
by brian
clean slate |
219 |
}
|
220 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
221 |
/* Get next record with identical key */
|
222 |
/* Can only be called if previous calls was hash_search */
|
|
1
by brian
clean slate |
223 |
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
224 |
unsigned char* hash_next(const HASH *hash, const unsigned char *key, |
225 |
size_t length, |
|
226 |
HASH_SEARCH_STATE *current_record) |
|
1
by brian
clean slate |
227 |
{
|
228 |
HASH_LINK *pos; |
|
482
by Brian Aker
Remove uint. |
229 |
uint32_t idx; |
1
by brian
clean slate |
230 |
|
231 |
if (*current_record != NO_RECORD) |
|
232 |
{
|
|
233 |
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*); |
|
234 |
for (idx=data[*current_record].next; idx != NO_RECORD ; idx=pos->next) |
|
235 |
{
|
|
236 |
pos=data+idx; |
|
237 |
if (!hashcmp(hash,pos,key,length)) |
|
238 |
{
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
239 |
*current_record= idx; |
240 |
return pos->data; |
|
1
by brian
clean slate |
241 |
}
|
242 |
}
|
|
243 |
*current_record= NO_RECORD; |
|
244 |
}
|
|
245 |
return 0; |
|
246 |
}
|
|
247 |
||
248 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
249 |
/* Change link from pos to new_link */
|
1
by brian
clean slate |
250 |
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
251 |
static void movelink(HASH_LINK *array, uint32_t find, |
252 |
uint32_t next_link, uint32_t newlink) |
|
1
by brian
clean slate |
253 |
{
|
254 |
HASH_LINK *old_link; |
|
255 |
do
|
|
256 |
{
|
|
257 |
old_link=array+next_link; |
|
258 |
}
|
|
259 |
while ((next_link=old_link->next) != find); |
|
260 |
old_link->next= newlink; |
|
261 |
return; |
|
262 |
}
|
|
263 |
||
264 |
/*
|
|
265 |
Compare a key in a record to a whole key. Return 0 if identical
|
|
266 |
||
267 |
SYNOPSIS
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
268 |
hashcmp()
|
269 |
hash hash table
|
|
270 |
pos position of hash record to use in comparison
|
|
271 |
key key for comparison
|
|
272 |
length length of key
|
|
1
by brian
clean slate |
273 |
|
274 |
NOTES:
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
275 |
If length is 0, comparison is done using the length of the
|
276 |
record being compared against.
|
|
1
by brian
clean slate |
277 |
|
278 |
RETURN
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
279 |
= 0 key of record == key
|
280 |
!= 0 key of record != key
|
|
281 |
*/
|
|
1
by brian
clean slate |
282 |
|
481
by Brian Aker
Remove all of uchar. |
283 |
static int hashcmp(const HASH *hash, HASH_LINK *pos, const unsigned char *key, |
1
by brian
clean slate |
284 |
size_t length) |
285 |
{
|
|
286 |
size_t rec_keylength; |
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
287 |
unsigned char *rec_key= (unsigned char*) hash_key(hash, pos->data, |
288 |
&rec_keylength,1); |
|
1
by brian
clean slate |
289 |
return ((length && length != rec_keylength) || |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
290 |
my_strnncoll(hash->charset, rec_key, rec_keylength, |
291 |
key, rec_keylength)); |
|
1
by brian
clean slate |
292 |
}
|
293 |
||
294 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
295 |
/* Write a hash-key to the hash-index */
|
1
by brian
clean slate |
296 |
|
481
by Brian Aker
Remove all of uchar. |
297 |
bool my_hash_insert(HASH *info,const unsigned char *record) |
1
by brian
clean slate |
298 |
{
|
299 |
int flag; |
|
300 |
size_t idx; |
|
482
by Brian Aker
Remove uint. |
301 |
uint32_t halfbuff,hash_nr,first_index; |
481
by Brian Aker
Remove all of uchar. |
302 |
unsigned char *ptr_to_rec=NULL,*ptr_to_rec2=NULL; |
77.1.71
by Monty Taylor
Uninitialized use. |
303 |
HASH_LINK *data,*empty,*gpos=NULL,*gpos2=NULL,*pos; |
1
by brian
clean slate |
304 |
|
305 |
if (HASH_UNIQUE & info->flags) |
|
306 |
{
|
|
481
by Brian Aker
Remove all of uchar. |
307 |
unsigned char *key= (unsigned char*) hash_key(info, record, &idx, 1); |
1
by brian
clean slate |
308 |
if (hash_search(info, key, idx)) |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
309 |
/* Duplicate entry */
|
310 |
return(true); |
|
1
by brian
clean slate |
311 |
}
|
312 |
||
313 |
flag=0; |
|
314 |
if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array))) |
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
315 |
/* No more memory */
|
316 |
return(true); |
|
1
by brian
clean slate |
317 |
|
318 |
data=dynamic_element(&info->array,0,HASH_LINK*); |
|
1138
by Brian Aker
Merge of Joe Daly's work |
319 |
halfbuff= info->blength >> 1; |
1
by brian
clean slate |
320 |
|
1138
by Brian Aker
Merge of Joe Daly's work |
321 |
idx= first_index= info->records-halfbuff; |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
322 |
/* If some records */
|
323 |
if (idx != info->records) |
|
1
by brian
clean slate |
324 |
{
|
325 |
do
|
|
326 |
{
|
|
327 |
pos=data+idx; |
|
328 |
hash_nr=rec_hashnr(info,pos->data); |
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
329 |
/* First loop; Check if ok */
|
330 |
if (flag == 0) |
|
1138
by Brian Aker
Merge of Joe Daly's work |
331 |
if (hash_mask(hash_nr,info->blength,info->records) != first_index) |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
332 |
break; |
1
by brian
clean slate |
333 |
if (!(hash_nr & halfbuff)) |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
334 |
{
|
335 |
/* Key will not move */
|
|
336 |
if (!(flag & LOWFIND)) |
|
337 |
{
|
|
338 |
if (flag & HIGHFIND) |
|
339 |
{
|
|
340 |
flag=LOWFIND | HIGHFIND; |
|
341 |
/* key shall be moved to the current empty position */
|
|
342 |
gpos=empty; |
|
343 |
ptr_to_rec=pos->data; |
|
344 |
/* This place is now free */
|
|
345 |
empty=pos; |
|
346 |
}
|
|
347 |
else
|
|
348 |
{
|
|
349 |
/* key isn't changed */
|
|
350 |
flag=LOWFIND | LOWUSED; |
|
351 |
gpos=pos; |
|
352 |
ptr_to_rec=pos->data; |
|
353 |
}
|
|
354 |
}
|
|
355 |
else
|
|
356 |
{
|
|
357 |
if (!(flag & LOWUSED)) |
|
358 |
{
|
|
359 |
/* Change link of previous LOW-key */
|
|
360 |
gpos->data=ptr_to_rec; |
|
895
by Brian Aker
Completion (?) of uint conversion. |
361 |
gpos->next= (uint32_t) (pos-data); |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
362 |
flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED); |
363 |
}
|
|
364 |
gpos=pos; |
|
365 |
ptr_to_rec=pos->data; |
|
366 |
}
|
|
1
by brian
clean slate |
367 |
}
|
368 |
else
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
369 |
{
|
370 |
/* key will be moved */
|
|
371 |
if (!(flag & HIGHFIND)) |
|
372 |
{
|
|
373 |
flag= (flag & LOWFIND) | HIGHFIND; |
|
374 |
/* key shall be moved to the last (empty) position */
|
|
375 |
gpos2 = empty; empty=pos; |
|
376 |
ptr_to_rec2=pos->data; |
|
377 |
}
|
|
378 |
else
|
|
379 |
{
|
|
380 |
if (!(flag & HIGHUSED)) |
|
381 |
{
|
|
382 |
/* Change link of previous hash-key and save */
|
|
383 |
gpos2->data=ptr_to_rec2; |
|
895
by Brian Aker
Completion (?) of uint conversion. |
384 |
gpos2->next=(uint32_t) (pos-data); |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
385 |
flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED); |
386 |
}
|
|
387 |
gpos2=pos; |
|
388 |
ptr_to_rec2=pos->data; |
|
389 |
}
|
|
1
by brian
clean slate |
390 |
}
|
391 |
}
|
|
392 |
while ((idx=pos->next) != NO_RECORD); |
|
393 |
||
394 |
if ((flag & (LOWFIND | LOWUSED)) == LOWFIND) |
|
395 |
{
|
|
396 |
gpos->data=ptr_to_rec; |
|
397 |
gpos->next=NO_RECORD; |
|
398 |
}
|
|
399 |
if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND) |
|
400 |
{
|
|
401 |
gpos2->data=ptr_to_rec2; |
|
402 |
gpos2->next=NO_RECORD; |
|
403 |
}
|
|
404 |
}
|
|
405 |
/* Check if we are at the empty position */
|
|
406 |
||
1138
by Brian Aker
Merge of Joe Daly's work |
407 |
idx=hash_mask(rec_hashnr(info,record),info->blength,info->records+1); |
1
by brian
clean slate |
408 |
pos=data+idx; |
409 |
if (pos == empty) |
|
410 |
{
|
|
481
by Brian Aker
Remove all of uchar. |
411 |
pos->data=(unsigned char*) record; |
1
by brian
clean slate |
412 |
pos->next=NO_RECORD; |
413 |
}
|
|
414 |
else
|
|
415 |
{
|
|
416 |
/* Check if more records in same hash-nr family */
|
|
417 |
empty[0]=pos[0]; |
|
1138
by Brian Aker
Merge of Joe Daly's work |
418 |
gpos=data+hash_rec_mask(info,pos,info->blength,info->records+1); |
1
by brian
clean slate |
419 |
if (pos == gpos) |
420 |
{
|
|
481
by Brian Aker
Remove all of uchar. |
421 |
pos->data=(unsigned char*) record; |
895
by Brian Aker
Completion (?) of uint conversion. |
422 |
pos->next=(uint32_t) (empty - data); |
1
by brian
clean slate |
423 |
}
|
424 |
else
|
|
425 |
{
|
|
481
by Brian Aker
Remove all of uchar. |
426 |
pos->data=(unsigned char*) record; |
1
by brian
clean slate |
427 |
pos->next=NO_RECORD; |
895
by Brian Aker
Completion (?) of uint conversion. |
428 |
movelink(data,(uint32_t) (pos-data),(uint32_t) (gpos-data),(uint32_t) (empty-data)); |
1
by brian
clean slate |
429 |
}
|
430 |
}
|
|
431 |
if (++info->records == info->blength) |
|
432 |
info->blength+= info->blength; |
|
433 |
return(0); |
|
434 |
}
|
|
435 |
||
436 |
||
437 |
/******************************************************************************
|
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
438 |
** Remove one record from hash-table. The record with the same record
|
439 |
** ptr is removed.
|
|
440 |
** if there is a free-function it's called for record if found
|
|
441 |
*****************************************************************************/
|
|
1
by brian
clean slate |
442 |
|
481
by Brian Aker
Remove all of uchar. |
443 |
bool hash_delete(HASH *hash,unsigned char *record) |
1
by brian
clean slate |
444 |
{
|
482
by Brian Aker
Remove uint. |
445 |
uint32_t blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index; |
1
by brian
clean slate |
446 |
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty; |
447 |
if (!hash->records) |
|
51.3.13
by Jay Pipes
Phase 1 removal of DBUG in mysys |
448 |
return(1); |
1
by brian
clean slate |
449 |
|
1138
by Brian Aker
Merge of Joe Daly's work |
450 |
blength=hash->blength; |
1
by brian
clean slate |
451 |
data=dynamic_element(&hash->array,0,HASH_LINK*); |
452 |
/* Search after record with key */
|
|
453 |
pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records); |
|
454 |
gpos = 0; |
|
455 |
||
456 |
while (pos->data != record) |
|
457 |
{
|
|
458 |
gpos=pos; |
|
459 |
if (pos->next == NO_RECORD) |
|
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
460 |
/* Key not found */
|
461 |
return(1); |
|
462 |
||
1
by brian
clean slate |
463 |
pos=data+pos->next; |
464 |
}
|
|
465 |
||
466 |
if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1; |
|
467 |
lastpos=data+hash->records; |
|
468 |
||
469 |
/* Remove link to record */
|
|
895
by Brian Aker
Completion (?) of uint conversion. |
470 |
empty=pos; empty_index=(uint32_t) (empty-data); |
1
by brian
clean slate |
471 |
if (gpos) |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
472 |
/* unlink current ptr */
|
473 |
gpos->next=pos->next; |
|
1
by brian
clean slate |
474 |
else if (pos->next != NO_RECORD) |
475 |
{
|
|
476 |
empty=data+(empty_index=pos->next); |
|
477 |
pos->data=empty->data; |
|
478 |
pos->next=empty->next; |
|
479 |
}
|
|
480 |
||
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
481 |
/* last key at wrong pos or no next link */
|
482 |
if (empty == lastpos) |
|
1
by brian
clean slate |
483 |
goto exit; |
484 |
||
485 |
/* Move the last key (lastpos) */
|
|
486 |
lastpos_hashnr=rec_hashnr(hash,lastpos->data); |
|
487 |
/* pos is where lastpos should be */
|
|
1138
by Brian Aker
Merge of Joe Daly's work |
488 |
pos=data+hash_mask(lastpos_hashnr,hash->blength,hash->records); |
520.7.1
by Monty Taylor
Moved hash.c to drizzled. |
489 |
/* Move to empty position. */
|
490 |
if (pos == empty) |
|
1
by brian
clean slate |
491 |
{
|
492 |
empty[0]=lastpos[0]; |
|
493 |
goto exit; |
|
494 |
}
|
|
495 |
pos_hashnr=rec_hashnr(hash,pos->data); |
|
496 |
/* pos3 is where the pos should be */
|
|
1138
by Brian Aker
Merge of Joe Daly's work |
497 |
pos3= data+hash_mask(pos_hashnr,hash->blength,hash->records); |
1
by brian
clean slate |
498 |
if (pos != pos3) |
499 |
{ /* pos is on wrong posit */ |
|
500 |
empty[0]=pos[0]; /* Save it here */ |
|
501 |
pos[0]=lastpos[0]; /* This should be here */ |
|
895
by Brian Aker
Completion (?) of uint conversion. |
502 |
movelink(data,(uint32_t) (pos-data),(uint32_t) (pos3-data),empty_index); |
1
by brian
clean slate |
503 |
goto exit; |
504 |
}
|
|
505 |
pos2= hash_mask(lastpos_hashnr,blength,hash->records+1); |
|
506 |
if (pos2 == hash_mask(pos_hashnr,blength,hash->records+1)) |
|
507 |
{ /* Identical key-positions */ |
|
508 |
if (pos2 != hash->records) |
|
509 |
{
|
|
510 |
empty[0]=lastpos[0]; |
|
895
by Brian Aker
Completion (?) of uint conversion. |
511 |
movelink(data,(uint32_t) (lastpos-data),(uint32_t) (pos-data),empty_index); |
1
by brian
clean slate |
512 |
goto exit; |
513 |
}
|
|
895
by Brian Aker
Completion (?) of uint conversion. |
514 |
idx= (uint32_t) (pos-data); /* Link pos->next after lastpos */ |
1
by brian
clean slate |
515 |
}
|
516 |
else idx= NO_RECORD; /* Different positions merge */ |
|
517 |
||
518 |
empty[0]=lastpos[0]; |
|
519 |
movelink(data,idx,empty_index,pos->next); |
|
520 |
pos->next=empty_index; |
|
521 |
||
522 |
exit: |
|
398.1.10
by Monty Taylor
Actually removed VOID() this time. |
523 |
pop_dynamic(&hash->array); |
1
by brian
clean slate |
524 |
if (hash->free) |
481
by Brian Aker
Remove all of uchar. |
525 |
(*hash->free)((unsigned char*) record); |
51.3.13
by Jay Pipes
Phase 1 removal of DBUG in mysys |
526 |
return(0); |
1
by brian
clean slate |
527 |
}
|
528 |
||
481
by Brian Aker
Remove all of uchar. |
529 |
unsigned char *hash_element(HASH *hash,uint32_t idx) |
1
by brian
clean slate |
530 |
{
|
531 |
if (idx < hash->records) |
|
532 |
return dynamic_element(&hash->array,idx,HASH_LINK*)->data; |
|
533 |
return 0; |
|
534 |
}
|
|
535 |
||
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
536 |
} /* namespace drizzled */ |