diff options
author | Michael Widenius <monty@askmonty.org> | 2012-08-01 17:27:34 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2012-08-01 17:27:34 +0300 |
commit | 1d0f70c2f894b27e98773a282871d32802f67964 (patch) | |
tree | 833e683e0ced29c4323c29a9d845703d4dfcd81b /storage/innobase/include/ut0vec.ic | |
parent | 5a86a61219826aadf8d08cbc447fe438f2bf50c3 (diff) | |
download | mariadb-git-1d0f70c2f894b27e98773a282871d32802f67964.tar.gz |
Temporary commit of merge of MariaDB 10.0-base and MySQL 5.6
Diffstat (limited to 'storage/innobase/include/ut0vec.ic')
-rw-r--r-- | storage/innobase/include/ut0vec.ic | 349 |
1 files changed, 324 insertions, 25 deletions
diff --git a/storage/innobase/include/ut0vec.ic b/storage/innobase/include/ut0vec.ic index 34c858868ce..1255caee2d9 100644 --- a/storage/innobase/include/ut0vec.ic +++ b/storage/innobase/include/ut0vec.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 2006, 2009, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -11,8 +11,8 @@ 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 +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -23,21 +23,169 @@ A vector of pointers to data items Created 4/6/2006 Osku Salerma ************************************************************************/ -/****************************************************************//** -Get number of elements in vector. -@return number of elements in vector */ +#define IB_VEC_OFFSET(v, i) (vec->sizeof_value * i) + +/******************************************************************** +The default ib_vector_t heap malloc. Uses mem_heap_alloc(). */ +UNIV_INLINE +void* +ib_heap_malloc( +/*===========*/ + ib_alloc_t* allocator, /* in: allocator */ + ulint size) /* in: size in bytes */ +{ + mem_heap_t* heap = (mem_heap_t*) allocator->arg; + + return(mem_heap_alloc(heap, size)); +} + +/******************************************************************** +The default ib_vector_t heap free. Does nothing. */ +UNIV_INLINE +void +ib_heap_free( +/*=========*/ + ib_alloc_t* allocator UNIV_UNUSED, /* in: allocator */ + void* ptr UNIV_UNUSED) /* in: size in bytes */ +{ + /* We can't free individual elements. */ +} + +/******************************************************************** +The default ib_vector_t heap resize. Since we can't resize the heap +we have to copy the elements from the old ptr to the new ptr. +Uses mem_heap_alloc(). */ +UNIV_INLINE +void* +ib_heap_resize( +/*===========*/ + ib_alloc_t* allocator, /* in: allocator */ + void* old_ptr, /* in: pointer to memory */ + ulint old_size, /* in: old size in bytes */ + ulint new_size) /* in: new size in bytes */ +{ + void* new_ptr; + mem_heap_t* heap = (mem_heap_t*) allocator->arg; + + new_ptr = mem_heap_alloc(heap, new_size); + memcpy(new_ptr, old_ptr, old_size); + + return(new_ptr); +} + +/******************************************************************** +Create a heap allocator that uses the passed in heap. */ +UNIV_INLINE +ib_alloc_t* +ib_heap_allocator_create( +/*=====================*/ + mem_heap_t* heap) /* in: heap to use */ +{ + ib_alloc_t* heap_alloc; + + heap_alloc = (ib_alloc_t*) mem_heap_alloc(heap, sizeof(*heap_alloc)); + + heap_alloc->arg = heap; + heap_alloc->mem_release = ib_heap_free; + heap_alloc->mem_malloc = ib_heap_malloc; + heap_alloc->mem_resize = ib_heap_resize; + + return(heap_alloc); +} + +/******************************************************************** +Free a heap allocator. */ +UNIV_INLINE +void +ib_heap_allocator_free( +/*===================*/ + ib_alloc_t* ib_ut_alloc) /* in: alloc instace to free */ +{ + mem_heap_free((mem_heap_t*) ib_ut_alloc->arg); +} + +/******************************************************************** +Wrapper around ut_malloc(). */ +UNIV_INLINE +void* +ib_ut_malloc( +/*=========*/ + ib_alloc_t* allocator UNIV_UNUSED, /* in: allocator */ + ulint size) /* in: size in bytes */ +{ + return(ut_malloc(size)); +} + +/******************************************************************** +Wrapper around ut_free(). */ +UNIV_INLINE +void +ib_ut_free( +/*=======*/ + ib_alloc_t* allocator UNIV_UNUSED, /* in: allocator */ + void* ptr) /* in: size in bytes */ +{ + ut_free(ptr); +} + +/******************************************************************** +Wrapper aroung ut_realloc(). */ +UNIV_INLINE +void* +ib_ut_resize( +/*=========*/ + ib_alloc_t* allocator UNIV_UNUSED, /* in: allocator */ + void* old_ptr, /* in: pointer to memory */ + ulint old_size UNIV_UNUSED,/* in: old size in bytes */ + ulint new_size) /* in: new size in bytes */ +{ + return(ut_realloc(old_ptr, new_size)); +} + +/******************************************************************** +Create a ut allocator. */ +UNIV_INLINE +ib_alloc_t* +ib_ut_allocator_create(void) +/*========================*/ +{ + ib_alloc_t* ib_ut_alloc; + + ib_ut_alloc = (ib_alloc_t*) ut_malloc(sizeof(*ib_ut_alloc)); + + ib_ut_alloc->arg = NULL; + ib_ut_alloc->mem_release = ib_ut_free; + ib_ut_alloc->mem_malloc = ib_ut_malloc; + ib_ut_alloc->mem_resize = ib_ut_resize; + + return(ib_ut_alloc); +} + +/******************************************************************** +Free a ut allocator. */ +UNIV_INLINE +void +ib_ut_allocator_free( +/*=================*/ + ib_alloc_t* ib_ut_alloc) /* in: alloc instace to free */ +{ + ut_free(ib_ut_alloc); +} + +/******************************************************************** +Get number of elements in vector. */ UNIV_INLINE ulint ib_vector_size( /*===========*/ - const ib_vector_t* vec) /*!< in: vector */ + /* out: number of elements in vector*/ + const ib_vector_t* vec) /* in: vector */ { return(vec->used); } /****************************************************************//** -Get n'th element. -@return n'th element */ +Get n'th element. */ UNIV_INLINE void* ib_vector_get( @@ -47,9 +195,23 @@ ib_vector_get( { ut_a(n < vec->used); - return(vec->data[n]); + return((byte*) vec->data + IB_VEC_OFFSET(vec, n)); } +/******************************************************************** +Const version of the get n'th element. +@return n'th element */ +UNIV_INLINE +const void* +ib_vector_get_const( +/*================*/ + const ib_vector_t* vec, /* in: vector */ + ulint n) /* in: element index to get */ +{ + ut_a(n < vec->used); + + return((byte*) vec->data + IB_VEC_OFFSET(vec, n)); +} /****************************************************************//** Get last element. The vector must not be empty. @return last element */ @@ -61,7 +223,7 @@ ib_vector_get_last( { ut_a(vec->used > 0); - return(vec->data[vec->used - 1]); + return((byte*) ib_vector_get(vec, vec->used - 1)); } /****************************************************************//** @@ -74,9 +236,52 @@ ib_vector_set( ulint n, /*!< in: element index to set */ void* elem) /*!< in: data element */ { + void* slot; + ut_a(n < vec->used); - vec->data[n] = elem; + slot = ((byte*) vec->data + IB_VEC_OFFSET(vec, n)); + memcpy(slot, elem, vec->sizeof_value); +} + +/******************************************************************** +Reset the vector size to 0 elements. */ +UNIV_INLINE +void +ib_vector_reset( +/*============*/ + /* out: void */ + ib_vector_t* vec) /* in: vector */ +{ + vec->used = 0; +} + +/******************************************************************** +Get the last element of the vector. */ +UNIV_INLINE +void* +ib_vector_last( +/*===========*/ + /* out: void */ + ib_vector_t* vec) /* in: vector */ +{ + ut_a(ib_vector_size(vec) > 0); + + return(ib_vector_get(vec, ib_vector_size(vec) - 1)); +} + +/******************************************************************** +Get the last element of the vector. */ +UNIV_INLINE +const void* +ib_vector_last_const( +/*=================*/ + /* out: void */ + const ib_vector_t* vec) /* in: vector */ +{ + ut_a(ib_vector_size(vec) > 0); + + return(ib_vector_get_const(vec, ib_vector_size(vec) - 1)); } /****************************************************************//** @@ -86,35 +291,129 @@ UNIV_INLINE void* ib_vector_pop( /*==========*/ - ib_vector_t* vec) /*!< in/out: vector */ + /* out: pointer to element */ + ib_vector_t* vec) /* in: vector */ { - void* elem; + void* elem; ut_a(vec->used > 0); - --vec->used; - elem = vec->data[vec->used]; - ut_d(vec->data[vec->used] = NULL); - UNIV_MEM_INVALID(&vec->data[vec->used], sizeof(*vec->data)); + elem = ib_vector_last(vec); + --vec->used; return(elem); } -/****************************************************************//** -Free the underlying heap of the vector. Note that vec is invalid -after this call. */ +/******************************************************************** +Append an element to the vector, if elem != NULL then copy the data +from elem.*/ +UNIV_INLINE +void* +ib_vector_push( +/*===========*/ + /* out: pointer to the "new" element */ + ib_vector_t* vec, /* in: vector */ + const void* elem) /* in: element to add (can be NULL) */ +{ + void* last; + + if (vec->used >= vec->total) { + ib_vector_resize(vec); + } + + last = (byte*) vec->data + IB_VEC_OFFSET(vec, vec->used); + +#ifdef UNIV_DEBUG + memset(last, 0, vec->sizeof_value); +#endif + + if (elem) { + memcpy(last, elem, vec->sizeof_value); + } + + ++vec->used; + + return(last); +} + +/*******************************************************************//** +Remove an element to the vector +@return pointer to the "removed" element */ +UNIV_INLINE +void* +ib_vector_remove( +/*=============*/ + ib_vector_t* vec, /*!< in: vector */ + const void* elem) /*!< in: value to remove */ +{ + void* current; + void* next; + ulint i; + + for (i = 0; i < vec->used; i++) { + current = ib_vector_get(vec, i); + + if (*(void**) current == elem) { + if (i == vec->used - 1) { + return(ib_vector_pop(vec)); + } + + next = ib_vector_get(vec, i + 1); + memcpy(current, next, vec->sizeof_value + * (vec->used - i - 1)); + } + } + + --vec->used; + + return(current); +} + +/******************************************************************** +Sort the vector elements. */ +UNIV_INLINE +void +ib_vector_sort( +/*===========*/ + /* out: void */ + ib_vector_t* vec, /* in: vector */ + ib_compare_t compare)/* in: the comparator to use for sort */ +{ + qsort(vec->data, vec->used, vec->sizeof_value, compare); +} + +/******************************************************************** +Destroy the vector. Make sure the vector owns the allocator, e.g., +the heap in the the heap allocator. */ UNIV_INLINE void ib_vector_free( /*===========*/ - ib_vector_t* vec) /*!< in, own: vector */ + ib_vector_t* vec) /* in, own: vector */ { - mem_heap_free(vec->heap); + /* Currently we only support two types of allocators, heap + and ut_malloc(), when the heap is freed all the elements are + freed too. With ut allocator, we need to free the elements, + the vector instance and the allocator separately. */ + + /* Only the heap allocator uses the arg field. */ + if (vec->allocator->arg) { + mem_heap_free((mem_heap_t*) vec->allocator->arg); + } else { + ib_alloc_t* allocator; + + allocator = vec->allocator; + + allocator->mem_release(allocator, vec->data); + allocator->mem_release(allocator, vec); + + ib_ut_allocator_free(allocator); + } } -/****************************************************************//** +/******************************************************************** Test whether a vector is empty or not. -@return TRUE if empty */ +@return TRUE if empty */ UNIV_INLINE ibool ib_vector_is_empty( |