~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/heap/hp_hash.c

Removed DBUG symbols and fixed TRUE/FALSE

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
/* The hash functions used for saveing keys */
17
17
 
18
18
#include "heapdef.h"
19
 
#include <mystrings/m_ctype.h>
20
 
#include <drizzled/util/test.h>
 
19
#include <m_ctype.h>
 
20
 
21
21
 
22
22
 
23
23
/*
53
53
  HP_KEYDEF *keyinfo= info->s->keydef + inx;
54
54
  TREE *rb_tree = &keyinfo->rb_tree;
55
55
  heap_rb_param custom_arg;
 
56
  DBUG_ENTER("hp_rb_records_in_range");
56
57
 
57
58
  info->lastinx= inx;
58
59
  custom_arg.keyseg= keyinfo->seg;
59
60
  custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
60
61
  if (min_key)
61
62
  {
62
 
    custom_arg.key_length= hp_rb_pack_key(keyinfo, (unsigned char*) info->recbuf,
63
 
                                          (unsigned char*) min_key->key,
 
63
    custom_arg.key_length= hp_rb_pack_key(keyinfo, (uchar*) info->recbuf,
 
64
                                          (uchar*) min_key->key,
64
65
                                          min_key->keypart_map);
65
66
    start_pos= tree_record_pos(rb_tree, info->recbuf, min_key->flag,
66
67
                               &custom_arg);
72
73
 
73
74
  if (max_key)
74
75
  {
75
 
    custom_arg.key_length= hp_rb_pack_key(keyinfo, (unsigned char*) info->recbuf,
76
 
                                          (unsigned char*) max_key->key,
 
76
    custom_arg.key_length= hp_rb_pack_key(keyinfo, (uchar*) info->recbuf,
 
77
                                          (uchar*) max_key->key,
77
78
                                          max_key->keypart_map);
78
79
    end_pos= tree_record_pos(rb_tree, info->recbuf, max_key->flag,
79
80
                             &custom_arg);
83
84
    end_pos= rb_tree->elements_in_tree + (ha_rows)1;
84
85
  }
85
86
 
 
87
  DBUG_PRINT("info",("start_pos: %lu  end_pos: %lu", (ulong) start_pos,
 
88
                     (ulong) end_pos));
86
89
  if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
87
 
    return(HA_POS_ERROR);
88
 
  return(end_pos < start_pos ? (ha_rows) 0 :
 
90
    DBUG_RETURN(HA_POS_ERROR);
 
91
  DBUG_RETURN(end_pos < start_pos ? (ha_rows) 0 :
89
92
              (end_pos == start_pos ? (ha_rows) 1 : end_pos - start_pos));
90
93
}
91
94
 
94
97
        /* Sets info->current_ptr to found record */
95
98
        /* next_flag:  Search=0, next=1, prev =2, same =3 */
96
99
 
97
 
unsigned char *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const unsigned char *key,
98
 
                uint32_t nextflag)
 
100
uchar *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key,
 
101
                uint nextflag)
99
102
{
100
103
  register HASH_INFO *pos,*prev_ptr;
101
104
  int flag;
102
 
  uint32_t old_nextflag;
 
105
  uint old_nextflag;
103
106
  HP_SHARE *share=info->s;
 
107
  DBUG_ENTER("hp_search");
104
108
  old_nextflag=nextflag;
105
109
  flag=1;
106
110
  prev_ptr=0;
115
119
      {
116
120
        switch (nextflag) {
117
121
        case 0:                                 /* Search after key */
 
122
          DBUG_PRINT("exit", ("found key at 0x%lx", (long) pos->ptr_to_rec));
118
123
          info->current_hash_ptr=pos;
119
 
          return(info->current_ptr= pos->ptr_to_rec);
 
124
          DBUG_RETURN(info->current_ptr= pos->ptr_to_rec);
120
125
        case 1:                                 /* Search next */
121
126
          if (pos->ptr_to_rec == info->current_ptr)
122
127
            nextflag=0;
126
131
          {
127
132
            my_errno=HA_ERR_KEY_NOT_FOUND;      /* If gpos == 0 */
128
133
            info->current_hash_ptr=prev_ptr;
129
 
            return(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0);
 
134
            DBUG_RETURN(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0);
130
135
          }
131
136
          prev_ptr=pos;                         /* Prev. record found */
132
137
          break;
134
139
          if (pos->ptr_to_rec == info->current_ptr)
135
140
          {
136
141
            info->current_hash_ptr=pos;
137
 
            return(info->current_ptr);
 
142
            DBUG_RETURN(info->current_ptr);
138
143
          }
139
144
        }
140
145
      }
154
159
  {
155
160
    /* Do a previous from end */
156
161
    info->current_hash_ptr=prev_ptr;
157
 
    return(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0);
 
162
    DBUG_RETURN(info->current_ptr=prev_ptr ? prev_ptr->ptr_to_rec : 0);
158
163
  }
159
164
 
160
165
  if (old_nextflag && nextflag)
161
166
    my_errno=HA_ERR_RECORD_CHANGED;             /* Didn't find old record */
 
167
  DBUG_PRINT("exit",("Error: %d",my_errno));
162
168
  info->current_hash_ptr=0;  
163
 
  return((info->current_ptr= 0));
 
169
  DBUG_RETURN((info->current_ptr= 0));
164
170
}
165
171
 
166
172
 
169
175
  since last read !
170
176
*/
171
177
 
172
 
unsigned char *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const unsigned char *key,
 
178
uchar *hp_search_next(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *key,
173
179
                      HASH_INFO *pos)
174
180
{
 
181
  DBUG_ENTER("hp_search_next");
 
182
 
175
183
  while ((pos= pos->next_key))
176
184
  {
177
185
    if (! hp_key_cmp(keyinfo, pos->ptr_to_rec, key))
178
186
    {
179
187
      info->current_hash_ptr=pos;
180
 
      return (info->current_ptr= pos->ptr_to_rec);
 
188
      DBUG_RETURN (info->current_ptr= pos->ptr_to_rec);
181
189
    }
182
190
  }
183
191
  my_errno=HA_ERR_KEY_NOT_FOUND;
 
192
  DBUG_PRINT("exit",("Error: %d",my_errno));
184
193
  info->current_hash_ptr=0;
185
 
  return ((info->current_ptr= 0));
 
194
  DBUG_RETURN ((info->current_ptr= 0));
186
195
}
187
196
 
188
197
 
199
208
    Array index, in [0..maxlength)
200
209
*/
201
210
 
202
 
uint32_t hp_mask(uint32_t hashnr, uint32_t buffmax, uint32_t maxlength)
 
211
ulong hp_mask(ulong hashnr, ulong buffmax, ulong maxlength)
203
212
{
204
213
  if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
205
214
  return (hashnr & ((buffmax >> 1) -1));
229
238
 
230
239
        /* Calc hashvalue for a key */
231
240
 
232
 
uint32_t hp_hashnr(register HP_KEYDEF *keydef, register const unsigned char *key)
 
241
ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key)
233
242
{
234
243
  /*register*/ 
235
 
  uint32_t nr=1, nr2=4;
 
244
  ulong nr=1, nr2=4;
236
245
  HA_KEYSEG *seg,*endseg;
237
246
 
238
247
  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
239
248
  {
240
 
    unsigned char *pos=(unsigned char*) key;
 
249
    uchar *pos=(uchar*) key;
241
250
    key+=seg->length;
242
251
    if (seg->null_bit)
243
252
    {
254
263
    }
255
264
    if (seg->type == HA_KEYTYPE_TEXT)
256
265
    {
257
 
       const CHARSET_INFO * const cs= seg->charset;
258
 
       uint32_t length= seg->length;
 
266
       CHARSET_INFO *cs= seg->charset;
 
267
       uint length= seg->length;
259
268
       if (cs->mbmaxlen > 1)
260
269
       {
261
 
         uint32_t char_length;
 
270
         uint char_length;
262
271
         char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen);
263
272
         set_if_smaller(length, char_length);
264
273
       }
266
275
    }
267
276
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
268
277
    {
269
 
       const CHARSET_INFO * const cs= seg->charset;
270
 
       uint32_t pack_length= 2;                     /* Key packing is constant */
271
 
       uint32_t length= uint2korr(pos);
 
278
       CHARSET_INFO *cs= seg->charset;
 
279
       uint pack_length= 2;                     /* Key packing is constant */
 
280
       uint length= uint2korr(pos);
272
281
       if (cs->mbmaxlen > 1)
273
282
       {
274
 
         uint32_t char_length;
 
283
         uint char_length;
275
284
         char_length= my_charpos(cs, pos +pack_length,
276
285
                                 pos +pack_length + length,
277
286
                                 seg->length/cs->mbmaxlen);
282
291
    }
283
292
    else
284
293
    {
285
 
      for (; pos < (unsigned char*) key ; pos++)
 
294
      for (; pos < (uchar*) key ; pos++)
286
295
      {
287
 
        nr^=(uint32_t) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8);
 
296
        nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8);
288
297
        nr2+=3;
289
298
      }
290
299
    }
291
300
  }
292
 
  return((uint32_t) nr);
 
301
  DBUG_PRINT("exit", ("hash: 0x%lx", nr));
 
302
  return((ulong) nr);
293
303
}
294
304
 
295
305
        /* Calc hashvalue for a key in a record */
296
306
 
297
 
uint32_t hp_rec_hashnr(register HP_KEYDEF *keydef, register const unsigned char *rec)
 
307
ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
298
308
{
299
 
  uint32_t nr=1, nr2=4;
 
309
  ulong nr=1, nr2=4;
300
310
  HA_KEYSEG *seg,*endseg;
301
311
 
302
312
  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
303
313
  {
304
 
    unsigned char *pos=(unsigned char*) rec+seg->start,*end=pos+seg->length;
 
314
    uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length;
305
315
    if (seg->null_bit)
306
316
    {
307
317
      if (rec[seg->null_pos] & seg->null_bit)
312
322
    }
313
323
    if (seg->type == HA_KEYTYPE_TEXT)
314
324
    {
315
 
      const CHARSET_INFO * const cs= seg->charset;
316
 
      uint32_t char_length= seg->length;
 
325
      CHARSET_INFO *cs= seg->charset;
 
326
      uint char_length= seg->length;
317
327
      if (cs->mbmaxlen > 1)
318
328
      {
319
329
        char_length= my_charpos(cs, pos, pos + char_length,
324
334
    }
325
335
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
326
336
    {
327
 
      const CHARSET_INFO * const cs= seg->charset;
328
 
      uint32_t pack_length= seg->bit_start;
329
 
      uint32_t length= (pack_length == 1 ? (uint) *(unsigned char*) pos : uint2korr(pos));
 
337
      CHARSET_INFO *cs= seg->charset;
 
338
      uint pack_length= seg->bit_start;
 
339
      uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
330
340
      if (cs->mbmaxlen > 1)
331
341
      {
332
 
        uint32_t char_length;
 
342
        uint char_length;
333
343
        char_length= my_charpos(cs, pos + pack_length,
334
344
                                pos + pack_length + length,
335
345
                                seg->length/cs->mbmaxlen);
341
351
    {
342
352
      for (; pos < end ; pos++)
343
353
      {
344
 
        nr^=(uint32_t) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
 
354
        nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
345
355
        nr2+=3;
346
356
      }
347
357
    }
348
358
  }
 
359
  DBUG_PRINT("exit", ("hash: 0x%lx", nr));
349
360
  return(nr);
350
361
}
351
362
 
366
377
 * far, and works well on both numbers and strings.
367
378
 */
368
379
 
369
 
uint32_t hp_hashnr(register HP_KEYDEF *keydef, register const unsigned char *key)
 
380
ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key)
370
381
{
371
382
  /*
372
383
    Note, if a key consists of a combination of numeric and
374
385
    Making text columns work with NEW_HASH_FUNCTION
375
386
    needs also changes in strings/ctype-xxx.c.
376
387
  */
377
 
  uint32_t nr= 1, nr2= 4;
 
388
  ulong nr= 1, nr2= 4;
378
389
  HA_KEYSEG *seg,*endseg;
379
390
 
380
391
  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
381
392
  {
382
 
    unsigned char *pos=(unsigned char*) key;
 
393
    uchar *pos=(uchar*) key;
383
394
    key+=seg->length;
384
395
    if (seg->null_bit)
385
396
    {
396
407
    }
397
408
    if (seg->type == HA_KEYTYPE_TEXT)
398
409
    {
399
 
      seg->charset->coll->hash_sort(seg->charset, pos, ((unsigned char*)key)-pos,
 
410
      seg->charset->coll->hash_sort(seg->charset, pos, ((uchar*)key)-pos,
400
411
                                    &nr, &nr2);
401
412
    }
402
413
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
403
414
    {
404
 
      uint32_t pack_length= 2;                      /* Key packing is constant */
405
 
      uint32_t length= uint2korr(pos);
 
415
      uint pack_length= 2;                      /* Key packing is constant */
 
416
      uint length= uint2korr(pos);
406
417
      seg->charset->coll->hash_sort(seg->charset, pos+pack_length, length,
407
418
                                    &nr, &nr2);
408
419
      key+= pack_length;
409
420
    }
410
421
    else
411
422
    {
412
 
      for ( ; pos < (unsigned char*) key ; pos++)
 
423
      for ( ; pos < (uchar*) key ; pos++)
413
424
      {
414
425
        nr *=16777619; 
415
426
        nr ^=(uint) *pos;
416
427
      }
417
428
    }
418
429
  }
 
430
  DBUG_PRINT("exit", ("hash: 0x%lx", nr));
419
431
  return(nr);
420
432
}
421
433
 
422
434
        /* Calc hashvalue for a key in a record */
423
435
 
424
 
uint32_t hp_rec_hashnr(register HP_KEYDEF *keydef, register const unsigned char *rec)
 
436
ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
425
437
{
426
 
  uint32_t nr= 1, nr2= 4;
 
438
  ulong nr= 1, nr2= 4;
427
439
  HA_KEYSEG *seg,*endseg;
428
440
 
429
441
  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
430
442
  {
431
 
    unsigned char *pos=(unsigned char*) rec+seg->start;
 
443
    uchar *pos=(uchar*) rec+seg->start;
432
444
    if (seg->null_bit)
433
445
    {
434
446
      if (rec[seg->null_pos] & seg->null_bit)
439
451
    }
440
452
    if (seg->type == HA_KEYTYPE_TEXT)
441
453
    {
442
 
      uint32_t char_length= seg->length; /* TODO: fix to use my_charpos() */
 
454
      uint char_length= seg->length; /* TODO: fix to use my_charpos() */
443
455
      seg->charset->coll->hash_sort(seg->charset, pos, char_length,
444
456
                                    &nr, &nr2);
445
457
    }
446
458
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
447
459
    {
448
 
      uint32_t pack_length= seg->bit_start;
449
 
      uint32_t length= (pack_length == 1 ? (uint) *(unsigned char*) pos : uint2korr(pos));
 
460
      uint pack_length= seg->bit_start;
 
461
      uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
450
462
      seg->charset->coll->hash_sort(seg->charset, pos+pack_length,
451
463
                                    length, &nr, &nr2);
452
464
    }
453
465
    else
454
466
    {
455
 
      unsigned char *end= pos+seg->length;
 
467
      uchar *end= pos+seg->length;
456
468
      for ( ; pos < end ; pos++)
457
469
      {
458
470
        nr *=16777619; 
460
472
      }
461
473
    }
462
474
  }
 
475
  DBUG_PRINT("exit", ("hash: 0x%lx", nr));
463
476
  return(nr);
464
477
}
465
478
 
486
499
    <> 0        Key differes
487
500
*/
488
501
 
489
 
int hp_rec_key_cmp(HP_KEYDEF *keydef, const unsigned char *rec1, const unsigned char *rec2,
490
 
                   bool diff_if_only_endspace_difference)
 
502
int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2,
 
503
                   my_bool diff_if_only_endspace_difference)
491
504
{
492
505
  HA_KEYSEG *seg,*endseg;
493
506
 
503
516
    }
504
517
    if (seg->type == HA_KEYTYPE_TEXT)
505
518
    {
506
 
      const CHARSET_INFO * const cs= seg->charset;
507
 
      uint32_t char_length1;
508
 
      uint32_t char_length2;
509
 
      unsigned char *pos1= (unsigned char*)rec1 + seg->start;
510
 
      unsigned char *pos2= (unsigned char*)rec2 + seg->start;
 
519
      CHARSET_INFO *cs= seg->charset;
 
520
      uint char_length1;
 
521
      uint char_length2;
 
522
      uchar *pos1= (uchar*)rec1 + seg->start;
 
523
      uchar *pos2= (uchar*)rec2 + seg->start;
511
524
      if (cs->mbmaxlen > 1)
512
525
      {
513
 
        uint32_t char_length= seg->length / cs->mbmaxlen;
 
526
        uint char_length= seg->length / cs->mbmaxlen;
514
527
        char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
515
528
        set_if_smaller(char_length1, seg->length);
516
529
        char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
527
540
    }
528
541
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
529
542
    {
530
 
      unsigned char *pos1= (unsigned char*) rec1 + seg->start;
531
 
      unsigned char *pos2= (unsigned char*) rec2 + seg->start;
532
 
      uint32_t char_length1, char_length2;
533
 
      uint32_t pack_length= seg->bit_start;
534
 
      const CHARSET_INFO * const cs= seg->charset;
 
543
      uchar *pos1= (uchar*) rec1 + seg->start;
 
544
      uchar *pos2= (uchar*) rec2 + seg->start;
 
545
      uint char_length1, char_length2;
 
546
      uint pack_length= seg->bit_start;
 
547
      CHARSET_INFO *cs= seg->charset;
535
548
      if (pack_length == 1)
536
549
      {
537
 
        char_length1= (uint) *(unsigned char*) pos1++;
538
 
        char_length2= (uint) *(unsigned char*) pos2++;
 
550
        char_length1= (uint) *(uchar*) pos1++;
 
551
        char_length2= (uint) *(uchar*) pos2++;
539
552
      }
540
553
      else
541
554
      {
546
559
      }
547
560
      if (cs->mbmaxlen > 1)
548
561
      {
549
 
        uint32_t safe_length1= char_length1;
550
 
        uint32_t safe_length2= char_length2;
551
 
        uint32_t char_length= seg->length / cs->mbmaxlen;
 
562
        uint safe_length1= char_length1;
 
563
        uint safe_length2= char_length2;
 
564
        uint char_length= seg->length / cs->mbmaxlen;
552
565
        char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length);
553
566
        set_if_smaller(char_length1, safe_length1);
554
567
        char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length);
564
577
    }
565
578
    else
566
579
    {
567
 
      if (memcmp(rec1+seg->start,rec2+seg->start,seg->length))
 
580
      if (bcmp(rec1+seg->start,rec2+seg->start,seg->length))
568
581
        return 1;
569
582
    }
570
583
  }
573
586
 
574
587
        /* Compare a key in a record to a whole key */
575
588
 
576
 
int hp_key_cmp(HP_KEYDEF *keydef, const unsigned char *rec, const unsigned char *key)
 
589
int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key)
577
590
{
578
591
  HA_KEYSEG *seg,*endseg;
579
592
 
596
609
    }
597
610
    if (seg->type == HA_KEYTYPE_TEXT)
598
611
    {
599
 
      const CHARSET_INFO * const cs= seg->charset;
600
 
      uint32_t char_length_key;
601
 
      uint32_t char_length_rec;
602
 
      unsigned char *pos= (unsigned char*) rec + seg->start;
 
612
      CHARSET_INFO *cs= seg->charset;
 
613
      uint char_length_key;
 
614
      uint char_length_rec;
 
615
      uchar *pos= (uchar*) rec + seg->start;
603
616
      if (cs->mbmaxlen > 1)
604
617
      {
605
 
        uint32_t char_length= seg->length / cs->mbmaxlen;
 
618
        uint char_length= seg->length / cs->mbmaxlen;
606
619
        char_length_key= my_charpos(cs, key, key + seg->length, char_length);
607
620
        set_if_smaller(char_length_key, seg->length);
608
621
        char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length);
615
628
      }
616
629
      
617
630
      if (seg->charset->coll->strnncollsp(seg->charset,
618
 
                                          (unsigned char*) pos, char_length_rec,
619
 
                                          (unsigned char*) key, char_length_key, 0))
 
631
                                          (uchar*) pos, char_length_rec,
 
632
                                          (uchar*) key, char_length_key, 0))
620
633
        return 1;
621
634
    }
622
635
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
623
636
    {
624
 
      unsigned char *pos= (unsigned char*) rec + seg->start;
625
 
      const CHARSET_INFO * const cs= seg->charset;
626
 
      uint32_t pack_length= seg->bit_start;
627
 
      uint32_t char_length_rec= (pack_length == 1 ? (uint) *(unsigned char*) pos :
 
637
      uchar *pos= (uchar*) rec + seg->start;
 
638
      CHARSET_INFO *cs= seg->charset;
 
639
      uint pack_length= seg->bit_start;
 
640
      uint char_length_rec= (pack_length == 1 ? (uint) *(uchar*) pos :
628
641
                             uint2korr(pos));
629
642
      /* Key segments are always packed with 2 bytes */
630
 
      uint32_t char_length_key= uint2korr(key);
 
643
      uint char_length_key= uint2korr(key);
631
644
      pos+= pack_length;
632
645
      key+= 2;                                  /* skip key pack length */
633
646
      if (cs->mbmaxlen > 1)
634
647
      {
635
 
        uint32_t char_length1, char_length2;
 
648
        uint char_length1, char_length2;
636
649
        char_length1= char_length2= seg->length / cs->mbmaxlen; 
637
650
        char_length1= my_charpos(cs, key, key + char_length_key, char_length1);
638
651
        set_if_smaller(char_length_key, char_length1);
641
654
      }
642
655
 
643
656
      if (cs->coll->strnncollsp(seg->charset,
644
 
                                (unsigned char*) pos, char_length_rec,
645
 
                                (unsigned char*) key, char_length_key, 0))
 
657
                                (uchar*) pos, char_length_rec,
 
658
                                (uchar*) key, char_length_key, 0))
646
659
        return 1;
647
660
    }
648
661
    else
649
662
    {
650
 
      if (memcmp(rec+seg->start,key,seg->length))
 
663
      if (bcmp(rec+seg->start,key,seg->length))
651
664
        return 1;
652
665
    }
653
666
  }
657
670
 
658
671
        /* Copy a key from a record to a keybuffer */
659
672
 
660
 
void hp_make_key(HP_KEYDEF *keydef, unsigned char *key, const unsigned char *rec)
 
673
void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec)
661
674
{
662
675
  HA_KEYSEG *seg,*endseg;
663
676
 
664
677
  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
665
678
  {
666
 
    const CHARSET_INFO * const cs= seg->charset;
667
 
    uint32_t char_length= seg->length;
668
 
    unsigned char *pos= (unsigned char*) rec + seg->start;
 
679
    CHARSET_INFO *cs= seg->charset;
 
680
    uint char_length= seg->length;
 
681
    uchar *pos= (uchar*) rec + seg->start;
669
682
    if (seg->null_bit)
670
683
      *key++= test(rec[seg->null_pos] & seg->null_bit);
671
684
    if (cs->mbmaxlen > 1)
689
702
  } while(0)
690
703
 
691
704
 
692
 
uint32_t hp_rb_make_key(HP_KEYDEF *keydef, unsigned char *key, 
693
 
                    const unsigned char *rec, unsigned char *recpos)
 
705
uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key, 
 
706
                    const uchar *rec, uchar *recpos)
694
707
{
695
 
  unsigned char *start_key= key;
 
708
  uchar *start_key= key;
696
709
  HA_KEYSEG *seg, *endseg;
697
710
 
698
711
  for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
699
712
  {
700
 
    uint32_t char_length;
 
713
    uint char_length;
701
714
    if (seg->null_bit)
702
715
    {
703
716
      if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit)))
705
718
    }
706
719
    if (seg->flag & HA_SWAP_KEY)
707
720
    {
708
 
      uint32_t length= seg->length;
709
 
      unsigned char *pos= (unsigned char*) rec + seg->start;
 
721
      uint length= seg->length;
 
722
      uchar *pos= (uchar*) rec + seg->start;
710
723
      
711
724
#ifdef HAVE_ISNAN
712
725
      if (seg->type == HA_KEYTYPE_FLOAT)
716
729
        if (isnan(nr))
717
730
        {
718
731
          /* Replace NAN with zero */
719
 
          memset(key, 0, length);
 
732
          bzero(key, length);
720
733
          key+= length;
721
734
          continue;
722
735
        }
727
740
        float8get(nr, pos);
728
741
        if (isnan(nr))
729
742
        {
730
 
          memset(key, 0, length);
 
743
          bzero(key, length);
731
744
          key+= length;
732
745
          continue;
733
746
        }
743
756
 
744
757
    if (seg->flag & HA_VAR_LENGTH_PART)
745
758
    {
746
 
      unsigned char *pos=      (unsigned char*) rec + seg->start;
747
 
      uint32_t length=     seg->length;
748
 
      uint32_t pack_length= seg->bit_start;
749
 
      uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
 
759
      uchar *pos=      (uchar*) rec + seg->start;
 
760
      uint length=     seg->length;
 
761
      uint pack_length= seg->bit_start;
 
762
      uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
750
763
                        uint2korr(pos));
751
 
      const CHARSET_INFO * const cs= seg->charset;
 
764
      CHARSET_INFO *cs= seg->charset;
752
765
      char_length= length/cs->mbmaxlen;
753
766
 
754
767
      pos+= pack_length;                        /* Skip VARCHAR length */
755
768
      set_if_smaller(length,tmp_length);
756
769
      FIX_LENGTH(cs, pos, length, char_length);
757
770
      store_key_length_inc(key,char_length);
758
 
      memcpy(key,pos,(size_t) char_length);
 
771
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
759
772
      key+= char_length;
760
773
      continue;
761
774
    }
774
787
    memcpy(key, rec + seg->start, (size_t) char_length);
775
788
    key+= seg->length;
776
789
  }
777
 
  memcpy(key, &recpos, sizeof(unsigned char*));
 
790
  memcpy(key, &recpos, sizeof(uchar*));
778
791
  return (uint) (key - start_key);
779
792
}
780
793
 
781
794
 
782
 
uint32_t hp_rb_pack_key(HP_KEYDEF *keydef, unsigned char *key, const unsigned char *old,
 
795
uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
783
796
                    key_part_map keypart_map)
784
797
{
785
798
  HA_KEYSEG *seg, *endseg;
786
 
  unsigned char *start_key= key;
 
799
  uchar *start_key= key;
787
800
 
788
801
  for (seg= keydef->seg, endseg= seg + keydef->keysegs;
789
802
       seg < endseg && keypart_map; old+= seg->length, seg++)
790
803
  {
791
 
    uint32_t char_length;
 
804
    uint char_length;
792
805
    keypart_map>>= 1;
793
806
    if (seg->null_bit)
794
807
    {
797
810
      }
798
811
    if (seg->flag & HA_SWAP_KEY)
799
812
    {
800
 
      uint32_t length= seg->length;
801
 
      unsigned char *pos= (unsigned char*) old + length;
 
813
      uint length= seg->length;
 
814
      uchar *pos= (uchar*) old + length;
802
815
      
803
816
      while (length--)
804
817
      {
809
822
    if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
810
823
    {
811
824
      /* Length of key-part used with heap_rkey() always 2 */
812
 
      uint32_t tmp_length=uint2korr(old);
813
 
      uint32_t length= seg->length;
814
 
      const CHARSET_INFO * const cs= seg->charset;
 
825
      uint tmp_length=uint2korr(old);
 
826
      uint length= seg->length;
 
827
      CHARSET_INFO *cs= seg->charset;
815
828
      char_length= length/cs->mbmaxlen;
816
829
 
817
830
      old+= 2;
818
831
      set_if_smaller(length,tmp_length);        /* Safety */
819
832
      FIX_LENGTH(cs, old, length, char_length);
820
833
      store_key_length_inc(key,char_length);
821
 
      memcpy(key, old,(size_t) char_length);
 
834
      memcpy((uchar*) key, old,(size_t) char_length);
822
835
      key+= char_length;
823
836
      continue;
824
837
    }
839
852
}
840
853
 
841
854
 
842
 
uint32_t hp_rb_key_length(HP_KEYDEF *keydef, 
843
 
                      const unsigned char *key __attribute__((unused)))
 
855
uint hp_rb_key_length(HP_KEYDEF *keydef, 
 
856
                      const uchar *key __attribute__((unused)))
844
857
{
845
858
  return keydef->length;
846
859
}
847
860
 
848
861
 
849
 
uint32_t hp_rb_null_key_length(HP_KEYDEF *keydef, const unsigned char *key)
 
862
uint hp_rb_null_key_length(HP_KEYDEF *keydef, const uchar *key)
850
863
{
851
 
  const unsigned char *start_key= key;
 
864
  const uchar *start_key= key;
852
865
  HA_KEYSEG *seg, *endseg;
853
866
  
854
867
  for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
861
874
}
862
875
                  
863
876
 
864
 
uint32_t hp_rb_var_key_length(HP_KEYDEF *keydef, const unsigned char *key)
 
877
uint hp_rb_var_key_length(HP_KEYDEF *keydef, const uchar *key)
865
878
{
866
 
  const unsigned char *start_key= key;
 
879
  const uchar *start_key= key;
867
880
  HA_KEYSEG *seg, *endseg;
868
881
  
869
882
  for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
870
883
  {
871
 
    uint32_t length= seg->length;
 
884
    uint length= seg->length;
872
885
    if (seg->null_bit && !*key++)
873
886
      continue;
874
887
    if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
888
901
    0 otherwise
889
902
*/
890
903
 
891
 
bool hp_if_null_in_key(HP_KEYDEF *keydef, const unsigned char *record)
 
904
my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const uchar *record)
892
905
{
893
906
  HA_KEYSEG *seg,*endseg;
894
907
  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
914
927
    less than zero.
915
928
*/
916
929
 
917
 
void heap_update_auto_increment(HP_INFO *info, const unsigned char *record)
 
930
void heap_update_auto_increment(HP_INFO *info, const uchar *record)
918
931
{
919
 
  uint64_t value= 0;                    /* Store unsigned values here */
920
 
  int64_t s_value= 0;                   /* Store signed values here */
 
932
  ulonglong value= 0;                   /* Store unsigned values here */
 
933
  longlong s_value= 0;                  /* Store signed values here */
921
934
 
922
935
  HA_KEYSEG *keyseg= info->s->keydef[info->s->auto_key - 1].seg;
923
 
  const unsigned char *key=  (unsigned char*) record + keyseg->start;
 
936
  const uchar *key=  (uchar*) record + keyseg->start;
924
937
 
925
938
  switch (info->s->auto_key_type) {
926
939
  case HA_KEYTYPE_INT8:
927
 
    s_value= (int64_t) *(char*)key;
 
940
    s_value= (longlong) *(char*)key;
928
941
    break;
929
942
  case HA_KEYTYPE_BINARY:
930
 
    value=(uint64_t)  *(unsigned char*) key;
 
943
    value=(ulonglong)  *(uchar*) key;
931
944
    break;
932
945
  case HA_KEYTYPE_SHORT_INT:
933
 
    s_value= (int64_t) sint2korr(key);
 
946
    s_value= (longlong) sint2korr(key);
934
947
    break;
935
948
  case HA_KEYTYPE_USHORT_INT:
936
 
    value=(uint64_t) uint2korr(key);
 
949
    value=(ulonglong) uint2korr(key);
937
950
    break;
938
951
  case HA_KEYTYPE_LONG_INT:
939
 
    s_value= (int64_t) sint4korr(key);
 
952
    s_value= (longlong) sint4korr(key);
940
953
    break;
941
954
  case HA_KEYTYPE_ULONG_INT:
942
 
    value=(uint64_t) uint4korr(key);
 
955
    value=(ulonglong) uint4korr(key);
943
956
    break;
944
957
  case HA_KEYTYPE_INT24:
945
 
    s_value= (int64_t) sint3korr(key);
 
958
    s_value= (longlong) sint3korr(key);
946
959
    break;
947
960
  case HA_KEYTYPE_UINT24:
948
 
    value=(uint64_t) uint3korr(key);
 
961
    value=(ulonglong) uint3korr(key);
949
962
    break;
950
963
  case HA_KEYTYPE_FLOAT:                        /* This shouldn't be used */
951
964
  {
952
965
    float f_1;
953
966
    float4get(f_1,key);
954
967
    /* Ignore negative values */
955
 
    value = (f_1 < (float) 0.0) ? 0 : (uint64_t) f_1;
 
968
    value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
956
969
    break;
957
970
  }
958
971
  case HA_KEYTYPE_DOUBLE:                       /* This shouldn't be used */
960
973
    double f_1;
961
974
    float8get(f_1,key);
962
975
    /* Ignore negative values */
963
 
    value = (f_1 < 0.0) ? 0 : (uint64_t) f_1;
 
976
    value = (f_1 < 0.0) ? 0 : (ulonglong) f_1;
964
977
    break;
965
978
  }
966
979
  case HA_KEYTYPE_LONGLONG:
970
983
    value= uint8korr(key);
971
984
    break;
972
985
  default:
973
 
    assert(0);
 
986
    DBUG_ASSERT(0);
974
987
    value=0;                                    /* Error */
975
988
    break;
976
989
  }
981
994
    correct value.
982
995
  */
983
996
  set_if_bigger(info->s->auto_increment,
984
 
                (s_value > 0) ? (uint64_t) s_value : value);
 
997
                (s_value > 0) ? (ulonglong) s_value : value);
985
998
}