~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/uniques.cc

  • Committer: Brian Aker
  • Date: 2009-02-26 05:21:02 UTC
  • mfrom: (896.1.5 fix-osxs)
  • Revision ID: brian@intel-mini-2.local-20090226052102-8xtbjt8kph6mi0qx
Merge from Monty.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <drizzled/server_includes.h>
34
34
#include <drizzled/sql_sort.h>
35
35
#include <drizzled/session.h>
 
36
#include <queue>
36
37
#include CMATH_H
37
38
 
38
39
#if defined(CMATH_NAMESPACE)
39
40
using namespace CMATH_NAMESPACE;
40
41
#endif
41
42
 
 
43
using namespace std;
 
44
 
42
45
 
43
46
int unique_write_to_file(unsigned char* key, element_count,
44
47
                         Unique *unique)
386
389
}
387
390
#endif
388
391
 
 
392
/*
 
393
 The comparison function object, passed to a priority_queue in merge_walk()
 
394
 as its sort function parameter.
 
395
*/
389
396
 
 
397
class buffpek_compare_functor
 
398
{
 
399
  qsort_cmp2 key_compare;
 
400
  void *key_compare_arg;
 
401
  public:
 
402
  buffpek_compare_functor(qsort_cmp2 in_key_compare, void *in_compare_arg)
 
403
    : key_compare(in_key_compare), key_compare_arg(in_compare_arg) { }
 
404
  inline bool operator()(BUFFPEK *i, BUFFPEK *j)
 
405
  {
 
406
    return key_compare(key_compare_arg,
 
407
                    i->key, j->key);
 
408
  }
 
409
};
390
410
 
391
411
/*
392
412
  DESCRIPTION
428
448
                       qsort_cmp2 compare, void *compare_arg,
429
449
                       IO_CACHE *file)
430
450
{
431
 
  BUFFPEK_COMPARE_CONTEXT compare_context = { compare, compare_arg };
432
 
  QUEUE queue;
433
451
  if (end <= begin ||
434
 
      merge_buffer_size < (ulong) (key_length * (end - begin + 1)) ||
435
 
      init_queue(&queue, (uint32_t) (end - begin), offsetof(BUFFPEK, key), 0,
436
 
                 buffpek_compare, &compare_context))
 
452
      merge_buffer_size < (ulong) (key_length * (end - begin + 1))) 
437
453
    return 1;
 
454
  priority_queue<BUFFPEK *, vector<BUFFPEK *>, buffpek_compare_functor >
 
455
    queue(buffpek_compare_functor(compare, compare_arg));
438
456
  /* we need space for one key when a piece of merge buffer is re-read */
439
457
  merge_buffer_size-= key_length;
440
458
  unsigned char *save_key_buff= merge_buffer + merge_buffer_size;
459
477
    if (bytes_read == (uint32_t) (-1))
460
478
      goto end;
461
479
    assert(bytes_read);
462
 
    queue_insert(&queue, (unsigned char *) top);
 
480
    queue.push(top);
463
481
  }
464
 
  top= (BUFFPEK *) queue_top(&queue);
465
 
  while (queue.elements > 1)
 
482
  top= queue.top();
 
483
  while (queue.size() > 1)
466
484
  {
467
485
    /*
468
486
      Every iteration one element is removed from the queue, and one is
478
496
    */
479
497
    top->key+= key_length;
480
498
    if (--top->mem_count)
481
 
      queue_replaced(&queue);
 
499
    {
 
500
      queue.pop();
 
501
      queue.push(top);
 
502
    }
482
503
    else /* next piece should be read */
483
504
    {
484
505
      /* save old_key not to overwrite it in read_to_buffer */
487
508
      bytes_read= read_to_buffer(file, top, key_length);
488
509
      if (bytes_read == (uint32_t) (-1))
489
510
        goto end;
490
 
      else if (bytes_read > 0)      /* top->key, top->mem_count are reset */
491
 
        queue_replaced(&queue);     /* in read_to_buffer */
 
511
      else if (bytes_read > 0) /* top->key, top->mem_count are reset */
 
512
      {                        /* in read_to_buffer */
 
513
        queue.pop();
 
514
        queue.push(top);
 
515
      }
492
516
      else
493
517
      {
494
518
        /*
495
 
          Tree for old 'top' element is empty: remove it from the queue and
496
 
          give all its memory to the nearest tree.
 
519
          Tree for old 'top' element is empty: remove it from the queue. 
497
520
        */
498
 
        queue_remove(&queue, 0);
499
 
        reuse_freed_buff(&queue, top, key_length);
 
521
        queue.pop();
500
522
      }
501
523
    }
502
 
    top= (BUFFPEK *) queue_top(&queue);
 
524
    top= queue.top();
503
525
    /* new top has been obtained; if old top is unique, apply the action */
504
526
    if (compare(compare_arg, old_key, top->key))
505
527
    {
528
550
  while (bytes_read);
529
551
  res= 0;
530
552
end:
531
 
  delete_queue(&queue);
532
553
  return res;
533
554
}
534
555