~ubuntu-branches/ubuntu/hardy/mysql-dfsg-5.0/hardy-updates

« back to all changes in this revision

Viewing changes to ndb/src/common/util/ConfigValues.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2007-04-02 16:10:53 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070402161053-zkil9hjq9k5p1uzv
Tags: 5.0.37-0ubuntu1
* New upstream bugfix release.
  - Fixes replication failure with auto-increment and on duplicate key
    update, a regression introduced into 5.0.24. (LP: #95821)
* debian/control: Set Ubuntu maintainer.
* debian/rules: Change comments from 'Debian etch' to 'Ubuntu 7.04'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2004, 2006 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1
15
 
2
16
#include <ndb_global.h>
3
17
#include <ConfigValues.hpp>
34
48
 
35
49
//#define DEBUG_CV
36
50
#ifdef DEBUG_CV
37
 
#define DEBUG
 
51
#define DEBUG if(getenv("CV_DEBUG"))
38
52
#else
39
53
#define DEBUG if(0)
40
54
#endif
202
216
static
203
217
bool
204
218
findKey(const Uint32 * values, Uint32 sz, Uint32 key, Uint32 * _pos){
205
 
  Uint32 pos = hash(key, sz);
206
 
  Uint32 count = 0;
207
 
  while((values[pos] & KP_MASK) != key && count < sz){
208
 
    pos = nextHash(key, sz, pos, ++count);
209
 
  }
210
 
 
211
 
  if((values[pos] & KP_MASK)== key){
212
 
    *_pos = pos;
213
 
    return true;
214
 
  }
 
219
  Uint32 lo = 0;
 
220
  Uint32 hi = sz;
 
221
  Uint32 pos = (hi + lo) >> 1;
 
222
 
 
223
  DEBUG printf("findKey(H'%.8x %d)", key, sz);
 
224
 
 
225
  if (sz == 0)
 
226
  {
 
227
    DEBUG ndbout_c(" -> false, 0");
 
228
    * _pos = 0;
 
229
    return false;
 
230
  }
 
231
 
 
232
  Uint32 val = 0;
 
233
  Uint32 oldpos = pos + 1;
 
234
  while (pos != oldpos) 
 
235
  {
 
236
    DEBUG printf(" [ %d %d %d ] ", lo, pos, hi);
 
237
    assert(pos < hi);
 
238
    assert(pos >= lo);
 
239
    val = values[2*pos] & KP_MASK;
 
240
    if (key > val)
 
241
    {
 
242
      lo = pos;
 
243
    }
 
244
    else if (key < val)
 
245
    {
 
246
      hi = pos;
 
247
    }
 
248
    else 
 
249
    {
 
250
      * _pos = 2*pos;
 
251
      DEBUG ndbout_c(" -> true, %d", pos);
 
252
      return true;
 
253
    }
 
254
    oldpos = pos;
 
255
    pos = (hi + lo) >> 1;
 
256
  } 
 
257
 
 
258
  DEBUG printf(" pos: %d (key %.8x val: %.8x values[pos]: %x) key>val: %d ",
 
259
               pos, key, val, values[2*pos] & KP_MASK,
 
260
               key > val);
 
261
 
 
262
  pos += (key > val) ? 1 : 0;
 
263
  
 
264
  * _pos = 2*pos;
 
265
  DEBUG ndbout_c(" -> false, %d", pos);
215
266
  return false;
216
267
}
217
268
 
218
 
static
219
 
Uint32
220
 
hash(Uint32 key, Uint32 size){
221
 
  Uint32 tmp = (key >> 16) ^ (key & 0xFFFF);
222
 
  return (((tmp << 16) | tmp) % size) << 1;
223
 
}
224
 
 
225
 
static
226
 
Uint32
227
 
nextHash(Uint32 key, Uint32 size, Uint32 pos, Uint32 count){
228
 
  Uint32 p = (pos >> 1);
229
 
  if((key % size) != 0)
230
 
    p += key;
231
 
  else
232
 
    p += 1;
233
 
  return (p % size) << 1;
234
 
}
235
 
 
236
 
static
237
 
Uint32
238
 
directory(Uint32 sz){
239
 
  const Uint32 _input = sz;
240
 
  if((sz & 1) == 0)
241
 
    sz ++;
242
 
  
243
 
  bool prime = false;
244
 
  while(!prime){
245
 
    prime = true;
246
 
    for(Uint32 n = 3; n*n <= sz; n += 2){
247
 
      if((sz % n) == 0){
248
 
        prime = false;
249
 
        sz += 2;
250
 
        break;
251
 
      }
252
 
    }
253
 
  }
254
 
  DEBUG printf("directory %d -> %d\n", _input, sz);
255
 
  return sz;
256
 
}
257
269
 
258
270
ConfigValuesFactory::ConfigValuesFactory(Uint32 keys, Uint32 data){
259
271
  m_sectionCounter = (1 << KP_SECTION_SHIFT);
260
 
  m_freeKeys = directory(keys);
 
272
  m_freeKeys = keys;
261
273
  m_freeData = (data + 7) & ~7;
262
274
  m_currentSection = 0;
263
275
  m_cfg = create(m_freeKeys, m_freeData);
316
328
    return ;
317
329
  }
318
330
 
 
331
  DEBUG printf("[ fk fd ] : [ %d %d ]", m_freeKeys, m_freeData);
 
332
  
319
333
  m_freeKeys = (m_freeKeys >= fk ? m_cfg->m_size : fk + m_cfg->m_size);
320
334
  m_freeData = (m_freeData >= fs ? m_cfg->m_dataSize : fs + m_cfg->m_dataSize);
321
 
  m_freeKeys = directory(m_freeKeys);
322
335
  m_freeData = (m_freeData + 7) & ~7;
323
 
 
 
336
  
 
337
  DEBUG ndbout_c(" [ %d %d ]", m_freeKeys, m_freeData);
 
338
 
324
339
  ConfigValues * m_tmp = m_cfg;
325
340
  m_cfg = create(m_freeKeys, m_freeData);
326
341
  put(* m_tmp);
336
351
 
337
352
  m_freeKeys = m_cfg->m_size - m_freeKeys;
338
353
  m_freeData = m_cfg->m_dataSize - m_freeData;
339
 
  m_freeKeys = directory(m_freeKeys);
340
354
  m_freeData = (m_freeData + 7) & ~7;
341
355
 
342
356
  ConfigValues * m_tmp = m_cfg;
415
429
  }
416
430
  
417
431
  const Uint32 tmp = entry.m_key | m_currentSection;
418
 
  const Uint32 sz = m_cfg->m_size;
419
 
  Uint32 pos = hash(tmp, sz);
420
 
  Uint32 count = 0;
421
 
  Uint32 val = m_cfg->m_values[pos];
422
 
 
423
 
  while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){
424
 
    pos = nextHash(tmp, sz, pos, ++count);
425
 
    val = m_cfg->m_values[pos];
426
 
  }
427
 
 
428
 
  if((val & KP_MASK) == tmp){
 
432
  const Uint32 sz = m_cfg->m_size - m_freeKeys;
 
433
 
 
434
  Uint32 pos;
 
435
  if (findKey(m_cfg->m_values, sz, tmp, &pos))
 
436
  {
429
437
    DEBUG ndbout_c("key %x already found at pos: %d", tmp, pos);
430
438
    return false;
431
439
  }
432
440
 
433
 
  if(count >= sz){
434
 
    pos = hash(tmp, sz);    
435
 
    count = 0;
436
 
    Uint32 val = m_cfg->m_values[pos];
437
 
   
438
 
    printf("key: %d, (key %% size): %d\n", entry.m_key, (entry.m_key % sz));
439
 
    printf("pos: %d", pos);
440
 
    while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){
441
 
      pos = nextHash(tmp, sz, pos, ++count);
442
 
      val = m_cfg->m_values[pos];
443
 
      printf(" %d", pos);
 
441
  DEBUG {
 
442
    printf("H'before ");
 
443
    Uint32 prev = 0;
 
444
    for (Uint32 i = 0; i<sz; i++)
 
445
    {
 
446
      Uint32 val = m_cfg->m_values[2*i] & KP_MASK;
 
447
      ndbout_c("%.8x", val);
 
448
      assert(val >= prev);
 
449
      prev = val;
444
450
    }
445
 
    printf("\n");
446
 
 
447
 
    abort();
448
 
    printf("Full\n");
449
 
    return false;
450
 
  }
451
 
 
452
 
  assert(pos < (sz << 1));
 
451
  }
 
452
  
 
453
  if (pos != 2*sz)
 
454
  {
 
455
    DEBUG ndbout_c("pos: %d sz: %d", pos, sz);
 
456
    memmove(m_cfg->m_values + pos + 2, m_cfg->m_values + pos, 
 
457
            4 * (2*sz - pos));
 
458
  }
 
459
 
453
460
 
454
461
  Uint32 key = tmp;
455
462
  key |= (entry.m_type << KP_TYPE_SHIFT);
456
463
  m_cfg->m_values[pos] = key;
 
464
 
 
465
  DEBUG {
 
466
    printf("H'after ");
 
467
    Uint32 prev = 0;
 
468
    for (Uint32 i = 0; i<=sz; i++)
 
469
    {
 
470
      Uint32 val = m_cfg->m_values[2*i] & KP_MASK;
 
471
      ndbout_c("%.8x", val);
 
472
      assert(val >= prev);
 
473
      prev = val;
 
474
    }
 
475
  }
 
476
  
457
477
  switch(entry.m_type){
458
478
  case ConfigValues::IntType:
459
479
  case ConfigValues::SectionType:
460
480
    m_cfg->m_values[pos+1] = entry.m_int;    
461
481
    m_freeKeys--;
462
482
    DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value: %d\n", 
463
 
                   pos, sz, count, 
 
483
                   pos, sz, 0, 
464
484
                   (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
465
485
                   entry.m_int);
466
486
    return true;
472
492
    m_freeKeys--;
473
493
    m_freeData -= sizeof(char *);
474
494
    DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value(%d): %s\n", 
475
 
                   pos, sz, count, 
 
495
                   pos, sz, 0, 
476
496
                   (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
477
497
                   index,
478
498
                   entry.m_string);
485
505
    m_freeKeys--;
486
506
    m_freeData -= 8;
487
507
    DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value64(%d): %lld\n", 
488
 
                   pos, sz, count, 
 
508
                   pos, sz, 0, 
489
509
                   (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
490
510
                   index,
491
511
                   entry.m_int64);
648
668
  }
649
669
 
650
670
  const char * src = (const char *)_src;
651
 
 
 
671
  const char * end = src + len - 4;
 
672
  src += sizeof(Magic);
 
673
  
652
674
  {
653
675
    Uint32 len32 = (len >> 2);
654
676
    const Uint32 * tmp = (const Uint32*)_src;
663
685
    }
664
686
  }
665
687
 
666
 
  const char * end = src + len - 4;
667
 
  src += sizeof(Magic);
668
 
 
 
688
  const char * save = src;
 
689
 
 
690
  {
 
691
    Uint32 keys = 0;
 
692
    Uint32 data = 0;
 
693
    while(end - src > 4){
 
694
      Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4;
 
695
      keys++;
 
696
      switch(::getTypeOf(tmp)){
 
697
      case ConfigValues::IntType:
 
698
      case ConfigValues::SectionType:
 
699
        src += 4;
 
700
        break;
 
701
      case ConfigValues::Int64Type:
 
702
        src += 8;
 
703
        data += 8;
 
704
        break;
 
705
      case ConfigValues::StringType:{
 
706
        Uint32 s_len = ntohl(* (const Uint32 *)src);
 
707
        src += 4 + mod4(s_len);
 
708
        data += sizeof(char*);
 
709
        break;
 
710
      }
 
711
      default:
 
712
        break;
 
713
      }
 
714
    }
 
715
    expand(keys, data);
 
716
  }
 
717
  
 
718
  src = save;
669
719
  ConfigValues::Entry entry;
670
720
  while(end - src > 4){
671
721
    Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4;