~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_list.h

move functions from item.cc/item.h to item directory

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
  }
 
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);
133
135
  inline base_list(bool) { }
134
136
  inline bool push_back(void *info)
135
137
  {
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(); }
431
433
  inline T *replace(T *)   { return (T*) 0; }
432
434
  inline T *replace(List<T> &) { return (T*) 0; }
433
435
  inline void remove(void)  { }
434
 
  inline void after(T *)   { }
 
436
  inline void after(T *a)   { }
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, size_t)
 
465
  {
 
466
     free((unsigned char*)ptr_arg);
 
467
  }
 
468
 
 
469
  inline ilink()
 
470
  {
 
471
    prev=0; next=0;
 
472
  }
 
473
  inline void unlink()
 
474
  {
 
475
    /* Extra tests because element doesn't have to be linked */
 
476
    if (prev) *prev= next;
 
477
    if (next) next->prev=prev;
 
478
    prev=0 ; next=0;
 
479
  }
 
480
  virtual ~ilink() { unlink(); }                /*lint -e1740 */
 
481
};
 
482
 
 
483
 
 
484
/* Needed to be able to have an I_List of char* strings in mysqld.cc. */
 
485
 
 
486
class i_string: public ilink
 
487
{
 
488
public:
 
489
  const char* ptr;
 
490
  i_string():ptr(0) { }
 
491
  i_string(const char* s) : ptr(s) {}
 
492
};
 
493
 
 
494
/* needed for linked list of two strings for replicate-rewrite-db */
 
495
class i_string_pair: public ilink
 
496
{
 
497
public:
 
498
  const char* key;
 
499
  const char* val;
 
500
  i_string_pair():key(0),val(0) { }
 
501
  i_string_pair(const char* key_arg, const char* val_arg) : 
 
502
    key(key_arg),val(val_arg) {}
 
503
};
 
504
 
 
505
 
 
506
template <class T> class I_List_iterator;
 
507
 
 
508
/*
 
509
  WARNING: copy constructor of this class does not create a usable
 
510
  copy, as its members may point at each other.
 
511
*/
 
512
 
 
513
class base_ilist
 
514
{
 
515
public:
 
516
  struct ilink *first,last;
 
517
  inline void empty() { first= &last; last.prev= &first; }
 
518
  base_ilist() { empty(); }
 
519
  inline bool is_empty() {  return first == &last; }
 
520
  inline void append(ilink *a)
 
521
  {
 
522
    first->prev= &a->next;
 
523
    a->next=first; a->prev= &first; first=a;
 
524
  }
 
525
  inline void push_back(ilink *a)
 
526
  {
 
527
    *last.prev= a;
 
528
    a->next= &last;
 
529
    a->prev= last.prev;
 
530
    last.prev= &a->next;
 
531
  }
 
532
  inline struct ilink *get()
 
533
  {
 
534
    struct ilink *first_link=first;
 
535
    if (first_link == &last)
 
536
      return 0;
 
537
    first_link->unlink();                       // Unlink from list
 
538
    return first_link;
 
539
  }
 
540
  inline struct ilink *head()
 
541
  {
 
542
    return (first != &last) ? first : 0;
 
543
  }
 
544
  friend class base_list_iterator;
 
545
};
 
546
 
 
547
 
 
548
class base_ilist_iterator
 
549
{
 
550
  base_ilist *list;
 
551
  struct ilink **el,*current;
 
552
public:
 
553
  base_ilist_iterator(base_ilist &list_par) :list(&list_par),
 
554
    el(&list_par.first),current(0) {}
 
555
  void *next(void)
 
556
  {
 
557
    /* This is coded to allow push_back() while iterating */
 
558
    current= *el;
 
559
    if (current == &list->last) return 0;
 
560
    el= &current->next;
 
561
    return current;
 
562
  }
 
563
};
 
564
 
 
565
 
 
566
template <class T>
 
567
class I_List :private base_ilist
 
568
{
 
569
public:
 
570
  I_List() :base_ilist()        {}
 
571
  inline void empty()           { base_ilist::empty(); }
 
572
  inline bool is_empty()        { return base_ilist::is_empty(); } 
 
573
  inline void append(T* a)      { base_ilist::append(a); }
 
574
  inline void push_back(T* a)   { base_ilist::push_back(a); }
 
575
  inline T* get()               { return (T*) base_ilist::get(); }
 
576
  inline T* head()              { return (T*) base_ilist::head(); }
 
577
#ifndef _lint
 
578
  friend class I_List_iterator<T>;
 
579
#endif
 
580
};
 
581
 
 
582
 
 
583
template <class T> class I_List_iterator :public base_ilist_iterator
 
584
{
 
585
public:
 
586
  I_List_iterator(I_List<T> &a) : base_ilist_iterator(a) {}
 
587
  inline T* operator++(int) { return (T*) base_ilist_iterator::next(); }
 
588
};
 
589
 
450
590
/**
451
591
  Make a deep copy of each list element.
452
592
 
465
605
template <typename T>
466
606
inline
467
607
void
468
 
list_copy_and_replace_each_value(List<T> &list, memory::Root *mem_root)
 
608
list_copy_and_replace_each_value(List<T> &list, MEM_ROOT *mem_root)
469
609
{
470
610
  /* Make a deep copy of each element */
471
611
  List_iterator<T> it(list);
474
614
    it.replace(el->clone(mem_root));
475
615
}
476
616
 
477
 
} /* namespace drizzled */
478
 
 
479
 
#endif /* DRIZZLED_SQL_LIST_H */
 
617
/* sql_list.cc */
 
618
void free_list(I_List <i_string_pair> *list);
 
619
void free_list(I_List <i_string> *list);
 
620
 
 
621
 
 
622
#endif // DRIZZLED_SQL_LIST_H