2008-08-06 11:15:24 -07:00
|
|
|
/* EINA - EFL data type library
|
|
|
|
* Copyright (C) 2008 Cedric Bail
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library;
|
|
|
|
* if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2008-08-06 08:42:33 -07:00
|
|
|
#ifndef EINA_INLINE_ARRAY_X_
|
|
|
|
#define EINA_INLINE_ARRAY_X_
|
2008-07-30 09:34:54 -07:00
|
|
|
|
2011-12-06 08:57:28 -08:00
|
|
|
#include <stddef.h>
|
|
|
|
|
2011-12-06 17:10:43 -08:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2008-09-07 12:12:49 -07:00
|
|
|
/**
|
|
|
|
* @cond LOCAL
|
|
|
|
*/
|
|
|
|
|
2008-09-08 05:19:15 -07:00
|
|
|
EAPI Eina_Bool eina_array_grow(Eina_Array *array);
|
2008-07-30 09:34:54 -07:00
|
|
|
|
2008-09-07 12:12:49 -07:00
|
|
|
/**
|
|
|
|
* @endcond
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2008-09-18 22:22:43 -07:00
|
|
|
* @addtogroup Eina_Array_Group Array
|
2008-09-07 12:12:49 -07:00
|
|
|
*
|
|
|
|
* @brief These functions provide array management.
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
static inline Eina_Bool
|
2008-08-26 03:23:45 -07:00
|
|
|
eina_array_push(Eina_Array *array, const void *data)
|
2008-07-30 09:34:54 -07:00
|
|
|
{
|
eina_array: micro optimize eina_array_push
This commit does two things:
- Tell the compiler that it is unlikely that we need to grow, and that
it is unlikely that data is NULL. Sometimes the if check for data
would get dropped out by the compiler when it can be ensured that it is
!= NULL. However, if we for example efl_add something and eina_push
the result, the condition would not be removed, as there is no assertion
efl_add would be != NULL.
- Do not hide the array assignment in a branch, but make it the default
branch, this way instruction cache caches the correct instruction, as
branch prediction will now hopefully, due to the hinting, take the
correct branch.
While benchmarking this here (simply in elementary_perf), this reduced
pipeline faults in eina_array_push quite a bit. (Btw. it is hard to track
*which* exact calls to eina_array_push do cause that, as mostly this API
gets inlined, so it was easier optimizing that, instead of the method
arround)
Reviewed-by: Stefan Schmidt <stefan@datenfreihafen.org>
Differential Revision: https://phab.enlightenment.org/D11997
2020-06-10 11:48:37 -07:00
|
|
|
if (EINA_UNLIKELY(data == NULL)) return EINA_FALSE;
|
|
|
|
if (EINA_UNLIKELY((array->count + 1) > array->total)) goto do_grow;
|
2016-09-18 16:58:56 -07:00
|
|
|
do_grow_back:
|
|
|
|
|
eina_array: micro optimize eina_array_push
This commit does two things:
- Tell the compiler that it is unlikely that we need to grow, and that
it is unlikely that data is NULL. Sometimes the if check for data
would get dropped out by the compiler when it can be ensured that it is
!= NULL. However, if we for example efl_add something and eina_push
the result, the condition would not be removed, as there is no assertion
efl_add would be != NULL.
- Do not hide the array assignment in a branch, but make it the default
branch, this way instruction cache caches the correct instruction, as
branch prediction will now hopefully, due to the hinting, take the
correct branch.
While benchmarking this here (simply in elementary_perf), this reduced
pipeline faults in eina_array_push quite a bit. (Btw. it is hard to track
*which* exact calls to eina_array_push do cause that, as mostly this API
gets inlined, so it was easier optimizing that, instead of the method
arround)
Reviewed-by: Stefan Schmidt <stefan@datenfreihafen.org>
Differential Revision: https://phab.enlightenment.org/D11997
2020-06-10 11:48:37 -07:00
|
|
|
array->data[array->count++] = (void*) data;
|
2016-09-18 16:58:56 -07:00
|
|
|
|
eina_array: micro optimize eina_array_push
This commit does two things:
- Tell the compiler that it is unlikely that we need to grow, and that
it is unlikely that data is NULL. Sometimes the if check for data
would get dropped out by the compiler when it can be ensured that it is
!= NULL. However, if we for example efl_add something and eina_push
the result, the condition would not be removed, as there is no assertion
efl_add would be != NULL.
- Do not hide the array assignment in a branch, but make it the default
branch, this way instruction cache caches the correct instruction, as
branch prediction will now hopefully, due to the hinting, take the
correct branch.
While benchmarking this here (simply in elementary_perf), this reduced
pipeline faults in eina_array_push quite a bit. (Btw. it is hard to track
*which* exact calls to eina_array_push do cause that, as mostly this API
gets inlined, so it was easier optimizing that, instead of the method
arround)
Reviewed-by: Stefan Schmidt <stefan@datenfreihafen.org>
Differential Revision: https://phab.enlightenment.org/D11997
2020-06-10 11:48:37 -07:00
|
|
|
return EINA_TRUE;
|
2016-09-18 16:58:56 -07:00
|
|
|
do_grow:
|
|
|
|
if (!eina_array_grow(array)) return EINA_FALSE;
|
|
|
|
goto do_grow_back;
|
2008-07-30 09:34:54 -07:00
|
|
|
}
|
|
|
|
|
2008-08-26 03:23:45 -07:00
|
|
|
static inline void *
|
|
|
|
eina_array_pop(Eina_Array *array)
|
|
|
|
{
|
2016-09-18 16:58:56 -07:00
|
|
|
if (array->count > 0) return array->data[--array->count];
|
|
|
|
return NULL;
|
2008-08-26 03:23:45 -07:00
|
|
|
}
|
|
|
|
|
2008-07-30 09:34:54 -07:00
|
|
|
static inline void *
|
2010-08-10 05:00:36 -07:00
|
|
|
eina_array_data_get(const Eina_Array *array, unsigned int idx)
|
2008-07-30 09:34:54 -07:00
|
|
|
{
|
2010-08-10 05:00:36 -07:00
|
|
|
return array->data[idx];
|
2008-07-30 09:34:54 -07:00
|
|
|
}
|
|
|
|
|
2008-11-05 09:16:07 -08:00
|
|
|
static inline void
|
2010-08-10 05:00:36 -07:00
|
|
|
eina_array_data_set(const Eina_Array *array, unsigned int idx, const void *data)
|
2008-11-05 09:16:07 -08:00
|
|
|
{
|
2010-01-23 11:53:27 -08:00
|
|
|
array->data[idx] = (void*) data;
|
2008-11-05 09:16:07 -08:00
|
|
|
}
|
|
|
|
|
2014-03-20 00:35:41 -07:00
|
|
|
|
2008-08-01 05:26:35 -07:00
|
|
|
static inline unsigned int
|
2010-08-10 05:00:36 -07:00
|
|
|
eina_array_count_get(const Eina_Array *array)
|
2008-08-01 05:26:35 -07:00
|
|
|
{
|
|
|
|
return array->count;
|
|
|
|
}
|
|
|
|
|
2014-03-20 00:35:41 -07:00
|
|
|
|
2012-01-09 15:13:06 -08:00
|
|
|
static inline unsigned int
|
|
|
|
eina_array_count(const Eina_Array *array)
|
|
|
|
{
|
2020-02-17 04:55:33 -08:00
|
|
|
if (!array) return 0;
|
2012-01-09 15:13:06 -08:00
|
|
|
return array->count;
|
|
|
|
}
|
|
|
|
|
2019-08-26 05:06:51 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
eina_array_find(const Eina_Array *array, const void *data, unsigned int *out_idx)
|
|
|
|
{
|
2019-09-23 07:00:25 -07:00
|
|
|
unsigned int i;
|
|
|
|
|
2019-08-26 05:06:51 -07:00
|
|
|
if (!array) return EINA_FALSE;
|
|
|
|
|
2019-09-23 07:00:25 -07:00
|
|
|
for (i = 0; i < array->count; i++)
|
2019-08-26 05:06:51 -07:00
|
|
|
{
|
|
|
|
if (array->data[i] == data)
|
|
|
|
{
|
|
|
|
if (out_idx) *out_idx = i;
|
2019-09-23 07:00:25 -07:00
|
|
|
|
2019-08-26 05:06:51 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2010-08-11 07:32:30 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, void *fdata)
|
|
|
|
{
|
|
|
|
void *data;
|
|
|
|
Eina_Array_Iterator iterator;
|
|
|
|
unsigned int i;
|
|
|
|
Eina_Bool ret = EINA_TRUE;
|
|
|
|
|
|
|
|
EINA_ARRAY_ITER_NEXT(array, i, data, iterator)
|
2016-09-18 16:58:56 -07:00
|
|
|
{
|
|
|
|
if (cb(array, data, fdata) == EINA_TRUE) continue;
|
|
|
|
ret = EINA_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
2010-08-11 07:32:30 -07:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-11-29 10:32:30 -08:00
|
|
|
static inline void
|
|
|
|
eina_array_clean(Eina_Array *array)
|
|
|
|
{
|
|
|
|
array->count = 0;
|
|
|
|
}
|
|
|
|
|
2008-09-07 12:12:49 -07:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2008-07-30 09:34:54 -07:00
|
|
|
#endif
|