~drizzle-trunk/drizzle/development

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
 *
4
 *  Copyright (C) 2008 Sun Microsystems
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 */