~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_list.h

  • Committer: Monty Taylor
  • Date: 2008-10-22 21:31:15 UTC
  • Revision ID: monty@inaugust.com-20081022213115-xuxc80r939tl88p1
Renamed drizzle_common again. Removed sql_common. (empty) 
Now all we need to do is merge/disect base.h, common.h, common_includes.h, server_includes.h and globa.h (good grief)

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#ifndef DRIZZLED_SQL_LIST_H
21
 
#define DRIZZLED_SQL_LIST_H
22
 
 
23
 
 
24
 
#include <cstdlib>
25
 
#include <cassert>
 
20
#ifndef INCLUDES_DRIZZLE_SQL_LIST_H
 
21
#define INCLUDES_DRIZZLE_SQL_LIST_H
 
22
 
 
23
 
26
24
#include <utility>
27
25
#include <algorithm>
28
 
#include "drizzled/memory/sql_alloc.h"
29
 
 
30
 
namespace drizzled
31
 
{
32
26
 
33
27
/** Struct to handle simple linked lists. */
34
28
typedef struct st_sql_list {
72
66
  }
73
67
} SQL_LIST;
74
68
 
 
69
/* mysql standard class memory allocator */
 
70
class Sql_alloc
 
71
{
 
72
public:
 
73
  static void *operator new(size_t size) throw ()
 
74
  {
 
75
    return sql_alloc(size);
 
76
  }
 
77
  static void *operator new[](size_t size)
 
78
  {
 
79
    return sql_alloc(size);
 
80
  }
 
81
  static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
 
82
  { return alloc_root(mem_root, size); }
 
83
  static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
 
84
  { return alloc_root(mem_root, size); }
 
85
  static void operator delete(void *ptr __attribute__((unused)),
 
86
                              size_t size __attribute__((unused)))
 
87
  { TRASH(ptr, size); }
 
88
  static void operator delete(void *ptr __attribute__((unused)),
 
89
                              MEM_ROOT *mem_root __attribute__((unused)))
 
90
  { /* never called */ }
 
91
  static void operator delete[](void *ptr __attribute__((unused)),
 
92
                                MEM_ROOT *mem_root __attribute__((unused)))
 
93
  { /* never called */ }
 
94
  static void operator delete[](void *ptr __attribute__((unused)),
 
95
                                size_t size __attribute__((unused)))
 
96
  { TRASH(ptr, size); }
 
97
#ifdef HAVE_purify
 
98
  bool dummy;
 
99
  inline Sql_alloc() :dummy(0) {}
 
100
  inline ~Sql_alloc() {}
 
101
#else
 
102
  inline Sql_alloc() {}
 
103
  inline ~Sql_alloc() {}
 
104
#endif
 
105
 
 
106
};
 
107
 
 
108
 
75
109
/*
76
110
  Basic single linked list
77
111
  Used for item and item_buffs.
88
122
  @note We never call a destructor for instances of this class.
89
123
*/
90
124
 
91
 
struct list_node : public memory::SqlAlloc
 
125
struct list_node :public Sql_alloc
92
126
{
93
127
  list_node *next;
94
128
  void *info;
105
139
 
106
140
extern list_node end_of_list;
107
141
 
108
 
class base_list :public memory::SqlAlloc
 
142
class base_list :public Sql_alloc
109
143
{
110
144
protected:
111
145
  list_node *first,**last;
124
158
    relies on this behaviour. This logic is quite tricky: please do not use
125
159
    it in any new code.
126
160
  */
127
 
  inline base_list(const base_list &tmp) :memory::SqlAlloc()
 
161
  inline base_list(const base_list &tmp) :Sql_alloc()
128
162
  {
129
163
    elements= tmp.elements;
130
164
    first= tmp.first;
131
165
    last= elements ? tmp.last : &first;
132
166
  }
133
 
  inline base_list(bool) { }
 
167
  /**
 
168
    Construct a deep copy of the argument in memory root mem_root.
 
169
    The elements themselves are copied by pointer. If you also
 
170
    need to copy elements by value, you should employ
 
171
    list_copy_and_replace_each_value after creating a copy.
 
172
  */
 
173
  base_list(const base_list &rhs, MEM_ROOT *mem_root);
 
174
  inline base_list(bool error __attribute__((unused))) { }
134
175
  inline bool push_back(void *info)
135
176
  {
136
177
    if (((*last)=new list_node(info, &end_of_list)))
141
182
    }
142
183
    return 1;
143
184
  }
144
 
  inline bool push_back(void *info, memory::Root *mem_root)
 
185
  inline bool push_back(void *info, MEM_ROOT *mem_root)
145
186
  {
146
187
    if (((*last)=new (mem_root) list_node(info, &end_of_list)))
147
188
    {
246
287
      check_list()
247
288
        name  Name to print to trace file
248
289
 
249
 
    RETURN
 
290
    RETURN 
250
291
      1  The list is Ok.
251
292
      0  List invariants are not met.
252
293
  */
302
343
    ls.elements= elm;
303
344
  }
304
345
public:
305
 
  base_list_iterator()
 
346
  base_list_iterator() 
306
347
    :list(0), el(0), prev(0), current(0)
307
348
  {}
308
349
 
309
 
  base_list_iterator(base_list &list_par)
 
350
  base_list_iterator(base_list &list_par) 
310
351
  { init(list_par); }
311
352
 
312
353
  inline void init(base_list &list_par)
384
425
public:
385
426
  inline List() :base_list() {}
386
427
  inline List(const List<T> &tmp) :base_list(tmp) {}
387
 
  inline List(const List<T> &tmp, memory::Root *mem_root) :
 
428
  inline List(const List<T> &tmp, MEM_ROOT *mem_root) :
388
429
    base_list(tmp, mem_root) {}
389
430
  inline bool push_back(T *a) { return base_list::push_back(a); }
390
 
  inline bool push_back(T *a, memory::Root *mem_root)
 
431
  inline bool push_back(T *a, MEM_ROOT *mem_root)
391
432
  { return base_list::push_back(a, mem_root); }
392
433
  inline bool push_front(T *a) { return base_list::push_front(a); }
393
434
  inline T* head() {return (T*) base_list::head(); }
428
469
template <class T> class List_iterator_fast :public base_list_iterator
429
470
{
430
471
protected:
431
 
  inline T *replace(T *)   { return (T*) 0; }
432
 
  inline T *replace(List<T> &) { return (T*) 0; }
 
472
  inline T *replace(T *a __attribute__((unused)))   { return (T*) 0; }
 
473
  inline T *replace(List<T> &a __attribute__((unused))) { return (T*) 0; }
433
474
  inline void remove(void)  { }
434
 
  inline void after(T *)   { }
 
475
  inline void after(T *a __attribute__((unused)))   { }
435
476
  inline T** ref(void)      { return (T**) 0; }
436
477
 
437
478
public:
447
488
};
448
489
 
449
490
 
 
491
/*
 
492
  A simple intrusive list which automaticly removes element from list
 
493
  on delete (for Session element)
 
494
*/
 
495
 
 
496
struct ilink
 
497
{
 
498
  struct ilink **prev,*next;
 
499
  static void *operator new(size_t size)
 
500
  {
 
501
    return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE | ME_FATALERROR));
 
502
  }
 
503
  static void operator delete(void* ptr_arg,
 
504
                              size_t size __attribute__((unused)))
 
505
  {
 
506
     free((unsigned char*)ptr_arg);
 
507
  }
 
508
 
 
509
  inline ilink()
 
510
  {
 
511
    prev=0; next=0;
 
512
  }
 
513
  inline void unlink()
 
514
  {
 
515
    /* Extra tests because element doesn't have to be linked */
 
516
    if (prev) *prev= next;
 
517
    if (next) next->prev=prev;
 
518
    prev=0 ; next=0;
 
519
  }
 
520
  virtual ~ilink() { unlink(); }                /*lint -e1740 */
 
521
};
 
522
 
 
523
 
 
524
/* Needed to be able to have an I_List of char* strings in mysqld.cc. */
 
525
 
 
526
class i_string: public ilink
 
527
{
 
528
public:
 
529
  const char* ptr;
 
530
  i_string():ptr(0) { }
 
531
  i_string(const char* s) : ptr(s) {}
 
532
};
 
533
 
 
534
/* needed for linked list of two strings for replicate-rewrite-db */
 
535
class i_string_pair: public ilink
 
536
{
 
537
public:
 
538
  const char* key;
 
539
  const char* val;
 
540
  i_string_pair():key(0),val(0) { }
 
541
  i_string_pair(const char* key_arg, const char* val_arg) : 
 
542
    key(key_arg),val(val_arg) {}
 
543
};
 
544
 
 
545
 
 
546
template <class T> class I_List_iterator;
 
547
 
 
548
/*
 
549
  WARNING: copy constructor of this class does not create a usable
 
550
  copy, as its members may point at each other.
 
551
*/
 
552
 
 
553
class base_ilist
 
554
{
 
555
public:
 
556
  struct ilink *first,last;
 
557
  inline void empty() { first= &last; last.prev= &first; }
 
558
  base_ilist() { empty(); }
 
559
  inline bool is_empty() {  return first == &last; }
 
560
  inline void append(ilink *a)
 
561
  {
 
562
    first->prev= &a->next;
 
563
    a->next=first; a->prev= &first; first=a;
 
564
  }
 
565
  inline void push_back(ilink *a)
 
566
  {
 
567
    *last.prev= a;
 
568
    a->next= &last;
 
569
    a->prev= last.prev;
 
570
    last.prev= &a->next;
 
571
  }
 
572
  inline struct ilink *get()
 
573
  {
 
574
    struct ilink *first_link=first;
 
575
    if (first_link == &last)
 
576
      return 0;
 
577
    first_link->unlink();                       // Unlink from list
 
578
    return first_link;
 
579
  }
 
580
  inline struct ilink *head()
 
581
  {
 
582
    return (first != &last) ? first : 0;
 
583
  }
 
584
  friend class base_list_iterator;
 
585
};
 
586
 
 
587
 
 
588
class base_ilist_iterator
 
589
{
 
590
  base_ilist *list;
 
591
  struct ilink **el,*current;
 
592
public:
 
593
  base_ilist_iterator(base_ilist &list_par) :list(&list_par),
 
594
    el(&list_par.first),current(0) {}
 
595
  void *next(void)
 
596
  {
 
597
    /* This is coded to allow push_back() while iterating */
 
598
    current= *el;
 
599
    if (current == &list->last) return 0;
 
600
    el= &current->next;
 
601
    return current;
 
602
  }
 
603
};
 
604
 
 
605
 
 
606
template <class T>
 
607
class I_List :private base_ilist
 
608
{
 
609
public:
 
610
  I_List() :base_ilist()        {}
 
611
  inline void empty()           { base_ilist::empty(); }
 
612
  inline bool is_empty()        { return base_ilist::is_empty(); } 
 
613
  inline void append(T* a)      { base_ilist::append(a); }
 
614
  inline void push_back(T* a)   { base_ilist::push_back(a); }
 
615
  inline T* get()               { return (T*) base_ilist::get(); }
 
616
  inline T* head()              { return (T*) base_ilist::head(); }
 
617
#ifndef _lint
 
618
  friend class I_List_iterator<T>;
 
619
#endif
 
620
};
 
621
 
 
622
 
 
623
template <class T> class I_List_iterator :public base_ilist_iterator
 
624
{
 
625
public:
 
626
  I_List_iterator(I_List<T> &a) : base_ilist_iterator(a) {}
 
627
  inline T* operator++(int) { return (T*) base_ilist_iterator::next(); }
 
628
};
 
629
 
450
630
/**
451
631
  Make a deep copy of each list element.
452
632
 
465
645
template <typename T>
466
646
inline
467
647
void
468
 
list_copy_and_replace_each_value(List<T> &list, memory::Root *mem_root)
 
648
list_copy_and_replace_each_value(List<T> &list, MEM_ROOT *mem_root)
469
649
{
470
650
  /* Make a deep copy of each element */
471
651
  List_iterator<T> it(list);
474
654
    it.replace(el->clone(mem_root));
475
655
}
476
656
 
477
 
} /* namespace drizzled */
478
 
 
479
 
#endif /* DRIZZLED_SQL_LIST_H */
 
657
#endif // INCLUDES_DRIZZLE_SQL_LIST_H