summaryrefslogtreecommitdiff
path: root/sql/sql_list.h
diff options
context:
space:
mode:
authorunknown <kostja@bodhi.local>2006-12-12 01:23:30 +0300
committerunknown <kostja@bodhi.local>2006-12-12 01:23:30 +0300
commit3e3990433a0c8ec7cea01274909fdb17024519e8 (patch)
tree3a662cb0552120a80c60d29abb3b2f97c9d177b2 /sql/sql_list.h
parentfe84b016e1fd62d92c9f13a1e21784ea8cb200cd (diff)
parente47ded8114f0b692a2ecf010998edcad46e6c2b3 (diff)
downloadmariadb-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.h68
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); }