~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);
51.3.13 by Jay Pipes
Phase 1 removal of DBUG in mysys
125
  return;
1 by brian
clean slate
126
}
127
128
/* some helper functions */
129
130
/*
481 by Brian Aker
Remove all of uchar.
131
  This function is char* instead of unsigned char* as HPUX11 compiler can't
1 by brian
clean slate
132
  handle inline functions that are not defined as native types
133
*/
134
135
static inline char*
481 by Brian Aker
Remove all of uchar.
136
hash_key(const HASH *hash, const unsigned char *record, size_t *length,
146 by Brian Aker
my_bool cleanup.
137
         bool first)
1 by brian
clean slate
138
{
139
  if (hash->get_key)
140
    return (char*) (*hash->get_key)(record,length,first);
141
  *length=hash->key_length;
142
  return (char*) record+hash->key_offset;
143
}
144
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
145
/* Calculate pos according to keys */
1 by brian
clean slate
146
482 by Brian Aker
Remove uint.
147
static uint32_t hash_mask(uint32_t hashnr,uint32_t buffmax,uint32_t maxlength)
1 by brian
clean slate
148
{
149
  if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
150
  return (hashnr & ((buffmax >> 1) -1));
151
}
152
482 by Brian Aker
Remove uint.
153
static uint32_t hash_rec_mask(const HASH *hash, HASH_LINK *pos,
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
154
                              uint32_t buffmax, uint32_t maxlength)
1 by brian
clean slate
155
{
156
  size_t length;
481 by Brian Aker
Remove all of uchar.
157
  unsigned char *key= (unsigned char*) hash_key(hash,pos->data,&length,0);
1 by brian
clean slate
158
  return hash_mask(calc_hash(hash,key,length),buffmax,maxlength);
159
}
160
161
162
163
static
164
inline
481 by Brian Aker
Remove all of uchar.
165
unsigned int rec_hashnr(HASH *hash,const unsigned char *record)
1 by brian
clean slate
166
{
167
  size_t length;
481 by Brian Aker
Remove all of uchar.
168
  unsigned char *key= (unsigned char*) hash_key(hash,record,&length,0);
1 by brian
clean slate
169
  return calc_hash(hash,key,length);
170
}
171
172
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
173
unsigned char* hash_search(const HASH *hash, const unsigned char *key,
174
                           size_t length)
1 by brian
clean slate
175
{
176
  HASH_SEARCH_STATE state;
177
  return hash_first(hash, key, length, &state);
178
}
179
180
/*
181
  Search after a record based on a key
182
183
  NOTE
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
184
  Assigns the number of the found record to HASH_SEARCH_STATE state
1 by brian
clean slate
185
*/
186
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
187
unsigned char* hash_first(const HASH *hash, const unsigned char *key,
188
                          size_t length,
189
                          HASH_SEARCH_STATE *current_record)
1 by brian
clean slate
190
{
191
  HASH_LINK *pos;
482 by Brian Aker
Remove uint.
192
  uint32_t flag,idx;
1 by brian
clean slate
193
194
  flag=1;
195
  if (hash->records)
196
  {
197
    idx=hash_mask(calc_hash(hash,key,length ? length : hash->key_length),
1138 by Brian Aker
Merge of Joe Daly's work
198
                  hash->blength,hash->records);
1 by brian
clean slate
199
    do
200
    {
201
      pos= dynamic_element(&hash->array,idx,HASH_LINK*);
202
      if (!hashcmp(hash,pos,key,length))
203
      {
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
204
        *current_record= idx;
205
        return (pos->data);
1 by brian
clean slate
206
      }
207
      if (flag)
208
      {
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
209
        /* Reset flag */
210
        flag=0;
1138 by Brian Aker
Merge of Joe Daly's work
211
        if (hash_rec_mask(hash,pos,hash->blength,hash->records) != idx)
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
212
          /* Wrong link */
213
          break;
1 by brian
clean slate
214
      }
215
    }
216
    while ((idx=pos->next) != NO_RECORD);
217
  }
218
  *current_record= NO_RECORD;
51.3.13 by Jay Pipes
Phase 1 removal of DBUG in mysys
219
  return(0);
1 by brian
clean slate
220
}
221
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
222
/* Get next record with identical key */
223
/* Can only be called if previous calls was hash_search */
1 by brian
clean slate
224
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
225
unsigned char* hash_next(const HASH *hash, const unsigned char *key,
226
                         size_t length,
227
                         HASH_SEARCH_STATE *current_record)
1 by brian
clean slate
228
{
229
  HASH_LINK *pos;
482 by Brian Aker
Remove uint.
230
  uint32_t idx;
1 by brian
clean slate
231
232
  if (*current_record != NO_RECORD)
233
  {
234
    HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
235
    for (idx=data[*current_record].next; idx != NO_RECORD ; idx=pos->next)
236
    {
237
      pos=data+idx;
238
      if (!hashcmp(hash,pos,key,length))
239
      {
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
240
        *current_record= idx;
241
        return pos->data;
1 by brian
clean slate
242
      }
243
    }
244
    *current_record= NO_RECORD;
245
  }
246
  return 0;
247
}
248
249
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
250
/* Change link from pos to new_link */
1 by brian
clean slate
251
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
252
static void movelink(HASH_LINK *array, uint32_t find,
253
                     uint32_t next_link, uint32_t newlink)
1 by brian
clean slate
254
{
255
  HASH_LINK *old_link;
256
  do
257
  {
258
    old_link=array+next_link;
259
  }
260
  while ((next_link=old_link->next) != find);
261
  old_link->next= newlink;
262
  return;
263
}
264
265
/*
266
  Compare a key in a record to a whole key. Return 0 if identical
267
268
  SYNOPSIS
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
269
  hashcmp()
270
  hash   hash table
271
  pos    position of hash record to use in comparison
272
  key    key for comparison
273
  length length of key
1 by brian
clean slate
274
275
  NOTES:
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
276
  If length is 0, comparison is done using the length of the
277
  record being compared against.
1 by brian
clean slate
278
279
  RETURN
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
280
  = 0  key of record == key
281
  != 0 key of record != key
282
*/
1 by brian
clean slate
283
481 by Brian Aker
Remove all of uchar.
284
static int hashcmp(const HASH *hash, HASH_LINK *pos, const unsigned char *key,
1 by brian
clean slate
285
                   size_t length)
286
{
287
  size_t rec_keylength;
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
288
  unsigned char *rec_key= (unsigned char*) hash_key(hash, pos->data,
289
                                                    &rec_keylength,1);
1 by brian
clean slate
290
  return ((length && length != rec_keylength) ||
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
291
          my_strnncoll(hash->charset, rec_key, rec_keylength,
292
                       key, rec_keylength));
1 by brian
clean slate
293
}
294
295
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
296
/* Write a hash-key to the hash-index */
1 by brian
clean slate
297
481 by Brian Aker
Remove all of uchar.
298
bool my_hash_insert(HASH *info,const unsigned char *record)
1 by brian
clean slate
299
{
300
  int flag;
301
  size_t idx;
482 by Brian Aker
Remove uint.
302
  uint32_t halfbuff,hash_nr,first_index;
481 by Brian Aker
Remove all of uchar.
303
  unsigned char *ptr_to_rec=NULL,*ptr_to_rec2=NULL;
77.1.71 by Monty Taylor
Uninitialized use.
304
  HASH_LINK *data,*empty,*gpos=NULL,*gpos2=NULL,*pos;
1 by brian
clean slate
305
306
  if (HASH_UNIQUE & info->flags)
307
  {
481 by Brian Aker
Remove all of uchar.
308
    unsigned char *key= (unsigned char*) hash_key(info, record, &idx, 1);
1 by brian
clean slate
309
    if (hash_search(info, key, idx))
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
310
      /* Duplicate entry */
311
      return(true);
1 by brian
clean slate
312
  }
313
314
  flag=0;
315
  if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array)))
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
316
    /* No more memory */
317
    return(true);
1 by brian
clean slate
318
319
  data=dynamic_element(&info->array,0,HASH_LINK*);
1138 by Brian Aker
Merge of Joe Daly's work
320
  halfbuff= info->blength >> 1;
1 by brian
clean slate
321
1138 by Brian Aker
Merge of Joe Daly's work
322
  idx= first_index= info->records-halfbuff;
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
323
  /* If some records */
324
  if (idx != info->records)
1 by brian
clean slate
325
  {
326
    do
327
    {
328
      pos=data+idx;
329
      hash_nr=rec_hashnr(info,pos->data);
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
330
      /* First loop; Check if ok */
331
      if (flag == 0)
1138 by Brian Aker
Merge of Joe Daly's work
332
        if (hash_mask(hash_nr,info->blength,info->records) != first_index)
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
333
          break;
1 by brian
clean slate
334
      if (!(hash_nr & halfbuff))
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
335
      {
336
        /* Key will not move */
337
        if (!(flag & LOWFIND))
338
        {
339
          if (flag & HIGHFIND)
340
          {
341
            flag=LOWFIND | HIGHFIND;
342
            /* key shall be moved to the current empty position */
343
            gpos=empty;
344
            ptr_to_rec=pos->data;
345
            /* This place is now free */
346
            empty=pos;
347
          }
348
          else
349
          {
350
            /* key isn't changed */
351
            flag=LOWFIND | LOWUSED;
352
            gpos=pos;
353
            ptr_to_rec=pos->data;
354
          }
355
        }
356
        else
357
        {
358
          if (!(flag & LOWUSED))
359
          {
360
            /* Change link of previous LOW-key */
361
            gpos->data=ptr_to_rec;
895 by Brian Aker
Completion (?) of uint conversion.
362
            gpos->next= (uint32_t) (pos-data);
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
363
            flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED);
364
          }
365
          gpos=pos;
366
          ptr_to_rec=pos->data;
367
        }
1 by brian
clean slate
368
      }
369
      else
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
370
      {
371
        /* key will be moved */
372
        if (!(flag & HIGHFIND))
373
        {
374
          flag= (flag & LOWFIND) | HIGHFIND;
375
          /* key shall be moved to the last (empty) position */
376
          gpos2 = empty; empty=pos;
377
          ptr_to_rec2=pos->data;
378
        }
379
        else
380
        {
381
          if (!(flag & HIGHUSED))
382
          {
383
            /* Change link of previous hash-key and save */
384
            gpos2->data=ptr_to_rec2;
895 by Brian Aker
Completion (?) of uint conversion.
385
            gpos2->next=(uint32_t) (pos-data);
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
386
            flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED);
387
          }
388
          gpos2=pos;
389
          ptr_to_rec2=pos->data;
390
        }
1 by brian
clean slate
391
      }
392
    }
393
    while ((idx=pos->next) != NO_RECORD);
394
395
    if ((flag & (LOWFIND | LOWUSED)) == LOWFIND)
396
    {
397
      gpos->data=ptr_to_rec;
398
      gpos->next=NO_RECORD;
399
    }
400
    if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND)
401
    {
402
      gpos2->data=ptr_to_rec2;
403
      gpos2->next=NO_RECORD;
404
    }
405
  }
406
  /* Check if we are at the empty position */
407
1138 by Brian Aker
Merge of Joe Daly's work
408
  idx=hash_mask(rec_hashnr(info,record),info->blength,info->records+1);
1 by brian
clean slate
409
  pos=data+idx;
410
  if (pos == empty)
411
  {
481 by Brian Aker
Remove all of uchar.
412
    pos->data=(unsigned char*) record;
1 by brian
clean slate
413
    pos->next=NO_RECORD;
414
  }
415
  else
416
  {
417
    /* Check if more records in same hash-nr family */
418
    empty[0]=pos[0];
1138 by Brian Aker
Merge of Joe Daly's work
419
    gpos=data+hash_rec_mask(info,pos,info->blength,info->records+1);
1 by brian
clean slate
420
    if (pos == gpos)
421
    {
481 by Brian Aker
Remove all of uchar.
422
      pos->data=(unsigned char*) record;
895 by Brian Aker
Completion (?) of uint conversion.
423
      pos->next=(uint32_t) (empty - data);
1 by brian
clean slate
424
    }
425
    else
426
    {
481 by Brian Aker
Remove all of uchar.
427
      pos->data=(unsigned char*) record;
1 by brian
clean slate
428
      pos->next=NO_RECORD;
895 by Brian Aker
Completion (?) of uint conversion.
429
      movelink(data,(uint32_t) (pos-data),(uint32_t) (gpos-data),(uint32_t) (empty-data));
1 by brian
clean slate
430
    }
431
  }
432
  if (++info->records == info->blength)
433
    info->blength+= info->blength;
434
  return(0);
435
}
436
437
438
/******************************************************************************
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
439
 ** Remove one record from hash-table. The record with the same record
440
 ** ptr is removed.
441
 ** if there is a free-function it's called for record if found
442
 *****************************************************************************/
1 by brian
clean slate
443
481 by Brian Aker
Remove all of uchar.
444
bool hash_delete(HASH *hash,unsigned char *record)
1 by brian
clean slate
445
{
482 by Brian Aker
Remove uint.
446
  uint32_t blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
1 by brian
clean slate
447
  HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
448
  if (!hash->records)
51.3.13 by Jay Pipes
Phase 1 removal of DBUG in mysys
449
    return(1);
1 by brian
clean slate
450
1138 by Brian Aker
Merge of Joe Daly's work
451
  blength=hash->blength;
1 by brian
clean slate
452
  data=dynamic_element(&hash->array,0,HASH_LINK*);
453
  /* Search after record with key */
454
  pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records);
455
  gpos = 0;
456
457
  while (pos->data != record)
458
  {
459
    gpos=pos;
460
    if (pos->next == NO_RECORD)
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
461
      /* Key not found */
462
      return(1);
463
1 by brian
clean slate
464
    pos=data+pos->next;
465
  }
466
467
  if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1;
468
  lastpos=data+hash->records;
469
470
  /* Remove link to record */
895 by Brian Aker
Completion (?) of uint conversion.
471
  empty=pos; empty_index=(uint32_t) (empty-data);
1 by brian
clean slate
472
  if (gpos)
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
473
    /* unlink current ptr */
474
    gpos->next=pos->next;
1 by brian
clean slate
475
  else if (pos->next != NO_RECORD)
476
  {
477
    empty=data+(empty_index=pos->next);
478
    pos->data=empty->data;
479
    pos->next=empty->next;
480
  }
481
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
482
  /* last key at wrong pos or no next link */
483
  if (empty == lastpos)
1 by brian
clean slate
484
    goto exit;
485
486
  /* Move the last key (lastpos) */
487
  lastpos_hashnr=rec_hashnr(hash,lastpos->data);
488
  /* pos is where lastpos should be */
1138 by Brian Aker
Merge of Joe Daly's work
489
  pos=data+hash_mask(lastpos_hashnr,hash->blength,hash->records);
520.7.1 by Monty Taylor
Moved hash.c to drizzled.
490
  /* Move to empty position. */
491
  if (pos == empty)
1 by brian
clean slate
492
  {
493
    empty[0]=lastpos[0];
494
    goto exit;
495
  }
496
  pos_hashnr=rec_hashnr(hash,pos->data);
497
  /* pos3 is where the pos should be */
1138 by Brian Aker
Merge of Joe Daly's work
498
  pos3= data+hash_mask(pos_hashnr,hash->blength,hash->records);
1 by brian
clean slate
499
  if (pos != pos3)
500
  {					/* pos is on wrong posit */
501
    empty[0]=pos[0];			/* Save it here */
502
    pos[0]=lastpos[0];			/* This should be here */
895 by Brian Aker
Completion (?) of uint conversion.
503
    movelink(data,(uint32_t) (pos-data),(uint32_t) (pos3-data),empty_index);
1 by brian
clean slate
504
    goto exit;
505
  }
506
  pos2= hash_mask(lastpos_hashnr,blength,hash->records+1);
507
  if (pos2 == hash_mask(pos_hashnr,blength,hash->records+1))
508
  {					/* Identical key-positions */
509
    if (pos2 != hash->records)
510
    {
511
      empty[0]=lastpos[0];
895 by Brian Aker
Completion (?) of uint conversion.
512
      movelink(data,(uint32_t) (lastpos-data),(uint32_t) (pos-data),empty_index);
1 by brian
clean slate
513
      goto exit;
514
    }
895 by Brian Aker
Completion (?) of uint conversion.
515
    idx= (uint32_t) (pos-data);		/* Link pos->next after lastpos */
1 by brian
clean slate
516
  }
517
  else idx= NO_RECORD;		/* Different positions merge */
518
519
  empty[0]=lastpos[0];
520
  movelink(data,idx,empty_index,pos->next);
521
  pos->next=empty_index;
522
523
exit:
398.1.10 by Monty Taylor
Actually removed VOID() this time.
524
  pop_dynamic(&hash->array);
1 by brian
clean slate
525
  if (hash->free)
481 by Brian Aker
Remove all of uchar.
526
    (*hash->free)((unsigned char*) record);
51.3.13 by Jay Pipes
Phase 1 removal of DBUG in mysys
527
  return(0);
1 by brian
clean slate
528
}
529
481 by Brian Aker
Remove all of uchar.
530
unsigned char *hash_element(HASH *hash,uint32_t idx)
1 by brian
clean slate
531
{
532
  if (idx < hash->records)
533
    return dynamic_element(&hash->array,idx,HASH_LINK*)->data;
534
  return 0;
535
}
536
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
537
} /* namespace drizzled */