diff options
author | unknown <kostja@bodhi.local> | 2006-12-12 01:23:30 +0300 |
---|---|---|
committer | unknown <kostja@bodhi.local> | 2006-12-12 01:23:30 +0300 |
commit | 3e3990433a0c8ec7cea01274909fdb17024519e8 (patch) | |
tree | 3a662cb0552120a80c60d29abb3b2f97c9d177b2 /sql/sql_list.h | |
parent | fe84b016e1fd62d92c9f13a1e21784ea8cb200cd (diff) | |
parent | e47ded8114f0b692a2ecf010998edcad46e6c2b3 (diff) | |
download | mariadb-git-3e3990433a0c8ec7cea01274909fdb17024519e8.tar.gz |
Merge bodhi.local:/opt/local/work/mysql-4.1-4968
into bodhi.local:/opt/local/work/mysql-5.0-4968-pull-from-4.1
sql/sql_insert.cc:
Auto merged
mysql-test/r/ps.result:
Manual merge.
mysql-test/t/ps.test:
Manual merge.
sql/mysql_priv.h:
Manual merge.
sql/sql_class.h:
Manual merge.
sql/sql_lex.cc:
Manual merge.
sql/sql_lex.h:
Manual merge.
sql/sql_list.h:
Manual merge.
sql/sql_parse.cc:
Manual merge.
sql/sql_show.cc:
Manual merge.
sql/sql_table.cc:
Manual merge.
sql/sql_yacc.yy:
Manual merge.
Diffstat (limited to 'sql/sql_list.h')
-rw-r--r-- | sql/sql_list.h | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/sql/sql_list.h b/sql/sql_list.h index afad6d0f6ac..c1989590d2d 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -62,21 +62,24 @@ public: pointer. */ -class list_node :public Sql_alloc + +/** + list_node - a node of a single-linked list. + @note We never call a destructor for instances of this class. +*/ + +struct list_node :public Sql_alloc { -public: list_node *next; void *info; list_node(void *info_par,list_node *next_par) :next(next_par),info(info_par) - {} + {} list_node() /* For end_of_list */ - { - info=0; - next= this; - } - friend class base_list; - friend class base_list_iterator; + { + info= 0; + next= this; + } }; @@ -92,12 +95,57 @@ public: inline void empty() { elements=0; first= &end_of_list; last=&first;} inline base_list() { empty(); } + /** + This is a shallow copy constructor that implicitly passes the ownership + from the source list to the new instance. The old instance is not + updated, so both objects end up sharing the same nodes. If one of + the instances then adds or removes a node, the other becomes out of + sync ('last' pointer), while still operational. Some old code uses and + relies on this behaviour. This logic is quite tricky: please do not use + it in any new code. + */ inline base_list(const base_list &tmp) :Sql_alloc() { elements= tmp.elements; first= tmp.first; last= elements ? tmp.last : &first; } + /** + Construct a deep copy of the argument in memory root mem_root. + The elements themselves are copied by pointer. + */ + inline base_list(const base_list &rhs, MEM_ROOT *mem_root) + { + if (rhs.elements) + { + /* + It's okay to allocate an array of nodes at once: we never + call a destructor for list_node objects anyway. + */ + first= (list_node*) alloc_root(mem_root, + sizeof(list_node) * rhs.elements); + if (first) + { + elements= rhs.elements; + list_node *dst= first; + list_node *src= rhs.first; + for (; dst < first + elements - 1; dst++, src= src->next) + { + dst->info= src->info; + dst->next= dst + 1; + } + /* Copy the last node */ + dst->info= src->info; + dst->next= &end_of_list; + /* Setup 'last' member */ + last= &dst->next; + return; + } + } + elements= 0; + first= &end_of_list; + last= &first; + } inline base_list(bool error) { } inline bool push_back(void *info) { @@ -348,6 +396,8 @@ template <class T> class List :public base_list public: inline List() :base_list() {} inline List(const List<T> &tmp) :base_list(tmp) {} + inline List(const List<T> &tmp, MEM_ROOT *mem_root) : + base_list(tmp, mem_root) {} inline bool push_back(T *a) { return base_list::push_back(a); } inline bool push_back(T *a, MEM_ROOT *mem_root) { return base_list::push_back(a, mem_root); } |