~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_list.h

  • Committer: Brian Aker
  • Date: 2010-02-07 01:33:54 UTC
  • Revision ID: brian@gaz-20100207013354-d2pg1n68u5c09pgo
Remove giant include header to its own file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#ifndef INCLUDES_DRIZZLE_SQL_LIST_H
2
 
#define INCLUDES_DRIZZLE_SQL_LIST_H
3
 
/* Copyright (C) 2000-2003 MySQL AB
4
 
 
5
 
   This program is free software; you can redistribute it and/or modify
6
 
   it under the terms of the GNU General Public License as published by
7
 
   the Free Software Foundation; version 2 of the License.
8
 
 
9
 
   This program is distributed in the hope that it will be useful,
10
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
   GNU General Public License for more details.
13
 
 
14
 
   You should have received a copy of the GNU General Public License
15
 
   along with this program; if not, write to the Free Software
16
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
17
 
 
18
 
 
19
 
#ifdef USE_PRAGMA_INTERFACE
20
 
#pragma interface                       /* gcc class implementation */
21
 
#endif
22
 
                                  
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#ifndef DRIZZLED_SQL_LIST_H
 
21
#define DRIZZLED_SQL_LIST_H
 
22
 
 
23
 
 
24
#include <cstdlib>
 
25
#include <cassert>
 
26
#include <utility>
 
27
#include <algorithm>
 
28
#include "drizzled/memory/sql_alloc.h"
 
29
 
 
30
namespace drizzled
 
31
{
 
32
 
23
33
/** Struct to handle simple linked lists. */
24
34
typedef struct st_sql_list {
25
 
  uint elements;
26
 
  uchar *first;
27
 
  uchar **next;
 
35
  uint32_t elements;
 
36
  unsigned char *first;
 
37
  unsigned char **next;
28
38
 
29
39
  st_sql_list() {}                              /* Remove gcc warning */
30
40
  inline void empty()
33
43
    first=0;
34
44
    next= &first;
35
45
  }
36
 
  inline void link_in_list(uchar *element,uchar **next_ptr)
 
46
  inline void link_in_list(unsigned char *element,unsigned char **next_ptr)
37
47
  {
38
48
    elements++;
39
49
    (*next)=element;
62
72
  }
63
73
} SQL_LIST;
64
74
 
65
 
/* mysql standard class memory allocator */
66
 
class Sql_alloc
67
 
{
68
 
public:
69
 
  static void *operator new(size_t size) throw ()
70
 
  {
71
 
    return sql_alloc(size);
72
 
  }
73
 
  static void *operator new[](size_t size)
74
 
  {
75
 
    return sql_alloc(size);
76
 
  }
77
 
  static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
78
 
  { return alloc_root(mem_root, size); }
79
 
  static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
80
 
  { return alloc_root(mem_root, size); }
81
 
  static void operator delete(void *ptr __attribute__((unused)),
82
 
                              size_t size __attribute__((unused)))
83
 
  { TRASH(ptr, size); }
84
 
  static void operator delete(void *ptr __attribute__((unused)),
85
 
                              MEM_ROOT *mem_root __attribute__((unused)))
86
 
  { /* never called */ }
87
 
  static void operator delete[](void *ptr __attribute__((unused)),
88
 
                                MEM_ROOT *mem_root __attribute__((unused)))
89
 
  { /* never called */ }
90
 
  static void operator delete[](void *ptr __attribute__((unused)),
91
 
                                size_t size __attribute__((unused)))
92
 
  { TRASH(ptr, size); }
93
 
#ifdef HAVE_purify
94
 
  bool dummy;
95
 
  inline Sql_alloc() :dummy(0) {}
96
 
  inline ~Sql_alloc() {}
97
 
#else
98
 
  inline Sql_alloc() {}
99
 
  inline ~Sql_alloc() {}
100
 
#endif
101
 
 
102
 
};
103
 
 
104
 
 
105
75
/*
106
76
  Basic single linked list
107
77
  Used for item and item_buffs.
118
88
  @note We never call a destructor for instances of this class.
119
89
*/
120
90
 
121
 
struct list_node :public Sql_alloc
 
91
struct list_node : public memory::SqlAlloc
122
92
{
123
93
  list_node *next;
124
94
  void *info;
135
105
 
136
106
extern list_node end_of_list;
137
107
 
138
 
class base_list :public Sql_alloc
 
108
class base_list :public memory::SqlAlloc
139
109
{
140
110
protected:
141
111
  list_node *first,**last;
142
112
 
143
113
public:
144
 
  uint elements;
 
114
  uint32_t elements;
145
115
 
146
116
  inline void empty() { elements=0; first= &end_of_list; last=&first;}
147
117
  inline base_list() { empty(); }
154
124
    relies on this behaviour. This logic is quite tricky: please do not use
155
125
    it in any new code.
156
126
  */
157
 
  inline base_list(const base_list &tmp) :Sql_alloc()
 
127
  inline base_list(const base_list &tmp) :memory::SqlAlloc()
158
128
  {
159
129
    elements= tmp.elements;
160
130
    first= tmp.first;
161
131
    last= elements ? tmp.last : &first;
162
132
  }
163
 
  /**
164
 
    Construct a deep copy of the argument in memory root mem_root.
165
 
    The elements themselves are copied by pointer. If you also
166
 
    need to copy elements by value, you should employ
167
 
    list_copy_and_replace_each_value after creating a copy.
168
 
  */
169
 
  base_list(const base_list &rhs, MEM_ROOT *mem_root);
170
 
  inline base_list(bool error __attribute__((unused))) { }
 
133
  inline base_list(bool) { }
171
134
  inline bool push_back(void *info)
172
135
  {
173
136
    if (((*last)=new list_node(info, &end_of_list)))
178
141
    }
179
142
    return 1;
180
143
  }
181
 
  inline bool push_back(void *info, MEM_ROOT *mem_root)
 
144
  inline bool push_back(void *info, memory::Root *mem_root)
182
145
  {
183
146
    if (((*last)=new (mem_root) list_node(info, &end_of_list)))
184
147
    {
258
221
  */
259
222
  inline void swap(base_list &rhs)
260
223
  {
261
 
    swap_variables(list_node *, first, rhs.first);
262
 
    swap_variables(list_node **, last, rhs.last);
263
 
    swap_variables(uint, elements, rhs.elements);
 
224
    std::swap(first, rhs.first);
 
225
    std::swap(last, rhs.last);
 
226
    std::swap(elements, rhs.elements);
264
227
  }
265
228
  inline list_node* last_node() { return *last; }
266
229
  inline list_node* first_node() { return first;}
283
246
      check_list()
284
247
        name  Name to print to trace file
285
248
 
286
 
    RETURN 
 
249
    RETURN
287
250
      1  The list is Ok.
288
251
      0  List invariants are not met.
289
252
  */
292
255
  {
293
256
    base_list *list= this;
294
257
    list_node *node= first;
295
 
    uint cnt= 0;
 
258
    uint32_t cnt= 0;
296
259
 
297
260
    while (node->next != &end_of_list)
298
261
    {
332
295
protected:
333
296
  base_list *list;
334
297
  list_node **el,**prev,*current;
335
 
  void sublist(base_list &ls, uint elm)
 
298
  void sublist(base_list &ls, uint32_t elm)
336
299
  {
337
300
    ls.first= *el;
338
301
    ls.last= list->last;
339
302
    ls.elements= elm;
340
303
  }
341
304
public:
342
 
  base_list_iterator() 
 
305
  base_list_iterator()
343
306
    :list(0), el(0), prev(0), current(0)
344
307
  {}
345
308
 
346
 
  base_list_iterator(base_list &list_par) 
 
309
  base_list_iterator(base_list &list_par)
347
310
  { init(list_par); }
348
311
 
349
312
  inline void init(base_list &list_par)
421
384
public:
422
385
  inline List() :base_list() {}
423
386
  inline List(const List<T> &tmp) :base_list(tmp) {}
424
 
  inline List(const List<T> &tmp, MEM_ROOT *mem_root) :
 
387
  inline List(const List<T> &tmp, memory::Root *mem_root) :
425
388
    base_list(tmp, mem_root) {}
426
389
  inline bool push_back(T *a) { return base_list::push_back(a); }
427
 
  inline bool push_back(T *a, MEM_ROOT *mem_root)
 
390
  inline bool push_back(T *a, memory::Root *mem_root)
428
391
  { return base_list::push_back(a, mem_root); }
429
392
  inline bool push_front(T *a) { return base_list::push_front(a); }
430
393
  inline T* head() {return (T*) base_list::head(); }
465
428
template <class T> class List_iterator_fast :public base_list_iterator
466
429
{
467
430
protected:
468
 
  inline T *replace(T *a __attribute__((unused)))   { return (T*) 0; }
469
 
  inline T *replace(List<T> &a __attribute__((unused))) { return (T*) 0; }
 
431
  inline T *replace(T *)   { return (T*) 0; }
 
432
  inline T *replace(List<T> &) { return (T*) 0; }
470
433
  inline void remove(void)  { }
471
 
  inline void after(T *a __attribute__((unused)))   { }
 
434
  inline void after(T *a)   { }
472
435
  inline T** ref(void)      { return (T**) 0; }
473
436
 
474
437
public:
477
440
  inline void init(List<T> &a) { base_list_iterator::init(a); }
478
441
  inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
479
442
  inline void rewind(void)  { base_list_iterator::rewind(); }
480
 
  void sublist(List<T> &list_arg, uint el_arg)
 
443
  void sublist(List<T> &list_arg, uint32_t el_arg)
481
444
  {
482
445
    base_list_iterator::sublist(list_arg, el_arg);
483
446
  }
484
447
};
485
448
 
486
449
 
487
 
/*
488
 
  A simple intrusive list which automaticly removes element from list
489
 
  on delete (for THD element)
490
 
*/
491
 
 
492
 
struct ilink
493
 
{
494
 
  struct ilink **prev,*next;
495
 
  static void *operator new(size_t size)
496
 
  {
497
 
    return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE | ME_FATALERROR));
498
 
  }
499
 
  static void operator delete(void* ptr_arg,
500
 
                              size_t size __attribute__((unused)))
501
 
  {
502
 
     my_free((uchar*)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
503
 
  }
504
 
 
505
 
  inline ilink()
506
 
  {
507
 
    prev=0; next=0;
508
 
  }
509
 
  inline void unlink()
510
 
  {
511
 
    /* Extra tests because element doesn't have to be linked */
512
 
    if (prev) *prev= next;
513
 
    if (next) next->prev=prev;
514
 
    prev=0 ; next=0;
515
 
  }
516
 
  virtual ~ilink() { unlink(); }                /*lint -e1740 */
517
 
};
518
 
 
519
 
 
520
 
/* Needed to be able to have an I_List of char* strings in mysqld.cc. */
521
 
 
522
 
class i_string: public ilink
523
 
{
524
 
public:
525
 
  const char* ptr;
526
 
  i_string():ptr(0) { }
527
 
  i_string(const char* s) : ptr(s) {}
528
 
};
529
 
 
530
 
/* needed for linked list of two strings for replicate-rewrite-db */
531
 
class i_string_pair: public ilink
532
 
{
533
 
public:
534
 
  const char* key;
535
 
  const char* val;
536
 
  i_string_pair():key(0),val(0) { }
537
 
  i_string_pair(const char* key_arg, const char* val_arg) : 
538
 
    key(key_arg),val(val_arg) {}
539
 
};
540
 
 
541
 
 
542
 
template <class T> class I_List_iterator;
543
 
 
544
 
/*
545
 
  WARNING: copy constructor of this class does not create a usable
546
 
  copy, as its members may point at each other.
547
 
*/
548
 
 
549
 
class base_ilist
550
 
{
551
 
public:
552
 
  struct ilink *first,last;
553
 
  inline void empty() { first= &last; last.prev= &first; }
554
 
  base_ilist() { empty(); }
555
 
  inline bool is_empty() {  return first == &last; }
556
 
  inline void append(ilink *a)
557
 
  {
558
 
    first->prev= &a->next;
559
 
    a->next=first; a->prev= &first; first=a;
560
 
  }
561
 
  inline void push_back(ilink *a)
562
 
  {
563
 
    *last.prev= a;
564
 
    a->next= &last;
565
 
    a->prev= last.prev;
566
 
    last.prev= &a->next;
567
 
  }
568
 
  inline struct ilink *get()
569
 
  {
570
 
    struct ilink *first_link=first;
571
 
    if (first_link == &last)
572
 
      return 0;
573
 
    first_link->unlink();                       // Unlink from list
574
 
    return first_link;
575
 
  }
576
 
  inline struct ilink *head()
577
 
  {
578
 
    return (first != &last) ? first : 0;
579
 
  }
580
 
  friend class base_list_iterator;
581
 
};
582
 
 
583
 
 
584
 
class base_ilist_iterator
585
 
{
586
 
  base_ilist *list;
587
 
  struct ilink **el,*current;
588
 
public:
589
 
  base_ilist_iterator(base_ilist &list_par) :list(&list_par),
590
 
    el(&list_par.first),current(0) {}
591
 
  void *next(void)
592
 
  {
593
 
    /* This is coded to allow push_back() while iterating */
594
 
    current= *el;
595
 
    if (current == &list->last) return 0;
596
 
    el= &current->next;
597
 
    return current;
598
 
  }
599
 
};
600
 
 
601
 
 
602
 
template <class T>
603
 
class I_List :private base_ilist
604
 
{
605
 
public:
606
 
  I_List() :base_ilist()        {}
607
 
  inline void empty()           { base_ilist::empty(); }
608
 
  inline bool is_empty()        { return base_ilist::is_empty(); } 
609
 
  inline void append(T* a)      { base_ilist::append(a); }
610
 
  inline void push_back(T* a)   { base_ilist::push_back(a); }
611
 
  inline T* get()               { return (T*) base_ilist::get(); }
612
 
  inline T* head()              { return (T*) base_ilist::head(); }
613
 
#ifndef _lint
614
 
  friend class I_List_iterator<T>;
615
 
#endif
616
 
};
617
 
 
618
 
 
619
 
template <class T> class I_List_iterator :public base_ilist_iterator
620
 
{
621
 
public:
622
 
  I_List_iterator(I_List<T> &a) : base_ilist_iterator(a) {}
623
 
  inline T* operator++(int) { return (T*) base_ilist_iterator::next(); }
624
 
};
625
 
 
626
450
/**
627
451
  Make a deep copy of each list element.
628
452
 
634
458
  Evidently not all template arguments have clone() method with
635
459
  the right signature.
636
460
 
637
 
  @return You must query the error state in THD for out-of-memory
 
461
  @return You must query the error state in Session for out-of-memory
638
462
  situation after calling this function.
639
463
*/
640
464
 
641
465
template <typename T>
642
466
inline
643
467
void
644
 
list_copy_and_replace_each_value(List<T> &list, MEM_ROOT *mem_root)
 
468
list_copy_and_replace_each_value(List<T> &list, memory::Root *mem_root)
645
469
{
646
470
  /* Make a deep copy of each element */
647
471
  List_iterator<T> it(list);
650
474
    it.replace(el->clone(mem_root));
651
475
}
652
476
 
653
 
#endif // INCLUDES_DRIZZLE_SQL_LIST_H
 
477
} /* namespace drizzled */
 
478
 
 
479
#endif /* DRIZZLED_SQL_LIST_H */