38 #include <my_global.h>
43 void lf_dynarray_init(
LF_DYNARRAY *array, uint element_size)
45 memset(array, 0,
sizeof(*array));
46 array->size_of_element= element_size;
47 my_atomic_rwlock_init(&array->lock);
50 static void recursive_free(
void **alloc,
int level)
58 for (i= 0; i < LF_DYNARRAY_LEVEL_LENGTH; i++)
59 recursive_free(alloc[i], level-1);
69 for (i= 0; i < LF_DYNARRAY_LEVELS; i++)
70 recursive_free(array->level[i], i);
71 my_atomic_rwlock_destroy(&array->lock);
74 static const ulong dynarray_idxes_in_prev_levels[LF_DYNARRAY_LEVELS]=
77 LF_DYNARRAY_LEVEL_LENGTH,
78 LF_DYNARRAY_LEVEL_LENGTH * LF_DYNARRAY_LEVEL_LENGTH +
79 LF_DYNARRAY_LEVEL_LENGTH,
80 LF_DYNARRAY_LEVEL_LENGTH * LF_DYNARRAY_LEVEL_LENGTH *
81 LF_DYNARRAY_LEVEL_LENGTH + LF_DYNARRAY_LEVEL_LENGTH *
82 LF_DYNARRAY_LEVEL_LENGTH + LF_DYNARRAY_LEVEL_LENGTH
85 static const ulong dynarray_idxes_in_prev_level[LF_DYNARRAY_LEVELS]=
88 LF_DYNARRAY_LEVEL_LENGTH,
89 LF_DYNARRAY_LEVEL_LENGTH * LF_DYNARRAY_LEVEL_LENGTH,
90 LF_DYNARRAY_LEVEL_LENGTH * LF_DYNARRAY_LEVEL_LENGTH *
91 LF_DYNARRAY_LEVEL_LENGTH,
98 void *_lf_dynarray_lvalue(
LF_DYNARRAY *array, uint idx)
100 void * ptr, *
volatile * ptr_ptr= 0;
103 for (i= LF_DYNARRAY_LEVELS-1; idx < dynarray_idxes_in_prev_levels[
i]; i--)
105 ptr_ptr= &array->level[
i];
106 idx-= dynarray_idxes_in_prev_levels[
i];
109 if (!(ptr= *ptr_ptr))
111 void *alloc= my_malloc(LF_DYNARRAY_LEVEL_LENGTH *
sizeof(
void *),
112 MYF(MY_WME|MY_ZEROFILL));
113 if (unlikely(!alloc))
115 if (my_atomic_casptr(ptr_ptr, &ptr, alloc))
120 ptr_ptr= ((
void **)ptr) + idx / dynarray_idxes_in_prev_level[
i];
121 idx%= dynarray_idxes_in_prev_level[
i];
123 if (!(ptr= *ptr_ptr))
126 alloc= my_malloc(LF_DYNARRAY_LEVEL_LENGTH * array->size_of_element +
127 MY_MAX(array->size_of_element,
sizeof(
void *)),
128 MYF(MY_WME|MY_ZEROFILL));
129 if (unlikely(!alloc))
132 data= alloc +
sizeof(
void *);
134 intptr mod= ((intptr)data) % array->size_of_element;
136 data+= array->size_of_element - mod;
138 ((
void **)data)[-1]= alloc;
139 if (my_atomic_casptr(ptr_ptr, &ptr, data))
144 return ((uchar*)ptr) + array->size_of_element * idx;
151 void *_lf_dynarray_value(
LF_DYNARRAY *array, uint idx)
153 void * ptr, *
volatile * ptr_ptr= 0;
156 for (i= LF_DYNARRAY_LEVELS-1; idx < dynarray_idxes_in_prev_levels[
i]; i--)
158 ptr_ptr= &array->level[
i];
159 idx-= dynarray_idxes_in_prev_levels[
i];
162 if (!(ptr= *ptr_ptr))
164 ptr_ptr= ((
void **)ptr) + idx / dynarray_idxes_in_prev_level[
i];
165 idx %= dynarray_idxes_in_prev_level[
i];
167 if (!(ptr= *ptr_ptr))
169 return ((uchar*)ptr) + array->size_of_element * idx;
172 static int recursive_iterate(
LF_DYNARRAY *array,
void *ptr,
int level,
173 lf_dynarray_func func,
void *arg)
179 return func(ptr, arg);
180 for (i= 0; i < LF_DYNARRAY_LEVEL_LENGTH; i++)
181 if ((res= recursive_iterate(array, ((
void **)ptr)[i], level-1, func, arg)))
199 int _lf_dynarray_iterate(
LF_DYNARRAY *array, lf_dynarray_func func,
void *arg)
202 for (i= 0; i < LF_DYNARRAY_LEVELS; i++)
203 if ((res= recursive_iterate(array, array->level[i], i, func, arg)))