~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_strfunc.cc

  • Committer: Brian Aker
  • Date: 2008-10-28 13:45:31 UTC
  • Revision ID: brian@tangent.org-20081028134531-tgrxxokeago2sio5
New UUID code. Also changed default scaling for "8" core machine instead of
20 core machine.


Who the hell builds a 20 core machine? Stupid default.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <mysys/sha1.h>
31
31
#include <zlib.h>
32
32
#include <drizzled/query_id.h>
 
33
#include <uuid/uuid.h>
33
34
 
34
35
#ifdef __cplusplus
35
36
extern "C" {
2499
2500
  return 0;
2500
2501
}
2501
2502
 
2502
 
/*
2503
 
  UUID, as in
2504
 
    DCE 1.1: Remote Procedure Call,
2505
 
    Open Group Technical Standard Document Number C706, October 1997,
2506
 
    (supersedes C309 DCE: Remote Procedure Call 8/1994,
2507
 
    which was basis for ISO/IEC 11578:1996 specification)
2508
 
*/
2509
 
 
2510
 
static struct rand_struct uuid_rand;
2511
 
static uint32_t nanoseq;
2512
 
static uint64_t uuid_time=0;
2513
 
static char clock_seq_and_node_str[]="-0000-000000000000";
2514
 
 
2515
 
/**
2516
 
  number of 100-nanosecond intervals between
2517
 
  1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
2518
 
*/
2519
 
#define UUID_TIME_OFFSET ((uint64_t) 141427 * 24 * 60 * 60 * 1000 * 10 )
2520
 
 
2521
 
#define UUID_VERSION      0x1000
2522
 
#define UUID_VARIANT      0x8000
2523
 
 
2524
 
static void tohex(char *to, uint32_t from, uint32_t len)
2525
 
{
2526
 
  to+= len;
2527
 
  while (len--)
2528
 
  {
2529
 
    *--to= _dig_vec_lower[from & 15];
2530
 
    from >>= 4;
2531
 
  }
2532
 
}
2533
 
 
2534
 
static void set_clock_seq_str()
2535
 
{
2536
 
  uint16_t clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT;
2537
 
  tohex(clock_seq_and_node_str+1, clock_seq, 4);
2538
 
  nanoseq= 0;
2539
 
}
 
2503
 
2540
2504
 
2541
2505
String *Item_func_uuid::val_str(String *str)
2542
2506
{
2543
 
  assert(fixed == 1);
2544
 
  char *s;
2545
 
  Session *session= current_session;
2546
 
 
2547
 
  pthread_mutex_lock(&LOCK_uuid_generator);
2548
 
  if (! uuid_time) /* first UUID() call. initializing data */
2549
 
  {
2550
 
    ulong tmp= sql_rnd();
2551
 
    unsigned char mac[6];
2552
 
    int i;
2553
 
    const Query_id& query_id= Query_id::get_query_id();
2554
 
    if (my_gethwaddr(mac))
2555
 
    {
2556
 
      /* purecov: begin inspected */
2557
 
      /*
2558
 
        generating random "hardware addr"
2559
 
        and because specs explicitly specify that it should NOT correlate
2560
 
        with a clock_seq value (initialized random below), we use a separate
2561
 
        randominit() here
2562
 
      */
2563
 
      randominit(&uuid_rand, tmp + (ulong) session, tmp + query_id.value());
2564
 
      for (i=0; i < (int)sizeof(mac); i++)
2565
 
        mac[i]=(unsigned char)(my_rnd(&uuid_rand)*255);
2566
 
      /* purecov: end */    
2567
 
    }
2568
 
    s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
2569
 
    for (i=sizeof(mac)-1 ; i>=0 ; i--)
2570
 
    {
2571
 
      *--s=_dig_vec_lower[mac[i] & 15];
2572
 
      *--s=_dig_vec_lower[mac[i] >> 4];
2573
 
    }
2574
 
    randominit(&uuid_rand, tmp + (ulong) server_start_time,
2575
 
               tmp + (ulong) session->status_var.bytes_sent);
2576
 
    set_clock_seq_str();
2577
 
  }
2578
 
 
2579
 
  uint64_t tv=my_getsystime() + UUID_TIME_OFFSET + nanoseq;
2580
 
  if (unlikely(tv < uuid_time))
2581
 
    set_clock_seq_str();
2582
 
  else if (unlikely(tv == uuid_time))
2583
 
  {
2584
 
    /* special protection from low-res system clocks */
2585
 
    nanoseq++;
2586
 
    tv++;
2587
 
  }
2588
 
  else
2589
 
  {
2590
 
    if (nanoseq)
2591
 
    {
2592
 
      tv-=nanoseq;
2593
 
      nanoseq=0;
2594
 
    }
2595
 
    assert(tv > uuid_time);
2596
 
  }
2597
 
  uuid_time=tv;
2598
 
  pthread_mutex_unlock(&LOCK_uuid_generator);
2599
 
 
2600
 
  uint32_t time_low=            (uint32_t) (tv & 0xFFFFFFFF);
2601
 
  uint16_t time_mid=            (uint16_t) ((tv >> 32) & 0xFFFF);
2602
 
  uint16_t time_hi_and_version= (uint16_t) ((tv >> 48) | UUID_VERSION);
2603
 
 
2604
 
  str->realloc(UUID_LENGTH+1);
2605
 
  str->length(UUID_LENGTH);
 
2507
  uuid_t uu;
 
2508
  char *uuid_string;
 
2509
 
 
2510
  /* 36 characters for uuid string +1 for NULL */
 
2511
  str->realloc(36+1);
 
2512
  str->length(36);
2606
2513
  str->set_charset(system_charset_info);
2607
 
  s=(char *) str->ptr();
2608
 
  s[8]=s[13]='-';
2609
 
  tohex(s, time_low, 8);
2610
 
  tohex(s+9, time_mid, 4);
2611
 
  tohex(s+14, time_hi_and_version, 4);
2612
 
  my_stpcpy(s+18, clock_seq_and_node_str);
 
2514
  uuid_string= (char *) str->ptr();
 
2515
  uuid_generate_time(uu);
 
2516
  uuid_unparse(uu, uuid_string);
 
2517
 
2613
2518
  return str;
2614
2519
}