mariadb/sql/sql_list.h
unknown 034b44cb9f Merge with 4.0.14
BitKeeper/etc/logging_ok:
  auto-union
scripts/make_win_src_distribution.old:
  Merge rename: scripts/make_win_src_distribution.sh -> scripts/make_win_src_distribution.old
BUILD/compile-pentium-debug-max:
  Auto merged
BitKeeper/deleted/.del-sel000001.result~383913ae4505ec86:
  Auto merged
BitKeeper/deleted/.del-sel000001.test~9567c1646058cc:
  Auto merged
Build-tools/Bootstrap:
  Auto merged
Build-tools/Do-compile:
  Auto merged
Docs/Makefile.am:
  Auto merged
client/get_password.c:
  Auto merged
client/mysql.cc:
  Auto merged
client/mysqltest.c:
  Auto merged
extra/perror.c:
  Auto merged
include/config-win.h:
  Auto merged
include/my_sys.h:
  Auto merged
innobase/btr/btr0cur.c:
  Auto merged
innobase/btr/btr0pcur.c:
  Auto merged
innobase/buf/buf0buf.c:
  Auto merged
innobase/buf/buf0flu.c:
  Auto merged
innobase/dict/dict0dict.c:
  Auto merged
innobase/dict/dict0load.c:
  Auto merged
innobase/include/buf0buf.h:
  Auto merged
innobase/include/log0recv.h:
  Auto merged
innobase/include/row0sel.h:
  Auto merged
innobase/include/srv0srv.h:
  Auto merged
innobase/include/ut0mem.h:
  Auto merged
innobase/lock/lock0lock.c:
  Auto merged
innobase/log/log0log.c:
  Auto merged
innobase/mem/mem0pool.c:
  Auto merged
innobase/os/os0file.c:
  Auto merged
innobase/row/row0mysql.c:
  Auto merged
innobase/row/row0sel.c:
  Auto merged
innobase/srv/srv0srv.c:
  Auto merged
innobase/srv/srv0start.c:
  Auto merged
innobase/trx/trx0sys.c:
  Auto merged
innobase/trx/trx0trx.c:
  Auto merged
innobase/ut/ut0mem.c:
  Auto merged
innobase/ut/ut0ut.c:
  Auto merged
myisam/ft_boolean_search.c:
  Auto merged
myisam/mi_check.c:
  Auto merged
myisam/mi_extra.c:
  Auto merged
myisam/mi_key.c:
  Auto merged
myisam/myisamdef.h:
  Auto merged
myisammrg/myrg_queue.c:
  Auto merged
mysql-test/mysql-test-run.sh:
  Auto merged
mysql-test/r/ctype_latin1_de.result:
  Auto merged
mysql-test/r/flush.result:
  Auto merged
mysql-test/r/func_time.result:
  Auto merged
mysql-test/r/grant_cache.result:
  Auto merged
mysql-test/r/join.result:
  Auto merged
mysql-test/r/join_outer.result:
  Auto merged
mysql-test/r/range.result:
  Auto merged
mysql-test/r/rpl000018.result:
  Auto merged
mysql-test/r/rpl_insert_id.result:
  Auto merged
mysql-test/r/rpl_master_pos_wait.result:
  Auto merged
mysql-test/r/rpl_relayspace.result:
  Auto merged
mysql-test/r/select_safe.result:
  Auto merged
mysql-test/r/symlink.result:
  Auto merged
mysql-test/r/type_date.result:
  Auto merged
mysql-test/r/type_datetime.result:
  Auto merged
mysql-test/t/alias.test:
  Auto merged
mysql-test/t/ctype_latin1_de.test:
  Auto merged
mysql-test/t/fulltext_left_join.test:
  Auto merged
mysql-test/t/func_time.test:
  Auto merged
mysql-test/t/handler.test:
  Auto merged
mysql-test/t/heap.test:
  Auto merged
mysql-test/t/join.test:
  Auto merged
mysql-test/t/join_outer.test:
  Auto merged
mysql-test/t/order_by.test:
  Auto merged
mysql-test/t/range.test:
  Auto merged
mysql-test/t/rpl000001.test:
  Auto merged
mysql-test/t/rpl000018.test:
  Auto merged
mysql-test/t/rpl_insert_id.test:
  Auto merged
mysql-test/t/sel000100.test:
  Auto merged
mysql-test/t/select_safe.test:
  Auto merged
mysql-test/t/type_date.test:
  Auto merged
mysql-test/t/type_datetime.test:
  Auto merged
mysql-test/t/user_var.test:
  Auto merged
mysys/default.c:
  Auto merged
mysys/mf_format.c:
  Auto merged
mysys/my_getopt.c:
  Auto merged
mysys/thr_lock.c:
  Auto merged
mysys/tree.c:
  Auto merged
scripts/Makefile.am:
  Auto merged
scripts/mysql_install_db.sh:
  Auto merged
scripts/mysqld_safe.sh:
  Auto merged
sql/Makefile.am:
  Auto merged
sql/field_conv.cc:
  Auto merged
sql/ha_innodb.h:
  Auto merged
sql/ha_myisam.cc:
  Auto merged
sql/ha_myisammrg.h:
  Auto merged
sql/handler.cc:
  Auto merged
sql/handler.h:
  Auto merged
sql/item.h:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_timefunc.cc:
  Auto merged
sql/net_serv.cc:
  Auto merged
sql/nt_servc.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_cache.h:
  Auto merged
sql/sql_db.cc:
  Auto merged
sql/sql_delete.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_list.h:
  Auto merged
sql/sql_load.cc:
  Auto merged
sql/sql_rename.cc:
  Auto merged
sql/sql_repl.h:
  Auto merged
sql/sql_update.cc:
  Auto merged
sql/table.cc:
  Auto merged
sql/table.h:
  Auto merged
sql/uniques.cc:
  Auto merged
support-files/mysql.spec.sh:
  Auto merged
vio/viosocket.c:
  Auto merged
BitKeeper/deleted/.del-ctype-latin1_de.c~c5d8f9208bceb98e:
  merge
BitKeeper/deleted/.del-mini_client.cc~8677895ec8169183:
  merge
acinclude.m4:
  Merge with 4.0 (openssl patch)
client/mysqlbinlog.cc:
  Merge with 4.0 in which we had added code from 4.1
  (We are basicly only using the 4.1 code here)
configure.in:
  Keep 4.1 file
heap/hp_open.c:
  merge with 4.0
include/my_base.h:
  merge with 4.0
include/my_global.h:
  merge with 4.0
include/mysqld_error.h:
  merge with 4.0
innobase/ha/ha0ha.c:
  merge with 4.0
  (Code should be same but we use indentaion from 4.0)
innobase/log/log0recv.c:
  merge with 4.0
libmysql/libmysql.c:
  Remove with 4.0 code that was ported from 4.1
libmysqld/lib_sql.cc:
  merge with 4.0
myisam/mi_open.c:
  Remove 4.0 specific code
myisam/myisamchk.c:
  merge with 4.0
myisammrg/myrg_rkey.c:
  merge with 4.0
mysql-test/r/alter_table.result:
  May need to be fixed after merge
mysql-test/r/create.result:
  May need to be fixed after merge
mysql-test/r/distinct.result:
  May need to be fixed after merge
mysql-test/r/drop.result:
  May need to be fixed after merge
mysql-test/r/fulltext.result:
  May need to be fixed after merge
mysql-test/r/func_set.result:
  May need to be fixed after merge
mysql-test/r/func_str.result:
  May need to be fixed after merge
mysql-test/r/func_test.result:
  May need to be fixed after merge
mysql-test/r/grant.result:
  May need to be fixed after merge
mysql-test/r/group_by.result:
  May need to be fixed after merge
mysql-test/r/handler.result:
  May need to be fixed after merge
mysql-test/r/heap.result:
  May need to be fixed after merge
mysql-test/r/innodb.result:
  May need to be fixed after merge
mysql-test/r/insert.result:
  May need to be fixed after merge
mysql-test/r/insert_select.result:
  May need to be fixed after merge
mysql-test/r/key_diff.result:
  May need to be fixed after merge
mysql-test/r/merge.result:
  May need to be fixed after merge
mysql-test/r/myisam.result:
  May need to be fixed after merge
mysql-test/r/order_by.result:
  May need to be fixed after merge
mysql-test/r/query_cache.result:
  May need to be fixed after merge
mysql-test/r/rpl_flush_log_loop.result:
  May need to be fixed after merge
mysql-test/r/rpl_loaddata.result:
  May need to be fixed after merge
mysql-test/r/rpl_log.result:
  May need to be fixed after merge
mysql-test/r/rpl_log_pos.result:
  May need to be fixed after merge
mysql-test/r/rpl_rotate_logs.result:
  May need to be fixed after merge
mysql-test/r/select.result:
  May need to be fixed after merge
mysql-test/r/union.result:
  May need to be fixed after merge
mysql-test/r/user_var.result:
  May need to be fixed after merge
mysql-test/t/alter_table.test:
  merge with 4.0
mysql-test/t/create.test:
  merge with 4.0
mysql-test/t/distinct.test:
  merge with 4.0
mysql-test/t/drop.test:
  merge with 4.0
mysql-test/t/flush.test:
  merge with 4.0
mysql-test/t/fulltext.test:
  merge with 4.0
mysql-test/t/func_set.test:
  merge with 4.0
mysql-test/t/func_str.test:
  merge with 4.0
mysql-test/t/func_test.test:
  merge with 4.0
mysql-test/t/grant.test:
  merge with 4.0
mysql-test/t/grant_cache.test:
  merge with 4.0
mysql-test/t/innodb.test:
  Add back EXPLAIN and SHOW KEYS statements, but make them independent of number of rows returned by InnoDB
mysql-test/t/insert.test:
  merge with 4.0
mysql-test/t/insert_select.test:
  merge with 4.0
mysql-test/t/merge.test:
  merge with 4.0
mysql-test/t/query_cache.test:
  merge with 4.0
mysql-test/t/rpl_flush_log_loop.test:
  merge with 4.0
mysql-test/t/rpl_loaddata.test:
  merge with 4.0
mysql-test/t/rpl_rotate_logs.test:
  merge with 4.0
mysql-test/t/select.test:
  merge with 4.0
mysql-test/t/symlink.test:
  merge with 4.0
mysql-test/t/union.test:
  merge with 4.0
mysys/charset.c:
  merge with 4.0
scripts/mysql_fix_privilege_tables.sh:
  merge with 4.0 (Add quoting for some variables)
sql/field.h:
  merge with 4.0
sql/ha_innodb.cc:
  merge with 4.0
sql/item_cmpfunc.cc:
  merge with 4.0
sql/item_cmpfunc.h:
  merge with 4.0
sql/item_func.h:
  merge with 4.0
sql/item_strfunc.cc:
  merge with 4.0
  Fixed null handling with ELT()
sql/item_timefunc.h:
  merge with 4.0
sql/lex.h:
  merge with 4.0
sql/log.cc:
  merge with 4.0
sql/log_event.cc:
  Merge with 4.0
  Cleanups:
  - Indentation
  - #endif comments
  - Replace strmov() with *pos++= for two byte strings
  - Moved variable declarations to start of functions
  - Merged identical code (LOAD_EVENT)
  - Added casts when subtracting pointers
  Did a full diff between this and 4.0 to ensure that the file is correct after merge.
sql/log_event.h:
  merge with 4.0
sql/mysql_priv.h:
  merge with 4.0
sql/mysqld.cc:
  merge with 4.0
sql/repl_failsafe.cc:
  merge with 4.0
sql/set_var.cc:
  merge with 4.0
sql/set_var.h:
  merge with 4.0
sql/share/czech/errmsg.txt:
  merge with 4.0
sql/share/danish/errmsg.txt:
  merge with 4.0
sql/share/dutch/errmsg.txt:
  merge with 4.0
sql/share/english/errmsg.txt:
  merge with 4.0
sql/share/estonian/errmsg.txt:
  merge with 4.0
sql/share/french/errmsg.txt:
  merge with 4.0
sql/share/german/errmsg.txt:
  merge with 4.0
sql/share/greek/errmsg.txt:
  merge with 4.0
sql/share/hungarian/errmsg.txt:
  merge with 4.0
sql/share/italian/errmsg.txt:
  merge with 4.0
sql/share/japanese/errmsg.txt:
  merge with 4.0
sql/share/korean/errmsg.txt:
  merge with 4.0
sql/share/norwegian-ny/errmsg.txt:
  merge with 4.0
sql/share/norwegian/errmsg.txt:
  merge with 4.0
sql/share/polish/errmsg.txt:
  merge with 4.0
sql/share/portuguese/errmsg.txt:
  merge with 4.0
sql/share/romanian/errmsg.txt:
  merge with 4.0
sql/share/russian/errmsg.txt:
  merge with 4.0
sql/share/slovak/errmsg.txt:
  merge with 4.0
sql/share/spanish/errmsg.txt:
  merge with 4.0
sql/share/swedish/errmsg.txt:
  merge with 4.0
sql/share/ukrainian/errmsg.txt:
  merge with 4.0
sql/slave.cc:
  Merge + some indentation fixes
sql/slave.h:
  merge with 4.0
sql/sql_acl.cc:
  merge with 4.0
  Some end space removal to make it easier to do future merges
sql/sql_acl.h:
  merge with 4.0
sql/sql_cache.cc:
  merge with 4.0
sql/sql_class.h:
  merge with 4.0
sql/sql_handler.cc:
  merge with 4.0
sql/sql_lex.cc:
  merge with 4.0
sql/sql_lex.h:
  merge with 4.0
sql/sql_parse.cc:
  merge with 4.0
sql/sql_repl.cc:
  merge with 4.0
sql/sql_select.cc:
  merge with 4.0
sql/sql_table.cc:
  merge with 4.0
sql/sql_union.cc:
  Merge with 4.0
  Note that I couldn't find out how to merge OPTION_FOUND_ROWS handling so this has to be fixed later
sql/sql_yacc.yy:
  merge with 4.0
  Removed end space to make merge easier
vio/Makefile.am:
  merge with 4.0
2003-08-11 22:44:43 +03:00

397 lines
9.6 KiB
C++

/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
/* mysql standard class memoryallocator */
class Sql_alloc
{
public:
static void *operator new(size_t size)
{
return (void*) sql_alloc((uint) size);
}
static void *operator new[](size_t size)
{
return (void*) sql_alloc((uint) size);
}
static void *operator new(size_t size, MEM_ROOT *mem_root)
{ return (void*) alloc_root(mem_root, (uint) size); }
static void operator delete(void *ptr, size_t size) {} /*lint -e715 */
static void operator delete[](void *ptr, size_t size) {}
#ifdef HAVE_purify
bool dummy;
inline Sql_alloc() :dummy(0) {}
inline ~Sql_alloc() {}
#else
inline Sql_alloc() {}
inline ~Sql_alloc() {}
#endif
};
/*
Basic single linked list
Used for item and item_buffs.
All list ends with a pointer to the 'end_of_list' element, which
data pointer is a null pointer and the next pointer points to itself.
This makes it very fast to traverse lists as we don't have to
test for a specialend condition for list that can't contain a null
pointer.
*/
class 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;
};
extern list_node end_of_list;
class base_list :public Sql_alloc
{
protected:
list_node *first,**last;
public:
uint elements;
inline void empty() { elements=0; first= &end_of_list; last=&first;}
inline base_list() { empty(); }
inline base_list(const base_list &tmp) :Sql_alloc()
{
elements=tmp.elements;
first=tmp.first;
last=tmp.last;
}
inline base_list(bool error) { }
inline bool push_back(void *info)
{
if (((*last)=new list_node(info, &end_of_list)))
{
last= &(*last)->next;
elements++;
return 0;
}
return 1;
}
inline bool push_front(void *info)
{
list_node *node=new list_node(info,first);
if (node)
{
if (last == &first)
last= &node->next;
first=node;
elements++;
return 0;
}
return 1;
}
void remove(list_node **prev)
{
list_node *node=(*prev)->next;
delete *prev;
*prev=node;
if (!--elements)
last= &first;
}
inline void *pop(void)
{
if (first == &end_of_list) return 0;
list_node *tmp=first;
first=first->next;
if (!--elements)
last= &first;
return tmp->info;
}
inline list_node* last_node() { return *last; }
inline list_node* first_node() { return first;}
inline void *head() { return first->info; }
inline void **head_ref() { return first != &end_of_list ? &first->info : 0; }
inline bool is_empty() { return first == &end_of_list ; }
inline list_node *last_ref() { return &end_of_list; }
friend class base_list_iterator;
friend class error_list;
friend class error_list_iterator;
protected:
void after(void *info,list_node *node)
{
list_node *new_node=new list_node(info,node->next);
node->next=new_node;
elements++;
if (last == &(node->next))
last= &new_node->next;
}
};
class base_list_iterator
{
protected:
base_list *list;
list_node **el,**prev,*current;
void sublist(base_list &ls, uint elm)
{
ls.first= *el;
ls.last= list->last;
ls.elements= elm;
}
public:
base_list_iterator(base_list &list_par)
:list(&list_par), el(&list_par.first), prev(0), current(0)
{}
inline void *next(void)
{
prev=el;
current= *el;
el= &current->next;
return current->info;
}
inline void *next_fast(void)
{
list_node *tmp;
tmp= *el;
el= &tmp->next;
return tmp->info;
}
inline void rewind(void)
{
el= &list->first;
}
inline void *replace(void *element)
{ // Return old element
void *tmp=current->info;
DBUG_ASSERT(current->info != 0);
current->info=element;
return tmp;
}
void *replace(base_list &new_list)
{
void *ret_value=current->info;
if (!new_list.is_empty())
{
*new_list.last=current->next;
current->info=new_list.first->info;
current->next=new_list.first->next;
if ((list->last == &current->next) && (new_list.elements > 1))
list->last= new_list.last;
list->elements+=new_list.elements-1;
}
return ret_value; // return old element
}
inline void remove(void) // Remove current
{
list->remove(prev);
el=prev;
current=0; // Safeguard
}
void after(void *element) // Insert element after current
{
list->after(element,current);
current=current->next;
el= &current->next;
}
inline void **ref(void) // Get reference pointer
{
return &current->info;
}
inline bool is_last(void)
{
return el == &list->last_ref()->next;
}
friend class error_list_iterator;
};
template <class T> class List :public base_list
{
public:
inline List() :base_list() {}
inline List(const List<T> &tmp) :base_list(tmp) {}
inline bool push_back(T *a) { return base_list::push_back(a); }
inline bool push_front(T *a) { return base_list::push_front(a); }
inline T* head() {return (T*) base_list::head(); }
inline T** head_ref() {return (T**) base_list::head_ref(); }
inline T* pop() {return (T*) base_list::pop(); }
void delete_elements(void)
{
list_node *element,*next;
for (element=first; element != &end_of_list; element=next)
{
next=element->next;
delete (T*) element->info;
}
empty();
}
};
template <class T> class List_iterator :public base_list_iterator
{
public:
List_iterator(List<T> &a) : base_list_iterator(a) {}
inline T* operator++(int) { return (T*) base_list_iterator::next(); }
inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); }
inline T *replace(List<T> &a) { return (T*) base_list_iterator::replace(a); }
inline void after(T *a) { base_list_iterator::after(a); }
inline T** ref(void) { return (T**) base_list_iterator::ref(); }
};
template <class T> class List_iterator_fast :public base_list_iterator
{
protected:
inline T *replace(T *a) { return (T*) 0; }
inline T *replace(List<T> &a) { return (T*) 0; }
inline void remove(void) { }
inline void after(T *a) { }
inline T** ref(void) { return (T**) 0; }
public:
List_iterator_fast(List<T> &a) : base_list_iterator(a) {}
inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
inline void rewind(void) { base_list_iterator::rewind(); }
void sublist(List<T> &list, uint el)
{
base_list_iterator::sublist(list, el);
}
};
/*
A simple intrusive list which automaticly removes element from list
on delete (for THD element)
*/
struct ilink
{
struct ilink **prev,*next;
static void *operator new(size_t size)
{
return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE));
}
static void operator delete(void* ptr_arg, size_t size)
{
my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
inline ilink()
{
prev=0; next=0;
}
inline void unlink()
{
/* Extra tests because element doesn't have to be linked */
if (prev) *prev= next;
if (next) next->prev=prev;
prev=0 ; next=0;
}
virtual ~ilink() { unlink(); } /*lint -e1740 */
};
template <class T> class I_List_iterator;
class base_ilist
{
public:
struct ilink *first,last;
inline void empty() { first= &last; last.prev= &first; }
base_ilist() { empty(); }
inline bool is_empty() { return first == &last; }
inline void append(ilink *a)
{
first->prev= &a->next;
a->next=first; a->prev= &first; first=a;
}
inline void push_back(ilink *a)
{
*last.prev= a;
a->next= &last;
a->prev= last.prev;
last.prev= &a->next;
}
inline struct ilink *get()
{
struct ilink *first_link=first;
if (first_link == &last)
return 0;
first_link->unlink(); // Unlink from list
return first_link;
}
friend class base_list_iterator;
};
class base_ilist_iterator
{
base_ilist *list;
struct ilink **el,*current;
public:
base_ilist_iterator(base_ilist &list_par) :list(&list_par),
el(&list_par.first),current(0) {}
void *next(void)
{
/* This is coded to allow push_back() while iterating */
current= *el;
if (current == &list->last) return 0;
el= &current->next;
return current;
}
};
template <class T>
class I_List :private base_ilist
{
public:
I_List() :base_ilist() {}
inline void empty() { base_ilist::empty(); }
inline bool is_empty() { return base_ilist::is_empty(); }
inline void append(T* a) { base_ilist::append(a); }
inline void push_back(T* a) { base_ilist::push_back(a); }
inline T* get() { return (T*) base_ilist::get(); }
#ifndef _lint
friend class I_List_iterator<T>;
#endif
};
template <class T> class I_List_iterator :public base_ilist_iterator
{
public:
I_List_iterator(I_List<T> &a) : base_ilist_iterator(a) {}
inline T* operator++(int) { return (T*) base_ilist_iterator::next(); }
};