forked from enlightenment/efl
* -fno-strict-aliasing is checked at linked time (to make sure
that it is disabled for suncc) * add old evas data types in tests. Tell me if you encounter problems with them SVN revision: 46136
This commit is contained in:
parent
0a87819b44
commit
b87e1d6fae
|
@ -294,7 +294,6 @@ if ! test "x${VMIC}" = "x" ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
EFL_COMPILER_FLAG([-Wshadow])
|
EFL_COMPILER_FLAG([-Wshadow])
|
||||||
EFL_COMPILER_FLAG([-fno-strict-aliasing])
|
|
||||||
|
|
||||||
AC_SUBST(EINA_CPPFLAGS)
|
AC_SUBST(EINA_CPPFLAGS)
|
||||||
AC_SUBST(EINA_CFLAGS)
|
AC_SUBST(EINA_CFLAGS)
|
||||||
|
@ -327,6 +326,8 @@ esac
|
||||||
AC_SUBST(EINA_LIBS)
|
AC_SUBST(EINA_LIBS)
|
||||||
AC_SUBST(lt_enable_auto_import)
|
AC_SUBST(lt_enable_auto_import)
|
||||||
|
|
||||||
|
EFL_LINKER_FLAG([-fno-strict-aliasing])
|
||||||
|
|
||||||
|
|
||||||
### Checks for library functions
|
### Checks for library functions
|
||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
|
@ -483,7 +484,6 @@ if test "x$enable_coverage" = "xyes" ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
EFL_CHECK_BENCHMARK([enable_benchmark="yes"], [enable_benchmark="no"])
|
EFL_CHECK_BENCHMARK([enable_benchmark="yes"], [enable_benchmark="no"])
|
||||||
EINA_BENCH_MODULE([evas], [${enable_benchmark}], [evas], [enable_benchmark_evas="yes"], [enable_benchmark_evas="no"])
|
|
||||||
EINA_BENCH_MODULE([glib], [${enable_benchmark}], [glib-2.0], [enable_benchmark_glib="yes"], [enable_benchmark_glib="no"])
|
EINA_BENCH_MODULE([glib], [${enable_benchmark}], [glib-2.0], [enable_benchmark_glib="yes"], [enable_benchmark_glib="no"])
|
||||||
|
|
||||||
AC_SUBST(requirement_eina)
|
AC_SUBST(requirement_eina)
|
||||||
|
@ -554,7 +554,6 @@ echo " Coverage.............: ${enable_coverage}"
|
||||||
echo " Benchmark............: ${enable_benchmark}"
|
echo " Benchmark............: ${enable_benchmark}"
|
||||||
if test "x${enable_benchmark}" = "xyes" ; then
|
if test "x${enable_benchmark}" = "xyes" ; then
|
||||||
echo " Glib...............: ${enable_benchmark_glib}"
|
echo " Glib...............: ${enable_benchmark_glib}"
|
||||||
echo " Evas...............: ${enable_benchmark_evas}"
|
|
||||||
echo " E17 real data......: ${enable_benchmark_e17}"
|
echo " E17 real data......: ${enable_benchmark_e17}"
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
dnl Checks if a given compiler switch is supported.
|
dnl Copyright (C) 2010 Vincent Torri <vtorri at univ-evry dot fr>
|
||||||
dnl If so, this macro adds the flag to the CFLAGS
|
dnl and Albin Tonnerre <albin dot tonnerre at gmail dot com>
|
||||||
|
dnl That code is public domain and can be freely used or copied.
|
||||||
|
|
||||||
|
dnl Macro that checks if a compiler flag is supported by the compiler.
|
||||||
|
|
||||||
|
dnl Usage: EFL_COMPILER_FLAG(flag)
|
||||||
|
dnl flag is added to CFLAGS if supported.
|
||||||
|
|
||||||
AC_DEFUN([EFL_COMPILER_FLAG],
|
AC_DEFUN([EFL_COMPILER_FLAG],
|
||||||
[
|
[
|
||||||
|
@ -22,3 +28,30 @@ fi
|
||||||
AC_LANG_POP([C])
|
AC_LANG_POP([C])
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl Macro that checks if a linker flag is supported by the compiler.
|
||||||
|
|
||||||
|
dnl Usage: EFL_LINKER_FLAG(flag)
|
||||||
|
dnl flag is added to CFLAGS if supported (will be passed to ld anyway).
|
||||||
|
|
||||||
|
AC_DEFUN([EFL_LINKER_FLAG],
|
||||||
|
[
|
||||||
|
|
||||||
|
CFLAGS_save="${CFLAGS}"
|
||||||
|
CFLAGS="${CFLAGS} $1"
|
||||||
|
|
||||||
|
AC_LANG_PUSH([C])
|
||||||
|
AC_MSG_CHECKING([whether the compiler supports $1])
|
||||||
|
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([[]])],
|
||||||
|
[have_flag="yes"],
|
||||||
|
[have_flag="no"])
|
||||||
|
AC_MSG_RESULT([${have_flag}])
|
||||||
|
|
||||||
|
if test "x${have_flag}" = "xno" ; then
|
||||||
|
CFLAGS="${CFLAGS_save}"
|
||||||
|
fi
|
||||||
|
AC_LANG_POP([C])
|
||||||
|
|
||||||
|
])
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
#ifndef _EVAS_DATA_H
|
||||||
|
#define _EVAS_DATA_H
|
||||||
|
|
||||||
|
#ifdef EAPI
|
||||||
|
# undef EAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifdef EFL_EVAS_BUILD
|
||||||
|
# ifdef DLL_EXPORT
|
||||||
|
# define EAPI __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define EAPI
|
||||||
|
# endif /* ! DLL_EXPORT */
|
||||||
|
# else
|
||||||
|
# define EAPI __declspec(dllimport)
|
||||||
|
# endif /* ! EFL_EVAS_BUILD */
|
||||||
|
#else
|
||||||
|
# ifdef __GNUC__
|
||||||
|
# if __GNUC__ >= 4
|
||||||
|
# define EAPI __attribute__ ((visibility("default")))
|
||||||
|
# else
|
||||||
|
# define EAPI
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define EAPI
|
||||||
|
# endif
|
||||||
|
#endif /* ! _WIN32 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief These routines are used for Evas data types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef unsigned char Evas_Bool;
|
||||||
|
|
||||||
|
typedef struct _Evas_Array_Hash Evas_Array_Hash;
|
||||||
|
typedef struct _Evas_Hash Evas_Hash; /**< A Hash table handle */
|
||||||
|
typedef struct _Evas_List Evas_List; /**< A generic linked list node handle */
|
||||||
|
typedef struct _Evas_Object_List Evas_Object_List;
|
||||||
|
|
||||||
|
struct _Evas_Hash
|
||||||
|
{
|
||||||
|
int population;
|
||||||
|
Evas_Object_List *buckets[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _Evas_List /** A linked list node */
|
||||||
|
{
|
||||||
|
void *data; /**< Pointer to list element payload */
|
||||||
|
Evas_List *next; /**< Next member in the list */
|
||||||
|
Evas_List *prev; /**< Previous member in the list */
|
||||||
|
struct _Evas_List_Accounting *accounting; /**< Private list accounting info - don't touch */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _Evas_Object_List
|
||||||
|
{
|
||||||
|
Evas_Object_List *next, *prev;
|
||||||
|
Evas_Object_List *last;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evas Array Hash functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
EAPI Evas_Array_Hash *evas_array_hash_new (void);
|
||||||
|
EAPI void evas_array_hash_free (Evas_Array_Hash *hash);
|
||||||
|
EAPI void evas_array_hash_add (Evas_Array_Hash *hash, int key, int data);
|
||||||
|
EAPI int evas_array_hash_search (Evas_Array_Hash *hash, int key);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evas Hash functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FIXME: add:
|
||||||
|
* api to add find, del members by data, size not just string and also
|
||||||
|
* provide hash generation functions settable by the app
|
||||||
|
*
|
||||||
|
* do we really need this? hmmm - let me think... there may be a better way
|
||||||
|
*/
|
||||||
|
EAPI Evas_Hash *evas_hash_add (Evas_Hash *hash, const char *key, const void *data);
|
||||||
|
EAPI Evas_Hash *evas_hash_direct_add (Evas_Hash *hash, const char *key, const void *data);
|
||||||
|
EAPI Evas_Hash *evas_hash_del (Evas_Hash *hash, const char *key, const void *data);
|
||||||
|
EAPI void *evas_hash_find (const Evas_Hash *hash, const char *key);
|
||||||
|
EAPI void *evas_hash_modify (Evas_Hash *hash, const char *key, const void *data);
|
||||||
|
EAPI int evas_hash_size (const Evas_Hash *hash);
|
||||||
|
EAPI void evas_hash_free (Evas_Hash *hash);
|
||||||
|
EAPI void evas_hash_foreach (const Evas_Hash *hash, Evas_Bool (*func) (const Evas_Hash *hash, const char *key, void *data, void *fdata), const void *fdata);
|
||||||
|
EAPI int evas_hash_alloc_error (void);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evas List functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
EAPI Evas_List *evas_list_append (Evas_List *list, const void *data);
|
||||||
|
EAPI Evas_List *evas_list_prepend (Evas_List *list, const void *data);
|
||||||
|
EAPI Evas_List *evas_list_append_relative (Evas_List *list, const void *data, const void *relative);
|
||||||
|
EAPI Evas_List *evas_list_append_relative_list (Evas_List *list, const void *data, Evas_List *relative);
|
||||||
|
EAPI Evas_List *evas_list_prepend_relative (Evas_List *list, const void *data, const void *relative);
|
||||||
|
EAPI Evas_List *evas_list_prepend_relative_list (Evas_List *list, const void *data, Evas_List *relative);
|
||||||
|
EAPI Evas_List *evas_list_remove (Evas_List *list, const void *data);
|
||||||
|
EAPI Evas_List *evas_list_remove_list (Evas_List *list, Evas_List *remove_list);
|
||||||
|
EAPI Evas_List *evas_list_promote_list (Evas_List *list, Evas_List *move_list);
|
||||||
|
EAPI void *evas_list_find (const Evas_List *list, const void *data);
|
||||||
|
EAPI Evas_List *evas_list_find_list (const Evas_List *list, const void *data);
|
||||||
|
EAPI Evas_List *evas_list_free (Evas_List *list);
|
||||||
|
EAPI Evas_List *evas_list_last (const Evas_List *list);
|
||||||
|
EAPI Evas_List *evas_list_next (const Evas_List *list);
|
||||||
|
EAPI Evas_List *evas_list_prev (const Evas_List *list);
|
||||||
|
EAPI void *evas_list_data (const Evas_List *list);
|
||||||
|
EAPI int evas_list_count (const Evas_List *list);
|
||||||
|
EAPI void *evas_list_nth (const Evas_List *list, int n);
|
||||||
|
EAPI Evas_List *evas_list_nth_list (const Evas_List *list, int n);
|
||||||
|
EAPI Evas_List *evas_list_reverse (Evas_List *list);
|
||||||
|
EAPI Evas_List *evas_list_sort (Evas_List *list, int size, int(*func)(void*,void*));
|
||||||
|
EAPI int evas_list_alloc_error (void);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evas Object List functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
EAPI void *evas_object_list_append (void *in_list, void *in_item);
|
||||||
|
EAPI void *evas_object_list_prepend (void *in_list, void *in_item);
|
||||||
|
EAPI void *evas_object_list_append_relative (void *in_list, void *in_item, void *in_relative);
|
||||||
|
EAPI void *evas_object_list_prepend_relative (void *in_list, void *in_item, void *in_relative);
|
||||||
|
EAPI void *evas_object_list_remove (void *in_list, void *in_item);
|
||||||
|
EAPI void *evas_object_list_find (void *in_list, void *in_item);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evas Stringshare functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
EAPI void evas_stringshare_init (void); /* not implemented */
|
||||||
|
EAPI void evas_stringshare_shutdown (void); /* not implemented */
|
||||||
|
EAPI const char *evas_stringshare_add (const char *str);
|
||||||
|
EAPI void evas_stringshare_del (const char *str);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _EVAS_DATA_H */
|
|
@ -12,8 +12,7 @@ AM_CPPFLAGS = \
|
||||||
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
|
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
|
||||||
-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)\" \
|
-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)\" \
|
||||||
@CHECK_CFLAGS@ \
|
@CHECK_CFLAGS@ \
|
||||||
@GLIB_CFLAGS@ \
|
@GLIB_CFLAGS@
|
||||||
@EVAS_CFLAGS@
|
|
||||||
|
|
||||||
if EINA_HAVE_GLIB
|
if EINA_HAVE_GLIB
|
||||||
|
|
||||||
|
@ -21,12 +20,6 @@ AM_CPPFLAGS += -DEINA_BENCH_HAVE_GLIB
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if EINA_HAVE_EVAS
|
|
||||||
|
|
||||||
AM_CPPFLAGS += -DEINA_BENCH_HAVE_EVAS
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
if EINA_ENABLE_BENCHMARK_E17
|
if EINA_ENABLE_BENCHMARK_E17
|
||||||
|
|
||||||
AM_CPPFLAGS += -DEINA_ENABLE_BENCH_E17
|
AM_CPPFLAGS += -DEINA_ENABLE_BENCH_E17
|
||||||
|
@ -94,11 +87,16 @@ eina_bench_rectangle_pool.c \
|
||||||
ecore_list.c \
|
ecore_list.c \
|
||||||
ecore_strings.c \
|
ecore_strings.c \
|
||||||
ecore_hash.c \
|
ecore_hash.c \
|
||||||
ecore_sheap.c
|
ecore_sheap.c \
|
||||||
|
evas_hash.c \
|
||||||
|
evas_list.c \
|
||||||
|
evas_mempool.c \
|
||||||
|
evas_object_list.c \
|
||||||
|
evas_stringshare.c
|
||||||
|
|
||||||
eina_bench_LDADD = @EVAS_LIBS@ @GLIB_LIBS@ $(top_builddir)/src/lib/libeina.la
|
eina_bench_LDADD = @GLIB_LIBS@ $(top_builddir)/src/lib/libeina.la
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXTRA_DIST = eina_bench.h eina_suite.h
|
EXTRA_DIST = eina_bench.h eina_suite.h Ecore_Data.h Evas_Data.h evas_mempool.h
|
||||||
|
|
||||||
|
|
|
@ -28,16 +28,14 @@
|
||||||
# include <glib.h>
|
# include <glib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
#include "Evas_Data.h"
|
||||||
# include <Evas.h>
|
#include "Ecore_Data.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "Ecore_Data.h"
|
|
||||||
|
|
||||||
#include "eina_bench.h"
|
#include "eina_bench.h"
|
||||||
#include "eina_array.h"
|
#include "eina_array.h"
|
||||||
#include "eina_list.h"
|
#include "eina_list.h"
|
||||||
#include "eina_inlist.h"
|
#include "eina_inlist.h"
|
||||||
|
#include "eina_main.h"
|
||||||
|
|
||||||
typedef struct _Eina_Bench_Object Eina_Bench_Object;
|
typedef struct _Eina_Bench_Object Eina_Bench_Object;
|
||||||
struct _Eina_Bench_Object
|
struct _Eina_Bench_Object
|
||||||
|
@ -557,8 +555,6 @@ eina_bench_gptrarray_4evas_render(int request)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
#if 0
|
|
||||||
static void
|
static void
|
||||||
eina_bench_evas_list_4evas_render(int request)
|
eina_bench_evas_list_4evas_render(int request)
|
||||||
{
|
{
|
||||||
|
@ -568,8 +564,6 @@ eina_bench_evas_list_4evas_render(int request)
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
evas_init();
|
|
||||||
|
|
||||||
for (i = 0; i < 1000; ++i)
|
for (i = 0; i < 1000; ++i)
|
||||||
{
|
{
|
||||||
for (j = 0; j < request; ++j)
|
for (j = 0; j < request; ++j)
|
||||||
|
@ -624,11 +618,7 @@ eina_bench_evas_list_4evas_render(int request)
|
||||||
free(evas_list_data(list));
|
free(evas_list_data(list));
|
||||||
list = evas_list_remove_list(list, list);
|
list = evas_list_remove_list(list, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
evas_shutdown();
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_eina_ecore_for_each_remove(void *value, void *user_data)
|
_eina_ecore_for_each_remove(void *value, void *user_data)
|
||||||
|
@ -701,11 +691,7 @@ void eina_bench_array(Eina_Benchmark *bench)
|
||||||
eina_benchmark_register(bench, "glist", EINA_BENCHMARK(eina_bench_glist_4evas_render), 200, 4000, 100);
|
eina_benchmark_register(bench, "glist", EINA_BENCHMARK(eina_bench_glist_4evas_render), 200, 4000, 100);
|
||||||
eina_benchmark_register(bench, "gptrarray", EINA_BENCHMARK(eina_bench_gptrarray_4evas_render), 200, 4000, 100);
|
eina_benchmark_register(bench, "gptrarray", EINA_BENCHMARK(eina_bench_gptrarray_4evas_render), 200, 4000, 100);
|
||||||
#endif
|
#endif
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
#if 0
|
|
||||||
eina_benchmark_register(bench, "evas", EINA_BENCHMARK(eina_bench_evas_list_4evas_render), 200, 4000, 100);
|
eina_benchmark_register(bench, "evas", EINA_BENCHMARK(eina_bench_evas_list_4evas_render), 200, 4000, 100);
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
eina_benchmark_register(bench, "ecore", EINA_BENCHMARK(eina_bench_ecore_list_4evas_render), 200, 1000, 100);
|
eina_benchmark_register(bench, "ecore", EINA_BENCHMARK(eina_bench_ecore_list_4evas_render), 200, 1000, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,8 @@
|
||||||
# include <glib.h>
|
# include <glib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
#include "Evas_Data.h"
|
||||||
# include <Evas.h>
|
#include "Ecore_Data.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
# include <Ecore_Data.h>
|
|
||||||
|
|
||||||
#include "eina_hash.h"
|
#include "eina_hash.h"
|
||||||
#include "eina_array.h"
|
#include "eina_array.h"
|
||||||
|
@ -278,8 +275,6 @@ eina_bench_lookup_ghash(int request)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
#if 0
|
|
||||||
static void
|
static void
|
||||||
eina_bench_lookup_evas(int request)
|
eina_bench_lookup_evas(int request)
|
||||||
{
|
{
|
||||||
|
@ -298,7 +293,7 @@ eina_bench_lookup_evas(int request)
|
||||||
|
|
||||||
tmp_val = malloc(sizeof (int));
|
tmp_val = malloc(sizeof (int));
|
||||||
|
|
||||||
if (!tmp_key || !tmp_val) continue ;
|
if (!tmp_val) continue ;
|
||||||
|
|
||||||
eina_convert_itoa(i, tmp_key);
|
eina_convert_itoa(i, tmp_key);
|
||||||
*tmp_val = i;
|
*tmp_val = i;
|
||||||
|
@ -327,8 +322,6 @@ eina_bench_lookup_evas(int request)
|
||||||
|
|
||||||
eina_array_free(array);
|
eina_array_free(array);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _Eina_Bench_Ecore Eina_Bench_Ecore;
|
typedef struct _Eina_Bench_Ecore Eina_Bench_Ecore;
|
||||||
struct _Eina_Bench_Ecore
|
struct _Eina_Bench_Ecore
|
||||||
|
@ -386,10 +379,6 @@ void eina_bench_hash(Eina_Benchmark *bench)
|
||||||
#ifdef EINA_BENCH_HAVE_GLIB
|
#ifdef EINA_BENCH_HAVE_GLIB
|
||||||
eina_benchmark_register(bench, "ghash-lookup", EINA_BENCHMARK(eina_bench_lookup_ghash), 10, 3000, 10);
|
eina_benchmark_register(bench, "ghash-lookup", EINA_BENCHMARK(eina_bench_lookup_ghash), 10, 3000, 10);
|
||||||
#endif
|
#endif
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
#if 0
|
|
||||||
eina_benchmark_register(bench, "evas-lookup", EINA_BENCHMARK(eina_bench_lookup_evas), 10, 3000, 10);
|
eina_benchmark_register(bench, "evas-lookup", EINA_BENCHMARK(eina_bench_lookup_evas), 10, 3000, 10);
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
eina_benchmark_register(bench, "ecore-lookup", EINA_BENCHMARK(eina_bench_lookup_ecore), 10, 3000, 10);
|
eina_benchmark_register(bench, "ecore-lookup", EINA_BENCHMARK(eina_bench_lookup_ecore), 10, 3000, 10);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,14 +27,13 @@
|
||||||
# include <glib.h>
|
# include <glib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
#include "Evas_Data.h"
|
||||||
# include <Evas.h>
|
#include "Ecore_Data.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "Ecore_Data.h"
|
|
||||||
|
|
||||||
#include "eina_bench.h"
|
#include "eina_bench.h"
|
||||||
#include "Eina.h"
|
#include "eina_convert.h"
|
||||||
|
#include "eina_list.h"
|
||||||
|
#include "eina_main.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_eina_cmp_str(const char *a, const char *b)
|
_eina_cmp_str(const char *a, const char *b)
|
||||||
|
@ -72,16 +71,12 @@ eina_bench_sort_eina(int request)
|
||||||
eina_shutdown();
|
eina_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
#if 0
|
|
||||||
static void
|
static void
|
||||||
eina_bench_sort_evas(int request)
|
eina_bench_sort_evas(int request)
|
||||||
{
|
{
|
||||||
Evas_List *list = NULL;
|
Evas_List *list = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
evas_init();
|
|
||||||
|
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
for (i = 0; i < request; ++i)
|
for (i = 0; i < request; ++i)
|
||||||
|
@ -100,11 +95,7 @@ eina_bench_sort_evas(int request)
|
||||||
free(evas_list_data(list));
|
free(evas_list_data(list));
|
||||||
list = evas_list_remove_list(list, list);
|
list = evas_list_remove_list(list, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
evas_shutdown();
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_GLIB
|
#ifdef EINA_BENCH_HAVE_GLIB
|
||||||
static void
|
static void
|
||||||
|
@ -212,11 +203,7 @@ void eina_bench_sort(Eina_Benchmark *bench)
|
||||||
eina_benchmark_register(bench, "ecore", EINA_BENCHMARK(eina_bench_sort_ecore_default), 10, 10000, 100);
|
eina_benchmark_register(bench, "ecore", EINA_BENCHMARK(eina_bench_sort_ecore_default), 10, 10000, 100);
|
||||||
eina_benchmark_register(bench, "ecore-merge", EINA_BENCHMARK(eina_bench_sort_ecore_merge), 10, 10000, 100);
|
eina_benchmark_register(bench, "ecore-merge", EINA_BENCHMARK(eina_bench_sort_ecore_merge), 10, 10000, 100);
|
||||||
eina_benchmark_register(bench, "ecore-heap", EINA_BENCHMARK(eina_bench_sort_ecore_heap), 10, 10000, 100);
|
eina_benchmark_register(bench, "ecore-heap", EINA_BENCHMARK(eina_bench_sort_ecore_heap), 10, 10000, 100);
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
#if 0
|
|
||||||
eina_benchmark_register(bench, "evas", EINA_BENCHMARK(eina_bench_sort_evas), 10, 10000, 100);
|
eina_benchmark_register(bench, "evas", EINA_BENCHMARK(eina_bench_sort_evas), 10, 10000, 100);
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,15 +28,13 @@
|
||||||
# include <glib.h>
|
# include <glib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
#include "Evas_Data.h"
|
||||||
# include <Evas.h>
|
#include "Ecore_Data.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "Ecore_Data.h"
|
|
||||||
|
|
||||||
#include "eina_stringshare.h"
|
#include "eina_stringshare.h"
|
||||||
#include "eina_bench.h"
|
#include "eina_bench.h"
|
||||||
#include "eina_convert.h"
|
#include "eina_convert.h"
|
||||||
|
#include "eina_main.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eina_bench_stringshare_job(int request)
|
eina_bench_stringshare_job(int request)
|
||||||
|
@ -102,8 +100,6 @@ eina_bench_stringchunk_job(int request)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
#if 0
|
|
||||||
static void
|
static void
|
||||||
eina_bench_evas_job(int request)
|
eina_bench_evas_job(int request)
|
||||||
{
|
{
|
||||||
|
@ -111,9 +107,6 @@ eina_bench_evas_job(int request)
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
evas_init();
|
|
||||||
/* evas_stringshare_init(); */
|
|
||||||
|
|
||||||
for (i = 0; i < request; ++i)
|
for (i = 0; i < request; ++i)
|
||||||
{
|
{
|
||||||
char build[64] = "string_";
|
char build[64] = "string_";
|
||||||
|
@ -132,12 +125,7 @@ eina_bench_evas_job(int request)
|
||||||
eina_convert_xtoa(rand() % request, build + 7);
|
eina_convert_xtoa(rand() % request, build + 7);
|
||||||
tmp = evas_stringshare_add(build);
|
tmp = evas_stringshare_add(build);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* evas_stringshare_shutdown(); */
|
|
||||||
evas_shutdown();
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eina_bench_ecore_job(int request)
|
eina_bench_ecore_job(int request)
|
||||||
|
@ -176,10 +164,6 @@ void eina_bench_stringshare(Eina_Benchmark *bench)
|
||||||
#ifdef EINA_BENCH_HAVE_GLIB
|
#ifdef EINA_BENCH_HAVE_GLIB
|
||||||
eina_benchmark_register(bench, "stringchunk (glib)", EINA_BENCHMARK(eina_bench_stringchunk_job), 100, 20100, 500);
|
eina_benchmark_register(bench, "stringchunk (glib)", EINA_BENCHMARK(eina_bench_stringchunk_job), 100, 20100, 500);
|
||||||
#endif
|
#endif
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
#if 0
|
|
||||||
eina_benchmark_register(bench, "stringshare (evas)", EINA_BENCHMARK(eina_bench_evas_job), 100, 20100, 500);
|
eina_benchmark_register(bench, "stringshare (evas)", EINA_BENCHMARK(eina_bench_evas_job), 100, 20100, 500);
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
eina_benchmark_register(bench, "stringshare (ecore)", EINA_BENCHMARK(eina_bench_ecore_job), 100, 20100, 500);
|
eina_benchmark_register(bench, "stringshare (ecore)", EINA_BENCHMARK(eina_bench_ecore_job), 100, 20100, 500);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,13 +28,8 @@
|
||||||
# include <glib.h>
|
# include <glib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
#include "Evas_Data.h"
|
||||||
# include <Evas.h>
|
#include "Ecore_Data.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_ECORE
|
|
||||||
# include <Ecore_Data.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Eina.h"
|
#include "Eina.h"
|
||||||
|
|
||||||
|
@ -60,17 +55,14 @@ static Eina_Stringshare_Test eina_str = {
|
||||||
eina_shutdown
|
eina_shutdown
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
static Eina_Stringshare_Test evas_str = {
|
static Eina_Stringshare_Test evas_str = {
|
||||||
"evas",
|
"evas",
|
||||||
evas_init,
|
evas_stringshare_init,
|
||||||
evas_stringshare_add,
|
evas_stringshare_add,
|
||||||
evas_stringshare_del,
|
evas_stringshare_del,
|
||||||
evas_shutdown
|
evas_stringshare_shutdown
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EINA_BENCH_HAVE_ECORE
|
|
||||||
static Eina_Stringshare_Test ecore_str = {
|
static Eina_Stringshare_Test ecore_str = {
|
||||||
"ecore",
|
"ecore",
|
||||||
ecore_string_init,
|
ecore_string_init,
|
||||||
|
@ -78,16 +70,11 @@ static Eina_Stringshare_Test ecore_str = {
|
||||||
ecore_string_release,
|
ecore_string_release,
|
||||||
ecore_string_shutdown
|
ecore_string_shutdown
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
static Eina_Stringshare_Test* str[] = {
|
static Eina_Stringshare_Test* str[] = {
|
||||||
&eina_str,
|
&eina_str,
|
||||||
#ifdef EINA_BENCH_HAVE_EVAS
|
|
||||||
&evas_str,
|
&evas_str,
|
||||||
#endif
|
|
||||||
#ifdef EINA_BENCH_HAVE_ECORE
|
|
||||||
&ecore_str,
|
&ecore_str,
|
||||||
#endif
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,498 @@
|
||||||
|
/*
|
||||||
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Evas_Data.h"
|
||||||
|
|
||||||
|
typedef struct _Evas_Hash_El Evas_Hash_El;
|
||||||
|
|
||||||
|
struct _Evas_Hash_El
|
||||||
|
{
|
||||||
|
Evas_Object_List _list_data;
|
||||||
|
const char *key;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int _evas_hash_gen(const char *key);
|
||||||
|
|
||||||
|
static int _evas_hash_alloc_error = 0;
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
_evas_hash_gen(const char *key)
|
||||||
|
{
|
||||||
|
unsigned int hash_num = 5381;
|
||||||
|
const unsigned char *ptr;
|
||||||
|
|
||||||
|
if (!key) return 0;
|
||||||
|
for (ptr = (unsigned char *)key; *ptr; ptr++)
|
||||||
|
hash_num = (hash_num * 33) ^ *ptr;
|
||||||
|
|
||||||
|
hash_num &= 0xff;
|
||||||
|
return (int)hash_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Evas_Hash_Data Hash Data Functions
|
||||||
|
*
|
||||||
|
* Functions that add, access or remove data from hashes.
|
||||||
|
*
|
||||||
|
* The following example shows how to add and then access data in a
|
||||||
|
* hash table:
|
||||||
|
* @code
|
||||||
|
* Evas_Hash *hash = NULL;
|
||||||
|
* extern void *my_data;
|
||||||
|
*
|
||||||
|
* hash = evas_hash_add(hash, "My Data", my_data);
|
||||||
|
* if (evas_hash_alloc_error())
|
||||||
|
* {
|
||||||
|
* fprintf(stderr, "ERROR: Memory is low. Hash allocation failed.\n");
|
||||||
|
* exit(-1);
|
||||||
|
* }
|
||||||
|
* if (evas_hash_find(hash, "My Data") == my_data)
|
||||||
|
* {
|
||||||
|
* printf("My Data inserted and successfully found.\n");
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* What follows is another example, showing how the @ref evas_hash_del
|
||||||
|
* function is used:
|
||||||
|
* @code
|
||||||
|
* extern Evas_Hash *hash;
|
||||||
|
* extern void *data;
|
||||||
|
*
|
||||||
|
* printf("Insert some data...\n");
|
||||||
|
* hash = evas_hash_add(hash, "My Data", my_data);
|
||||||
|
* printf("Removing by key...\n");
|
||||||
|
* hash = evas_hash_del(hash, "My Data", NULL);
|
||||||
|
* printf("Insert some more data as a NULL key...\n");
|
||||||
|
* hash = evas_hash_add(hash, NULL, my_data);
|
||||||
|
* printf("Removing by data as a NULL key...\n");
|
||||||
|
* hash = evas_hash_del(hash, NULL, my_data);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an entry to the given hash table.
|
||||||
|
*
|
||||||
|
* @p key is expected to be a unique string within the hash table.
|
||||||
|
* Otherwise, you cannot be sure which inserted data pointer will be
|
||||||
|
* accessed with @ref evas_hash_find , and removed with
|
||||||
|
* @ref evas_hash_del .
|
||||||
|
*
|
||||||
|
* Key strings are case sensitive.
|
||||||
|
*
|
||||||
|
* @ref evas_hash_alloc_error should be used to determine if an
|
||||||
|
* allocation error occurred during this function.
|
||||||
|
*
|
||||||
|
* @param hash The given hash table. Can be @c NULL, in which case a
|
||||||
|
* new hash table is allocated and returned.
|
||||||
|
* @param key A unique string. Can be @c NULL.
|
||||||
|
* @param data Data to associate with the string given by @p key.
|
||||||
|
* @return Either the given hash table, or if the given value for @p
|
||||||
|
* hash is @c NULL, then a new one. @c NULL will be returned
|
||||||
|
* if memory could not be allocated for a new table.
|
||||||
|
* @ingroup Evas_Hash_Data
|
||||||
|
*/
|
||||||
|
EAPI Evas_Hash *
|
||||||
|
evas_hash_add(Evas_Hash *hash, const char *key, const void *data)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Evas_Hash_El *el;
|
||||||
|
|
||||||
|
if ((!key) || (!data)) return hash;
|
||||||
|
_evas_hash_alloc_error = 0;
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
hash = calloc(1, sizeof(struct _Evas_Hash));
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
_evas_hash_alloc_error = 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(el = malloc(sizeof(struct _Evas_Hash_El) + strlen(key) + 1)))
|
||||||
|
{
|
||||||
|
if (hash->population <= 0)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
hash = NULL;
|
||||||
|
}
|
||||||
|
_evas_hash_alloc_error = 1;
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
el->key = ((char *)el) + sizeof(struct _Evas_Hash_El);
|
||||||
|
strcpy((char *) el->key, key);
|
||||||
|
el->data = (void *)data;
|
||||||
|
hash_num = _evas_hash_gen(key);
|
||||||
|
hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el);
|
||||||
|
hash->population++;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an entry to the given hash table and does not duplicate the string key.
|
||||||
|
*
|
||||||
|
* @p key is expected to be a unique string within the hash table.
|
||||||
|
* Otherwise, you cannot be sure which inserted data pointer will be
|
||||||
|
* accessed with @ref evas_hash_find , and removed with
|
||||||
|
* @ref evas_hash_del . This call does not make a copy of the key so it must
|
||||||
|
* be a string constant or stored elsewhere (in the object being added) etc.
|
||||||
|
*
|
||||||
|
* Key strings are case sensitive.
|
||||||
|
*
|
||||||
|
* @ref evas_hash_alloc_error should be used to determine if an
|
||||||
|
* allocation error occurred during this function.
|
||||||
|
*
|
||||||
|
* @param hash The given hash table. Can be @c NULL, in which case a
|
||||||
|
* new hash table is allocated and returned.
|
||||||
|
* @param key A unique string. Can be @c NULL.
|
||||||
|
* @param data Data to associate with the string given by @p key.
|
||||||
|
* @return Either the given hash table, or if the given value for @p
|
||||||
|
* hash is @c NULL, then a new one. @c NULL will be returned
|
||||||
|
* if memory could not be allocated for a new table.
|
||||||
|
* @ingroup Evas_Hash_Data
|
||||||
|
*/
|
||||||
|
EAPI Evas_Hash *
|
||||||
|
evas_hash_direct_add(Evas_Hash *hash, const char *key, const void *data)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Evas_Hash_El *el;
|
||||||
|
|
||||||
|
if ((!key) || (!data)) return hash;
|
||||||
|
_evas_hash_alloc_error = 0;
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
hash = calloc(1, sizeof(struct _Evas_Hash));
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
_evas_hash_alloc_error = 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(el = malloc(sizeof(struct _Evas_Hash_El))))
|
||||||
|
{
|
||||||
|
if (hash->population <= 0)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
hash = NULL;
|
||||||
|
}
|
||||||
|
_evas_hash_alloc_error = 1;
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
el->key = key;
|
||||||
|
el->data = (void *)data;
|
||||||
|
hash_num = _evas_hash_gen(key);
|
||||||
|
hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el);
|
||||||
|
hash->population++;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the entry identified by @p key or @p data from the given
|
||||||
|
* hash table.
|
||||||
|
*
|
||||||
|
* If @p key is @c NULL, then @p data is used to find a match to
|
||||||
|
* remove.
|
||||||
|
*
|
||||||
|
* @param hash The given hash table.
|
||||||
|
* @param key The key string. Can be @c NULL.
|
||||||
|
* @param data The data pointer to remove if @p key is @c NULL.
|
||||||
|
* Otherwise, not required and can be @c NULL.
|
||||||
|
* @return The modified hash table. If there are no entries left, the
|
||||||
|
* hash table will be freed and @c NULL will be returned.
|
||||||
|
* @ingroup Evas_Hash_Data
|
||||||
|
*/
|
||||||
|
EAPI Evas_Hash *
|
||||||
|
evas_hash_del(Evas_Hash *hash, const char *key, const void *data)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Evas_Hash_El *el;
|
||||||
|
Evas_Object_List *l;
|
||||||
|
|
||||||
|
if (!hash) return NULL;
|
||||||
|
if (!key)
|
||||||
|
{
|
||||||
|
for (hash_num = 0; hash_num < 256; hash_num++)
|
||||||
|
{
|
||||||
|
for (l = hash->buckets[hash_num]; l; l = l->next)
|
||||||
|
{
|
||||||
|
el = (Evas_Hash_El *)l;
|
||||||
|
if (el->data == data)
|
||||||
|
{
|
||||||
|
hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el);
|
||||||
|
free(el);
|
||||||
|
hash->population--;
|
||||||
|
if (hash->population <= 0)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
hash = NULL;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hash_num = _evas_hash_gen(key);
|
||||||
|
for (l = hash->buckets[hash_num]; l; l = l->next)
|
||||||
|
{
|
||||||
|
el = (Evas_Hash_El *)l;
|
||||||
|
if (!strcmp(el->key, key))
|
||||||
|
{
|
||||||
|
if ((!data) || (el->data == data))
|
||||||
|
{
|
||||||
|
hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el);
|
||||||
|
free(el);
|
||||||
|
hash->population--;
|
||||||
|
if (hash->population <= 0)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
hash = NULL;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific entry in the given hash table.
|
||||||
|
* @param hash The given hash table.
|
||||||
|
* @param key The key string of the entry to find.
|
||||||
|
* @return The data pointer for the stored entry, or @c NULL if not
|
||||||
|
* found.
|
||||||
|
* @ingroup Evas_Hash_Data
|
||||||
|
*/
|
||||||
|
EAPI void *
|
||||||
|
evas_hash_find(const Evas_Hash *hash, const char *key)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Evas_Hash_El *el;
|
||||||
|
Evas_Object_List *l;
|
||||||
|
|
||||||
|
_evas_hash_alloc_error = 0;
|
||||||
|
if ((!hash) || (!key)) return NULL;
|
||||||
|
hash_num = _evas_hash_gen(key);
|
||||||
|
for (l = hash->buckets[hash_num]; l; l = l->next)
|
||||||
|
{
|
||||||
|
el = (Evas_Hash_El *)l;
|
||||||
|
if (!strcmp(el->key, key))
|
||||||
|
{
|
||||||
|
if (l != hash->buckets[hash_num])
|
||||||
|
{
|
||||||
|
Evas_Object_List *bucket;
|
||||||
|
|
||||||
|
bucket = hash->buckets[hash_num];
|
||||||
|
bucket = evas_object_list_remove(bucket, el);
|
||||||
|
bucket = evas_object_list_prepend(bucket, el);
|
||||||
|
((Evas_Hash *)hash)->buckets[hash_num] = bucket;
|
||||||
|
}
|
||||||
|
return el->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the entry pointer at the specified key and returns the old entry
|
||||||
|
* @param hash The given hash table.
|
||||||
|
* @param key The key string of the entry to modify.
|
||||||
|
* @param data The data to replace the old entry, if it exists.
|
||||||
|
* @return The data pointer for the old stored entry, or @c NULL if not
|
||||||
|
* found. If an existing entry is not found, nothing is added to the
|
||||||
|
* hash.
|
||||||
|
* @ingroup Evas_Hash_Data
|
||||||
|
*/
|
||||||
|
EAPI void *
|
||||||
|
evas_hash_modify(Evas_Hash *hash, const char *key, const void *data)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Evas_Hash_El *el;
|
||||||
|
Evas_Object_List *l;
|
||||||
|
|
||||||
|
_evas_hash_alloc_error = 0;
|
||||||
|
if (!hash) return NULL;
|
||||||
|
hash_num = _evas_hash_gen(key);
|
||||||
|
for (l = hash->buckets[hash_num]; l; l = l->next)
|
||||||
|
{
|
||||||
|
el = (Evas_Hash_El *)l;
|
||||||
|
if ((key) && (!strcmp(el->key, key)))
|
||||||
|
{
|
||||||
|
void *old_data;
|
||||||
|
|
||||||
|
if (l != hash->buckets[hash_num])
|
||||||
|
{
|
||||||
|
hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el);
|
||||||
|
hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el);
|
||||||
|
}
|
||||||
|
old_data = el->data;
|
||||||
|
el->data = (void *) data;
|
||||||
|
return old_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Evas_Hash_General_Group Hash General Functions
|
||||||
|
*
|
||||||
|
* Miscellaneous functions that operate on hash objects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the number of buckets available in the given hash table.
|
||||||
|
* @param hash The given hash table.
|
||||||
|
* @return @c 256 if @p hash is not @c NULL. @c 0 otherwise.
|
||||||
|
* @ingroup Evas_Hash_General_Group
|
||||||
|
*/
|
||||||
|
EAPI int
|
||||||
|
evas_hash_size(const Evas_Hash *hash)
|
||||||
|
{
|
||||||
|
if (!hash) return 0;
|
||||||
|
return 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo Complete polishing documentation for evas_hash.c. The
|
||||||
|
* functions' docs may be grouped, but they need some simplification.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free an entire hash table
|
||||||
|
* @param hash The hash table to be freed
|
||||||
|
*
|
||||||
|
* This function frees up all the memory allocated to storing the specified
|
||||||
|
* hash tale pointed to by @p hash. Any entries in the table that the program
|
||||||
|
* has no more pointers for elsewhere may now be lost, so this should only be
|
||||||
|
* called if the program has lready freed any allocated data in the hash table
|
||||||
|
* or has the pointers for data in teh table stored elswehere as well.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* extern Evas_Hash *hash;
|
||||||
|
*
|
||||||
|
* evas_hash_free(hash);
|
||||||
|
* hash = NULL;
|
||||||
|
* @endcode
|
||||||
|
* @ingroup Evas_Hash_General_Group
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
evas_hash_free(Evas_Hash *hash)
|
||||||
|
{
|
||||||
|
int i, size;
|
||||||
|
|
||||||
|
if (!hash) return;
|
||||||
|
size = evas_hash_size(hash);
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
while (hash->buckets[i])
|
||||||
|
{
|
||||||
|
Evas_Hash_El *el;
|
||||||
|
|
||||||
|
el = (Evas_Hash_El *)hash->buckets[i];
|
||||||
|
hash->buckets[i] = evas_object_list_remove(hash->buckets[i], el);
|
||||||
|
free(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a function on every member stored in the hash table
|
||||||
|
* @param hash The hash table whose members will be walked
|
||||||
|
* @param func The function to call on each parameter
|
||||||
|
* @param fdata The data pointer to pass to the function being called
|
||||||
|
*
|
||||||
|
* This function goes through every entry in the hash table @p hash and calls
|
||||||
|
* the function @p func on each member. The function should NOT modify the
|
||||||
|
* hash table contents if it returns 1. IF the hash table contents are
|
||||||
|
* modified by this function or the function wishes to stop processing it must
|
||||||
|
* return 0, otherwise return 1 to keep processing.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* extern Evas_Hash *hash;
|
||||||
|
*
|
||||||
|
* Evas_Bool hash_fn(Evas_Hash *hash, const char *key, void *data, void *fdata)
|
||||||
|
* {
|
||||||
|
* printf("Func data: %s, Hash entry: %s / %p\n", fdata, key, data);
|
||||||
|
* return 1;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* int main(int argc, char **argv)
|
||||||
|
* {
|
||||||
|
* char *hash_fn_data;
|
||||||
|
*
|
||||||
|
* hash_fn_data = strdup("Hello World");
|
||||||
|
* evas_hash_foreach(hash, hash_fn, hash_fn_data);
|
||||||
|
* free(hash_fn_data);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @ingroup Evas_Hash_General_Group
|
||||||
|
*/
|
||||||
|
EAPI void
|
||||||
|
evas_hash_foreach(const Evas_Hash *hash, Evas_Bool (*func) (const Evas_Hash *hash, const char *key, void *data, void *fdata), const void *fdata)
|
||||||
|
{
|
||||||
|
int i, size;
|
||||||
|
|
||||||
|
if (!hash) return;
|
||||||
|
size = evas_hash_size(hash);
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
Evas_Object_List *l, *next_l;
|
||||||
|
|
||||||
|
for (l = hash->buckets[i]; l;)
|
||||||
|
{
|
||||||
|
Evas_Hash_El *el;
|
||||||
|
|
||||||
|
next_l = l->next;
|
||||||
|
el = (Evas_Hash_El *)l;
|
||||||
|
if (!func(hash, el->key, el->data, (void *)fdata)) return;
|
||||||
|
l = next_l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return memory allocation failure flag after an function requiring allocation
|
||||||
|
* @return The state of the allocation flag
|
||||||
|
*
|
||||||
|
* This function returns the state of the memory allocation flag. This flag is
|
||||||
|
* set if memory allocations fail during evas_hash_add() calls. If they do, 1
|
||||||
|
* will be returned, otherwise 0 will be returned. The flag will remain in its
|
||||||
|
* current state until the next call that requires allocation is called, and
|
||||||
|
* is then reset.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* Evas_Hash *hash = NULL;
|
||||||
|
* extern void *my_data;
|
||||||
|
*
|
||||||
|
* hash = evas_hash_add(hash, "My Data", my_data);
|
||||||
|
* if (evas_hash_alloc_error())
|
||||||
|
* {
|
||||||
|
* fprintf(stderr, "ERROR: Memory is low. Hash allocation failed.\n");
|
||||||
|
* exit(-1);
|
||||||
|
* }
|
||||||
|
* if (evas_hash_find(hash, "My Data") == my_data)
|
||||||
|
* {
|
||||||
|
* printf("My Data inserted and successfully found.\n");
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @ingroup Evas_Hash_General_Group
|
||||||
|
*/
|
||||||
|
EAPI int
|
||||||
|
evas_hash_alloc_error(void)
|
||||||
|
{
|
||||||
|
return _evas_hash_alloc_error;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Evas_Data.h"
|
||||||
|
#include "evas_mempool.h"
|
||||||
|
|
||||||
|
//#define NOPOOL
|
||||||
|
|
||||||
|
typedef struct _Pool Pool;
|
||||||
|
|
||||||
|
struct _Pool
|
||||||
|
{
|
||||||
|
int usage;
|
||||||
|
void *base;
|
||||||
|
Pool *prev, *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Pool *
|
||||||
|
_evas_mp_pool_new(Evas_Mempool *pool)
|
||||||
|
#ifdef NOPOOL
|
||||||
|
{
|
||||||
|
static Pool thepool;
|
||||||
|
return &thepool;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
Pool *p;
|
||||||
|
void **ptr;
|
||||||
|
int item_alloc, i;
|
||||||
|
|
||||||
|
item_alloc = ((pool->item_size + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *);
|
||||||
|
p = malloc(sizeof(Pool) + (pool->pool_size * item_alloc));
|
||||||
|
ptr = (void **)(((unsigned char *)p) + sizeof(Pool));
|
||||||
|
p->usage = 0;
|
||||||
|
p->base = ptr;
|
||||||
|
for (i = 0; i < pool->pool_size - 1; i++)
|
||||||
|
{
|
||||||
|
*ptr = (void **)(((unsigned char *)ptr) + item_alloc);
|
||||||
|
ptr = *ptr;
|
||||||
|
}
|
||||||
|
*ptr = NULL;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
_evas_mp_pool_free(Pool *p)
|
||||||
|
#ifdef NOPOOL
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *
|
||||||
|
evas_mempool_malloc(Evas_Mempool *pool, int size)
|
||||||
|
#ifdef NOPOOL
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
Pool *p;
|
||||||
|
void *mem;
|
||||||
|
|
||||||
|
for (p = pool->first; p; p = p->next) // look 4 pool from 2nd bucket on
|
||||||
|
{
|
||||||
|
if (p->base) // base is not NULL - has a free slot
|
||||||
|
{
|
||||||
|
if (p->prev)
|
||||||
|
{
|
||||||
|
if (pool->last == p) pool->last = p->prev;
|
||||||
|
p->prev->next = p->next;
|
||||||
|
p->prev = NULL;
|
||||||
|
p->next = pool->first;
|
||||||
|
p->next->prev = p;
|
||||||
|
pool->first = p;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!p) // we have reached the end of the list - no free pools
|
||||||
|
{
|
||||||
|
p = _evas_mp_pool_new(pool);
|
||||||
|
if (!p) return NULL;
|
||||||
|
p->prev = NULL;
|
||||||
|
p->next = pool->first;
|
||||||
|
if (p->next) p->next->prev = p;
|
||||||
|
if (!pool->last) pool->last = p;
|
||||||
|
pool->first = p;
|
||||||
|
}
|
||||||
|
mem = p->base; // this points to the next free block - so take it
|
||||||
|
p->base = *((void **)mem); // base now points to the next free block
|
||||||
|
if (!p->base) // move to end - it just filled up
|
||||||
|
{
|
||||||
|
if (p->next)
|
||||||
|
{
|
||||||
|
if (p->prev) p->prev->next = p->next;
|
||||||
|
else pool->first = p->next;
|
||||||
|
p->next->prev = p->prev;
|
||||||
|
((Pool *)pool->last)->next = p;
|
||||||
|
p->prev = pool->last;
|
||||||
|
p->next = NULL;
|
||||||
|
pool->last = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->usage++;
|
||||||
|
pool->usage++;
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
evas_mempool_free(Evas_Mempool *pool, void *ptr)
|
||||||
|
#ifdef NOPOOL
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
Pool *p;
|
||||||
|
void *pmem;
|
||||||
|
int item_alloc, psize;
|
||||||
|
|
||||||
|
item_alloc = ((pool->item_size + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *);
|
||||||
|
psize = item_alloc * pool->pool_size;
|
||||||
|
for (p = (Pool *)(pool->first); p; p = p->next) // look 4 pool
|
||||||
|
{
|
||||||
|
pmem = (void *)(((unsigned char *)p) + sizeof(Pool)); // pool mem base
|
||||||
|
if ((ptr >= pmem) && ((unsigned char *)ptr < (((unsigned char *)pmem) + psize))) // is it in pool mem?
|
||||||
|
{
|
||||||
|
*((void **)ptr) = p->base; // freed node points to prev free node
|
||||||
|
p->base = ptr; // next free node is now the one we freed
|
||||||
|
p->usage--;
|
||||||
|
pool->usage--;
|
||||||
|
if (p->usage == 0) // free bucket
|
||||||
|
{
|
||||||
|
if (p->prev) p->prev->next = p->next;
|
||||||
|
if (p->next) p->next->prev = p->prev;
|
||||||
|
if (pool->last == p) pool->last = p->prev;
|
||||||
|
if (pool->first == p) pool->first = p->next;
|
||||||
|
_evas_mp_pool_free(p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p->prev) // if not the first - move to front
|
||||||
|
{
|
||||||
|
p->prev->next = p->next;
|
||||||
|
if (p->next) p->next->prev = p->prev;
|
||||||
|
if (pool->last == p) pool->last = p->prev;
|
||||||
|
p->prev = NULL;
|
||||||
|
p->next = pool->first;
|
||||||
|
p->next->prev = p;
|
||||||
|
pool->first = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *
|
||||||
|
evas_mempool_calloc(Evas_Mempool *pool, int size)
|
||||||
|
#ifdef NOPOOL
|
||||||
|
{
|
||||||
|
return calloc(1, size);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
void *mem;
|
||||||
|
|
||||||
|
mem = evas_mempool_malloc(pool, size);
|
||||||
|
memset(mem, 0, size);
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _EVAS_MEMPOOL_H
|
||||||
|
#define _EVAS_MEMPOOL_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _Evas_Mempool Evas_Mempool;
|
||||||
|
|
||||||
|
struct _Evas_Mempool
|
||||||
|
{
|
||||||
|
int item_size;
|
||||||
|
int pool_size;
|
||||||
|
int usage;
|
||||||
|
void *first, *last;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void *evas_mempool_malloc(Evas_Mempool *pool, int size);
|
||||||
|
void evas_mempool_free(Evas_Mempool *pool, void *ptr);
|
||||||
|
void *evas_mempool_calloc(Evas_Mempool *pool, int size);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _EVAS_MEMPOOL_H */
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "Evas_Data.h"
|
||||||
|
|
||||||
|
/* list ops */
|
||||||
|
void *
|
||||||
|
evas_object_list_append(void *in_list, void *in_item)
|
||||||
|
{
|
||||||
|
Evas_Object_List *l, *new_l;
|
||||||
|
Evas_Object_List *list;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
new_l = in_item;
|
||||||
|
new_l->next = NULL;
|
||||||
|
if (!list)
|
||||||
|
{
|
||||||
|
new_l->prev = NULL;
|
||||||
|
new_l->last = new_l;
|
||||||
|
return new_l;
|
||||||
|
}
|
||||||
|
if (list->last) l = list->last;
|
||||||
|
else for (l = list; (l) && (l->next); l = l->next);
|
||||||
|
l->next = new_l;
|
||||||
|
new_l->prev = l;
|
||||||
|
list->last = new_l;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
evas_object_list_prepend(void *in_list, void *in_item)
|
||||||
|
{
|
||||||
|
Evas_Object_List *new_l;
|
||||||
|
Evas_Object_List *list;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
new_l = in_item;
|
||||||
|
new_l->prev = NULL;
|
||||||
|
if (!list)
|
||||||
|
{
|
||||||
|
new_l->next = NULL;
|
||||||
|
new_l->last = new_l;
|
||||||
|
return new_l;
|
||||||
|
}
|
||||||
|
new_l->next = list;
|
||||||
|
list->prev = new_l;
|
||||||
|
new_l->last = list->last;
|
||||||
|
list->last = NULL;
|
||||||
|
return new_l;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
evas_object_list_append_relative(void *in_list, void *in_item, void *in_relative)
|
||||||
|
{
|
||||||
|
Evas_Object_List *list, *relative, *new_l;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
new_l = in_item;
|
||||||
|
relative = in_relative;
|
||||||
|
if (relative)
|
||||||
|
{
|
||||||
|
if (relative->next)
|
||||||
|
{
|
||||||
|
new_l->next = relative->next;
|
||||||
|
relative->next->prev = new_l;
|
||||||
|
}
|
||||||
|
else new_l->next = NULL;
|
||||||
|
relative->next = new_l;
|
||||||
|
new_l->prev = relative;
|
||||||
|
if (!new_l->next) list->last = new_l;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
return evas_object_list_append(list, new_l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
evas_object_list_prepend_relative(void *in_list, void *in_item, void *in_relative)
|
||||||
|
{
|
||||||
|
Evas_Object_List *list, *relative, *new_l;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
new_l = in_item;
|
||||||
|
relative = in_relative;
|
||||||
|
if (relative)
|
||||||
|
{
|
||||||
|
new_l->prev = relative->prev;
|
||||||
|
new_l->next = relative;
|
||||||
|
relative->prev = new_l;
|
||||||
|
if (new_l->prev)
|
||||||
|
{
|
||||||
|
new_l->prev->next = new_l;
|
||||||
|
if (!new_l->next)
|
||||||
|
list->last = new_l;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!new_l->next)
|
||||||
|
new_l->last = new_l;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_l->last = list->last;
|
||||||
|
list->last = NULL;
|
||||||
|
}
|
||||||
|
return new_l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return evas_object_list_prepend(list, new_l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
evas_object_list_remove(void *in_list, void *in_item)
|
||||||
|
{
|
||||||
|
Evas_Object_List *return_l;
|
||||||
|
Evas_Object_List *list, *item;
|
||||||
|
|
||||||
|
/* checkme */
|
||||||
|
if(!in_list)
|
||||||
|
return in_list;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
item = in_item;
|
||||||
|
if (!item) return list;
|
||||||
|
if (item->next)
|
||||||
|
item->next->prev = item->prev;
|
||||||
|
if (item->prev)
|
||||||
|
{
|
||||||
|
item->prev->next = item->next;
|
||||||
|
return_l = list;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return_l = item->next;
|
||||||
|
if (return_l)
|
||||||
|
return_l->last = list->last;
|
||||||
|
}
|
||||||
|
if (item == list->last)
|
||||||
|
list->last = item->prev;
|
||||||
|
item->next = NULL;
|
||||||
|
item->prev = NULL;
|
||||||
|
return return_l;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
evas_object_list_find(void *in_list, void *in_item)
|
||||||
|
{
|
||||||
|
Evas_Object_List *l;
|
||||||
|
Evas_Object_List *list, *item;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
item = in_item;
|
||||||
|
for (l = list; l; l = l->next)
|
||||||
|
{
|
||||||
|
if (l == item) return item;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,205 @@
|
||||||
|
/*
|
||||||
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "Evas_Data.h"
|
||||||
|
|
||||||
|
typedef struct _Evas_Stringshare Evas_Stringshare;
|
||||||
|
typedef struct _Evas_Stringshare_El Evas_Stringshare_El;
|
||||||
|
|
||||||
|
struct _Evas_Stringshare
|
||||||
|
{
|
||||||
|
Evas_Stringshare_El *buckets[1024];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _Evas_Stringshare_El
|
||||||
|
{
|
||||||
|
Evas_Stringshare_El *next;
|
||||||
|
// int op;
|
||||||
|
int references;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Evas_Stringshare share =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//static int op = 0;
|
||||||
|
//static FILE *f = NULL;
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
_evas_stringshare_hash_gen(const char *str, int *len)
|
||||||
|
{
|
||||||
|
unsigned int hash_num = 5381;
|
||||||
|
const unsigned char *ptr;
|
||||||
|
|
||||||
|
for (ptr = (const unsigned char *)str; *ptr; ptr++)
|
||||||
|
{
|
||||||
|
hash_num = (hash_num * 33) ^ *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_num &= 0x3ff;
|
||||||
|
*len = ptr - (const unsigned char *)str;
|
||||||
|
return (int)hash_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI const char *
|
||||||
|
evas_stringshare_add(const char *str)
|
||||||
|
{
|
||||||
|
int hash_num, slen;
|
||||||
|
char *el_str;
|
||||||
|
Evas_Stringshare_El *el, *pel = NULL;
|
||||||
|
|
||||||
|
if (!str) return NULL;
|
||||||
|
// if (!f)
|
||||||
|
// {
|
||||||
|
// char bf[256];
|
||||||
|
// snprintf(bf, sizeof(bf), "strlog-%i", getpid());
|
||||||
|
// f = fopen(bf, "w");
|
||||||
|
// }
|
||||||
|
hash_num = _evas_stringshare_hash_gen(str, &slen);
|
||||||
|
for (el = share.buckets[hash_num]; el; pel = el, el = el->next)
|
||||||
|
{
|
||||||
|
el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
|
||||||
|
if (!strcmp(el_str, str))
|
||||||
|
{
|
||||||
|
if (pel)
|
||||||
|
{
|
||||||
|
pel->next = el->next;
|
||||||
|
el->next = share.buckets[hash_num];
|
||||||
|
share.buckets[hash_num] = el;
|
||||||
|
}
|
||||||
|
el->references++;
|
||||||
|
// fprintf(f, "strings[%i] = str->add(strings[%i]);\n", el->op, el->op);
|
||||||
|
// fflush(f);
|
||||||
|
return el_str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(el = malloc(sizeof(Evas_Stringshare_El) + slen + 1))) return NULL;
|
||||||
|
el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
|
||||||
|
strcpy(el_str, str);
|
||||||
|
el->references = 1;
|
||||||
|
el->next = share.buckets[hash_num];
|
||||||
|
share.buckets[hash_num] = el;
|
||||||
|
// el->op = op;
|
||||||
|
// fprintf(f, "strings[%i] = str->add(\"%s\");\n", el->op, el_str);
|
||||||
|
// fflush(f);
|
||||||
|
// op++;
|
||||||
|
return el_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
evas_stringshare_del(const char *str)
|
||||||
|
{
|
||||||
|
int hash_num, slen;
|
||||||
|
char *el_str;
|
||||||
|
Evas_Stringshare_El *el, *pel = NULL;
|
||||||
|
|
||||||
|
if (!str) return;
|
||||||
|
hash_num = _evas_stringshare_hash_gen(str, &slen);
|
||||||
|
for (el = share.buckets[hash_num]; el; pel = el, el = el->next)
|
||||||
|
{
|
||||||
|
el_str = ((char *)el) + sizeof(Evas_Stringshare_El);
|
||||||
|
if (el_str == str)
|
||||||
|
{
|
||||||
|
el->references--;
|
||||||
|
// fprintf(f, "str->del(strings[%i]);\n", el->op);
|
||||||
|
// fflush(f);
|
||||||
|
if (el->references == 0)
|
||||||
|
{
|
||||||
|
if (pel) pel->next = el->next;
|
||||||
|
else share.buckets[hash_num] = el->next;
|
||||||
|
free(el);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pel)
|
||||||
|
{
|
||||||
|
pel->next = el->next;
|
||||||
|
el->next = share.buckets[hash_num];
|
||||||
|
share.buckets[hash_num] = el;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("EEEK trying to del non-shared stringshare \"%s\"\n", str);
|
||||||
|
abort();
|
||||||
|
}
|
Loading…
Reference in New Issue