~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_list.h

  • Committer: Monty Taylor
  • Date: 2008-11-16 06:29:53 UTC
  • mto: (584.1.9 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116062953-ivdltjmfe009b5fr
Moved stuff into item/

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#define DRIZZLED_SQL_LIST_H
22
22
 
23
23
 
24
 
#include <cstdlib>
25
 
#include <cassert>
26
24
#include <utility>
27
25
#include <algorithm>
28
 
#include "drizzled/memory/sql_alloc.h"
29
 
 
30
 
namespace drizzled
31
 
{
 
26
#include <drizzled/sql_alloc.h>
32
27
 
33
28
/** Struct to handle simple linked lists. */
34
29
typedef struct st_sql_list {
88
83
  @note We never call a destructor for instances of this class.
89
84
*/
90
85
 
91
 
struct list_node : public memory::SqlAlloc
 
86
struct list_node :public Sql_alloc
92
87
{
93
88
  list_node *next;
94
89
  void *info;
105
100
 
106
101
extern list_node end_of_list;
107
102
 
108
 
class base_list :public memory::SqlAlloc
 
103
class base_list :public Sql_alloc
109
104
{
110
105
protected:
111
106
  list_node *first,**last;
124
119
    relies on this behaviour. This logic is quite tricky: please do not use
125
120
    it in any new code.
126
121
  */
127
 
  inline base_list(const base_list &tmp) :memory::SqlAlloc()
 
122
  inline base_list(const base_list &tmp) :Sql_alloc()
128
123
  {
129
124
    elements= tmp.elements;
130
125
    first= tmp.first;
131
126
    last= elements ? tmp.last : &first;
132
127
  }
133
 
  inline base_list(bool) { }
 
128
  /**
 
129
    Construct a deep copy of the argument in memory root mem_root.
 
130
    The elements themselves are copied by pointer. If you also
 
131
    need to copy elements by value, you should employ
 
132
    list_copy_and_replace_each_value after creating a copy.
 
133
  */
 
134
  base_list(const base_list &rhs, MEM_ROOT *mem_root);
 
135
  inline base_list(bool error __attribute__((unused))) { }
134
136
  inline bool push_back(void *info)
135
137
  {
136
138
    if (((*last)=new list_node(info, &end_of_list)))
141
143
    }
142
144
    return 1;
143
145
  }
144
 
  inline bool push_back(void *info, memory::Root *mem_root)
 
146
  inline bool push_back(void *info, MEM_ROOT *mem_root)
145
147
  {
146
148
    if (((*last)=new (mem_root) list_node(info, &end_of_list)))
147
149
    {
246
248
      check_list()
247
249
        name  Name to print to trace file
248
250
 
249
 
    RETURN
 
251
    RETURN 
250
252
      1  The list is Ok.
251
253
      0  List invariants are not met.
252
254
  */
302
304
    ls.elements= elm;
303
305
  }
304
306
public:
305
 
  base_list_iterator()
 
307
  base_list_iterator() 
306
308
    :list(0), el(0), prev(0), current(0)
307
309
  {}
308
310
 
309
 
  base_list_iterator(base_list &list_par)
 
311
  base_list_iterator(base_list &list_par) 
310
312
  { init(list_par); }
311
313
 
312
314
  inline void init(base_list &list_par)
384
386
public:
385
387
  inline List() :base_list() {}
386
388
  inline List(const List<T> &tmp) :base_list(tmp) {}
387
 
  inline List(const List<T> &tmp, memory::Root *mem_root) :
 
389
  inline List(const List<T> &tmp, MEM_ROOT *mem_root) :
388
390
    base_list(tmp, mem_root) {}
389
391
  inline bool push_back(T *a) { return base_list::push_back(a); }
390
 
  inline bool push_back(T *a, memory::Root *mem_root)
 
392
  inline bool push_back(T *a, MEM_ROOT *mem_root)
391
393
  { return base_list::push_back(a, mem_root); }
392
394
  inline bool push_front(T *a) { return base_list::push_front(a); }
393
395
  inline T* head() {return (T*) base_list::head(); }
428
430
template <class T> class List_iterator_fast :public base_list_iterator
429
431
{
430
432
protected:
431
 
  inline T *replace(T *)   { return (T*) 0; }
432
 
  inline T *replace(List<T> &) { return (T*) 0; }
 
433
  inline T *replace(T *a __attribute__((unused)))   { return (T*) 0; }
 
434
  inline T *replace(List<T> &a __attribute__((unused))) { return (T*) 0; }
433
435
  inline void remove(void)  { }
434
 
  inline void after(T *a)   { }
 
436
  inline void after(T *a __attribute__((unused)))   { }
435
437
  inline T** ref(void)      { return (T**) 0; }
436
438
 
437
439
public:
447
449
};
448
450
 
449
451
 
 
452
/*
 
453
  A simple intrusive list which automaticly removes element from list
 
454
  on delete (for Session element)
 
455
*/
 
456
 
 
457
struct ilink
 
458
{
 
459
  struct ilink **prev,*next;
 
460
  static void *operator new(size_t size)
 
461
  {
 
462
    return (void*)malloc((uint)size);
 
463
  }
 
464
  static void operator delete(void* ptr_arg,
 
465
                              size_t size __attribute__((unused)))
 
466
  {
 
467
     free((unsigned char*)ptr_arg);
 
468
  }
 
469
 
 
470
  inline ilink()
 
471
  {
 
472
    prev=0; next=0;
 
473
  }
 
474
  inline void unlink()
 
475
  {
 
476
    /* Extra tests because element doesn't have to be linked */
 
477
    if (prev) *prev= next;
 
478
    if (next) next->prev=prev;
 
479
    prev=0 ; next=0;
 
480
  }
 
481
  virtual ~ilink() { unlink(); }                /*lint -e1740 */
 
482
};
 
483
 
 
484
 
 
485
/* Needed to be able to have an I_List of char* strings in mysqld.cc. */
 
486
 
 
487
class i_string: public ilink
 
488
{
 
489
public:
 
490
  const char* ptr;
 
491
  i_string():ptr(0) { }
 
492
  i_string(const char* s) : ptr(s) {}
 
493
};
 
494
 
 
495
/* needed for linked list of two strings for replicate-rewrite-db */
 
496
class i_string_pair: public ilink
 
497
{
 
498
public:
 
499
  const char* key;
 
500
  const char* val;
 
501
  i_string_pair():key(0),val(0) { }
 
502
  i_string_pair(const char* key_arg, const char* val_arg) : 
 
503
    key(key_arg),val(val_arg) {}
 
504
};
 
505
 
 
506
 
 
507
template <class T> class I_List_iterator;
 
508
 
 
509
/*
 
510
  WARNING: copy constructor of this class does not create a usable
 
511
  copy, as its members may point at each other.
 
512
*/
 
513
 
 
514
class base_ilist
 
515
{
 
516
public:
 
517
  struct ilink *first,last;
 
518
  inline void empty() { first= &last; last.prev= &first; }
 
519
  base_ilist() { empty(); }
 
520
  inline bool is_empty() {  return first == &last; }
 
521
  inline void append(ilink *a)
 
522
  {
 
523
    first->prev= &a->next;
 
524
    a->next=first; a->prev= &first; first=a;
 
525
  }
 
526
  inline void push_back(ilink *a)
 
527
  {
 
528
    *last.prev= a;
 
529
    a->next= &last;
 
530
    a->prev= last.prev;
 
531
    last.prev= &a->next;
 
532
  }
 
533
  inline struct ilink *get()
 
534
  {
 
535
    struct ilink *first_link=first;
 
536
    if (first_link == &last)
 
537
      return 0;
 
538
    first_link->unlink();                       // Unlink from list
 
539
    return first_link;
 
540
  }
 
541
  inline struct ilink *head()
 
542
  {
 
543
    return (first != &last) ? first : 0;
 
544
  }
 
545
  friend class base_list_iterator;
 
546
};
 
547
 
 
548
 
 
549
class base_ilist_iterator
 
550
{
 
551
  base_ilist *list;
 
552
  struct ilink **el,*current;
 
553
public:
 
554
  base_ilist_iterator(base_ilist &list_par) :list(&list_par),
 
555
    el(&list_par.first),current(0) {}
 
556
  void *next(void)
 
557
  {
 
558
    /* This is coded to allow push_back() while iterating */
 
559
    current= *el;
 
560
    if (current == &list->last) return 0;
 
561
    el= &current->next;
 
562
    return current;
 
563
  }
 
564
};
 
565
 
 
566
 
 
567
template <class T>
 
568
class I_List :private base_ilist
 
569
{
 
570
public:
 
571
  I_List() :base_ilist()        {}
 
572
  inline void empty()           { base_ilist::empty(); }
 
573
  inline bool is_empty()        { return base_ilist::is_empty(); } 
 
574
  inline void append(T* a)      { base_ilist::append(a); }
 
575
  inline void push_back(T* a)   { base_ilist::push_back(a); }
 
576
  inline T* get()               { return (T*) base_ilist::get(); }
 
577
  inline T* head()              { return (T*) base_ilist::head(); }
 
578
#ifndef _lint
 
579
  friend class I_List_iterator<T>;
 
580
#endif
 
581
};
 
582
 
 
583
 
 
584
template <class T> class I_List_iterator :public base_ilist_iterator
 
585
{
 
586
public:
 
587
  I_List_iterator(I_List<T> &a) : base_ilist_iterator(a) {}
 
588
  inline T* operator++(int) { return (T*) base_ilist_iterator::next(); }
 
589
};
 
590
 
450
591
/**
451
592
  Make a deep copy of each list element.
452
593
 
465
606
template <typename T>
466
607
inline
467
608
void
468
 
list_copy_and_replace_each_value(List<T> &list, memory::Root *mem_root)
 
609
list_copy_and_replace_each_value(List<T> &list, MEM_ROOT *mem_root)
469
610
{
470
611
  /* Make a deep copy of each element */
471
612
  List_iterator<T> it(list);
474
615
    it.replace(el->clone(mem_root));
475
616
}
476
617
 
477
 
} /* namespace drizzled */
478
 
 
479
 
#endif /* DRIZZLED_SQL_LIST_H */
 
618
#endif // DRIZZLED_SQL_LIST_H