forked from enlightenment/efl
benchmark: eina: remove outdated ecore_hash
Ecore_hash is an ancestor of eina_hash and not used anywhere anymore. We simply forgot to remove it from our benchmark utility. Together with ecore_hash we are removing ecore_strings, which uses it, and the corresponding benchmark files. Signed-off-by: Stefan Schmidt <s.schmidt@samsung.com> Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de> Differential Revision: https://phab.enlightenment.org/D12042
This commit is contained in:
parent
972cd7f62b
commit
cac95313c7
|
@ -2188,10 +2188,8 @@ src/benchmarks/evas/evas_bench_saver.c
|
|||
src/benchmarks/evas/evas_bench_loader.c
|
||||
src/benchmarks/elementary/collection.c
|
||||
src/benchmarks/elementary/focus_widget_tree.c
|
||||
src/benchmarks/eina/eina_bench_stringshare_e17.c
|
||||
src/benchmarks/eina/eina_bench_convert.c
|
||||
src/benchmarks/eina/eina_bench_mempool.c
|
||||
src/benchmarks/eina/ecore_hash.c
|
||||
src/benchmarks/eina/eina_bench_stringshare.c
|
||||
src/benchmarks/eina/eina_bench_crc_hash.c
|
||||
src/benchmarks/eina/evas_object_list.c
|
||||
|
@ -2201,10 +2199,8 @@ src/benchmarks/eina/eina_bench_rectangle_pool.c
|
|||
src/benchmarks/eina/eina_bench_quad.c
|
||||
src/benchmarks/eina/evas_mempool.c
|
||||
src/benchmarks/eina/eina_bench_array.c
|
||||
src/benchmarks/eina/ecore_strings.c
|
||||
src/benchmarks/eina/eina_bench_sort.c
|
||||
src/benchmarks/eina/ecore_list.c
|
||||
src/benchmarks/eina/evas_stringshare.c
|
||||
src/benchmarks/eina/ecore_sheap.c
|
||||
src/benchmarks/eina/eina_bench_hash.c
|
||||
src/benchmarks/eina/evas_list.c
|
||||
|
|
|
@ -299,76 +299,6 @@ EAPI int ecore_dlist_free_cb_set(Ecore_DList *dlist,
|
|||
Ecore_Free_Cb free_func);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Hash Table Implementation:
|
||||
*
|
||||
* Traditional hash table implementation. I had tried a list of tables
|
||||
* approach to save on the realloc's but it ended up being much slower than
|
||||
* the traditional approach.
|
||||
*/
|
||||
|
||||
typedef struct _ecore_hash_node Ecore_Hash_Node;
|
||||
# define ECORE_HASH_NODE(hash) ((Ecore_Hash_Node *)hash)
|
||||
|
||||
struct _ecore_hash_node
|
||||
{
|
||||
Ecore_Hash_Node *next; /* Pointer to the next node in the bucket list */
|
||||
void *key; /* The key for the data node */
|
||||
void *value; /* The value associated with this node */
|
||||
};
|
||||
|
||||
typedef struct _ecore_hash Ecore_Hash;
|
||||
# define ECORE_HASH(hash) ((Ecore_Hash *)hash)
|
||||
|
||||
struct _ecore_hash
|
||||
{
|
||||
Ecore_Hash_Node **buckets;
|
||||
int size; /* An index into the table of primes to
|
||||
determine size */
|
||||
int nodes; /* The number of nodes currently in the hash */
|
||||
|
||||
int index; /* The current index into the bucket table */
|
||||
|
||||
Ecore_Compare_Cb compare; /* The function used to compare node values */
|
||||
Ecore_Hash_Cb hash_func; /* The callback function to determine hash */
|
||||
|
||||
Ecore_Free_Cb free_key; /* The callback function to free key */
|
||||
Ecore_Free_Cb free_value; /* The callback function to free value */
|
||||
};
|
||||
|
||||
/* Create and initialize a hash */
|
||||
EAPI Ecore_Hash *ecore_hash_new(Ecore_Hash_Cb hash_func,
|
||||
Ecore_Compare_Cb compare);
|
||||
EAPI int ecore_hash_init(Ecore_Hash *hash,
|
||||
Ecore_Hash_Cb hash_func,
|
||||
Ecore_Compare_Cb compare);
|
||||
|
||||
/* Functions related to freeing the data in the hash table */
|
||||
EAPI int ecore_hash_free_key_cb_set(Ecore_Hash *hash,
|
||||
Ecore_Free_Cb function);
|
||||
EAPI int ecore_hash_free_value_cb_set(Ecore_Hash *hash,
|
||||
Ecore_Free_Cb function);
|
||||
EAPI void ecore_hash_destroy(Ecore_Hash *hash);
|
||||
|
||||
EAPI int ecore_hash_count(Ecore_Hash *hash);
|
||||
EAPI int ecore_hash_for_each_node(Ecore_Hash *hash,
|
||||
Ecore_For_Each for_each_func,
|
||||
void *user_data);
|
||||
EAPI Ecore_List *ecore_hash_keys(Ecore_Hash *hash);
|
||||
|
||||
/* Retrieve and store data into the hash */
|
||||
EAPI void * ecore_hash_get(Ecore_Hash *hash, const void *key);
|
||||
EAPI int ecore_hash_set(Ecore_Hash *hash, void *key, void *value);
|
||||
EAPI int ecore_hash_hash_set(Ecore_Hash *hash, Ecore_Hash *set);
|
||||
EAPI void * ecore_hash_remove(Ecore_Hash *hash, const void *key);
|
||||
EAPI void * ecore_hash_find(Ecore_Hash *hash,
|
||||
Ecore_Compare_Cb compare,
|
||||
const void *value);
|
||||
EAPI void ecore_hash_dump_graph(Ecore_Hash *hash);
|
||||
EAPI void ecore_hash_dump_stats(Ecore_Hash *hash);
|
||||
|
||||
|
||||
typedef struct _ecore_heap Ecore_Sheap;
|
||||
# define ECORE_HEAP(heap) ((Ecore_Sheap *)heap)
|
||||
|
||||
|
@ -415,11 +345,6 @@ struct _ecore_string
|
|||
int references;
|
||||
};
|
||||
|
||||
EAPI int ecore_string_init();
|
||||
EAPI int ecore_string_shutdown();
|
||||
EAPI const char *ecore_string_instance(const char *string);
|
||||
EAPI void ecore_string_release(const char *string);
|
||||
|
||||
typedef struct _Ecore_Tree_Node Ecore_Tree_Node;
|
||||
# define ECORE_TREE_NODE(object) ((Ecore_Tree_Node *)object)
|
||||
struct _Ecore_Tree_Node
|
||||
|
|
|
@ -1,952 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Ecore_Data.h"
|
||||
|
||||
#define PRIME_TABLE_MAX 21
|
||||
#define PRIME_MIN 17
|
||||
#define PRIME_MAX 16777213
|
||||
|
||||
#define ECORE_HASH_CHAIN_MAX 3
|
||||
|
||||
#define ECORE_COMPUTE_HASH(hash, key) hash->hash_func(key) % \
|
||||
ecore_prime_table[hash->size];
|
||||
|
||||
#define ECORE_HASH_INCREASE(hash) ((hash && ecore_prime_table[hash->size] < \
|
||||
PRIME_MAX) ? \
|
||||
(hash->nodes / \
|
||||
ecore_prime_table[hash->size]) > \
|
||||
ECORE_HASH_CHAIN_MAX : FALSE)
|
||||
#define ECORE_HASH_REDUCE(hash) ((hash && ecore_prime_table[hash->size] > \
|
||||
PRIME_MIN) ? \
|
||||
(double)hash->nodes / \
|
||||
(double)ecore_prime_table[hash->size - 1] \
|
||||
< ((double)ECORE_HASH_CHAIN_MAX * \
|
||||
0.375) : FALSE)
|
||||
|
||||
|
||||
static const unsigned int ecore_prime_table[] =
|
||||
{
|
||||
17, 31, 61, 127, 257, 509, 1021,
|
||||
2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573,
|
||||
2097143, 4194301, 8388617, 16777213
|
||||
};
|
||||
|
||||
|
||||
/* Private hash manipulation functions */
|
||||
static int _ecore_hash_node_add(Ecore_Hash *hash,
|
||||
Ecore_Hash_Node *node);
|
||||
static Ecore_Hash_Node * _ecore_hash_node_get(Ecore_Hash *hash,
|
||||
const void *key);
|
||||
static int _ecore_hash_increase(Ecore_Hash *hash);
|
||||
static int _ecore_hash_decrease(Ecore_Hash *hash);
|
||||
static inline int _ecore_hash_rehash(Ecore_Hash *hash,
|
||||
Ecore_Hash_Node **old_table,
|
||||
int old_size);
|
||||
static int _ecore_hash_bucket_destroy(Ecore_Hash_Node *list,
|
||||
Ecore_Free_Cb keyd,
|
||||
Ecore_Free_Cb valued);
|
||||
static inline Ecore_Hash_Node *_ecore_hash_bucket_get(Ecore_Hash *hash,
|
||||
Ecore_Hash_Node *bucket,
|
||||
const void *key);
|
||||
|
||||
static Ecore_Hash_Node * _ecore_hash_node_new(void *key, void *value);
|
||||
static int _ecore_hash_node_init(Ecore_Hash_Node *node,
|
||||
void *key,
|
||||
void *value);
|
||||
static int _ecore_hash_node_destroy(Ecore_Hash_Node *node,
|
||||
Ecore_Free_Cb keyd,
|
||||
Ecore_Free_Cb valued);
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Data_Hash_ADT_Creation_Group Hash Creation Functions
|
||||
*
|
||||
* Functions that create hash tables.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates and initializes a new hash
|
||||
* @param hash_func The function for determining hash position.
|
||||
* @param compare The function for comparing node keys.
|
||||
* @return @c NULL on error, a new hash on success.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Creation_Group
|
||||
*/
|
||||
EAPI Ecore_Hash *
|
||||
ecore_hash_new(Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare)
|
||||
{
|
||||
Ecore_Hash *new_hash = (Ecore_Hash *)malloc(sizeof(Ecore_Hash));
|
||||
if (!new_hash)
|
||||
return NULL;
|
||||
|
||||
if (!ecore_hash_init(new_hash, hash_func, compare))
|
||||
{
|
||||
FREE(new_hash);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new_hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the given hash.
|
||||
* @param hash The given hash.
|
||||
* @param hash_func The function used for hashing node keys.
|
||||
* @param compare The function used for comparing node keys.
|
||||
* @return @c TRUE on success, @c FALSE on an error.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Creation_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_init(Ecore_Hash *hash,
|
||||
Ecore_Hash_Cb hash_func,
|
||||
Ecore_Compare_Cb compare)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
|
||||
memset(hash, 0, sizeof(Ecore_Hash));
|
||||
|
||||
hash->hash_func = hash_func;
|
||||
hash->compare = compare;
|
||||
|
||||
hash->buckets = (Ecore_Hash_Node **)calloc(ecore_prime_table[0],
|
||||
sizeof(Ecore_Hash_Node *));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Data_Hash_ADT_Destruction_Group Hash Destruction Functions
|
||||
*
|
||||
* Functions that destroy hash tables and their contents.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the function to destroy the keys of the given hash.
|
||||
* @param hash The given hash.
|
||||
* @param function The function used to free the node keys. NULL is a
|
||||
* valid value and means that no function will be called.
|
||||
* @return @c TRUE on success, @c FALSE on error.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Destruction_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_free_key_cb_set(Ecore_Hash *hash, Ecore_Free_Cb function)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
|
||||
hash->free_key = function;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the function to destroy the values in the given hash.
|
||||
* @param hash The given hash.
|
||||
* @param function The function that will free the node values. NULL is a
|
||||
* valid value and means that no function will be called.
|
||||
* @return @c TRUE on success, @c FALSE on error
|
||||
* @ingroup Ecore_Data_Hash_ADT_Destruction_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_free_value_cb_set(Ecore_Hash *hash, Ecore_Free_Cb function)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
|
||||
hash->free_value = function;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Data_Hash_ADT_Data_Group Hash Data Functions
|
||||
*
|
||||
* Functions that set, access and delete values from the hash tables.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets a key-value pair in the given hash table.
|
||||
* @param hash The given hash table.
|
||||
* @param key The key.
|
||||
* @param value The value.
|
||||
* @return @c TRUE if successful, @c FALSE if not.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_set(Ecore_Hash *hash, void *key, void *value)
|
||||
{
|
||||
int ret = FALSE;
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
|
||||
node = _ecore_hash_node_get(hash, key);
|
||||
if (node)
|
||||
{
|
||||
if (hash->free_key)
|
||||
hash->free_key(key);
|
||||
|
||||
if (node->value && hash->free_value)
|
||||
hash->free_value(node->value);
|
||||
|
||||
node->value = value;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = _ecore_hash_node_new(key, value);
|
||||
if (node)
|
||||
ret = _ecore_hash_node_add(hash, node);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all key-value pairs from set in the given hash table.
|
||||
* @param hash The given hash table.
|
||||
* @param set The hash table to import.
|
||||
* @return @c TRUE if successful, @c FALSE if not.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_hash_set(Ecore_Hash *hash, Ecore_Hash *set)
|
||||
{
|
||||
unsigned int i;
|
||||
Ecore_Hash_Node *node, *old;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("set", set, FALSE);
|
||||
|
||||
for (i = 0; i < ecore_prime_table[set->size]; i++)
|
||||
{
|
||||
/* Hash into a new list to avoid loops of rehashing the same nodes */
|
||||
while ((old = set->buckets[i]))
|
||||
{
|
||||
set->buckets[i] = old->next;
|
||||
old->next = NULL;
|
||||
node = _ecore_hash_node_get(hash, old->key);
|
||||
if (node)
|
||||
{
|
||||
/* This key already exists. Delete the old and add the new
|
||||
* value */
|
||||
if (hash->free_key)
|
||||
hash->free_key(node->key);
|
||||
|
||||
if (hash->free_value)
|
||||
hash->free_value(node->value);
|
||||
|
||||
node->key = old->key;
|
||||
node->value = old->value;
|
||||
free(old);
|
||||
}
|
||||
else
|
||||
_ecore_hash_node_add(hash, old);
|
||||
}
|
||||
}
|
||||
FREE(set->buckets);
|
||||
ecore_hash_init(set, set->hash_func, set->compare);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees the hash table and the data contained inside it.
|
||||
* @param hash: The hash table to destroy.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Destruction_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_hash_destroy(Ecore_Hash *hash)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
CHECK_PARAM_POINTER("hash", hash);
|
||||
|
||||
if (hash->buckets)
|
||||
{
|
||||
while (i < ecore_prime_table[hash->size])
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
Ecore_Hash_Node *bucket;
|
||||
|
||||
/*
|
||||
* Remove the bucket list to avoid possible recursion
|
||||
* on the free callbacks.
|
||||
*/
|
||||
bucket = hash->buckets[i];
|
||||
hash->buckets[i] = NULL;
|
||||
_ecore_hash_bucket_destroy(bucket,
|
||||
hash->free_key,
|
||||
hash->free_value);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
FREE(hash->buckets);
|
||||
}
|
||||
|
||||
FREE(hash);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Data_Hash_ADT_Traverse_Group Hash Traverse Functions
|
||||
*
|
||||
* Functions that iterate through hash tables.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Counts the number of nodes in a hash table.
|
||||
* @param hash The hash table to count current nodes.
|
||||
* @return The number of nodes in the hash.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Destruction_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_count(Ecore_Hash *hash)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, 0);
|
||||
|
||||
return hash->nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the @p for_each_func function on each entry in the given hash.
|
||||
* @param hash The given hash.
|
||||
* @param for_each_func The function that each entry is passed to.
|
||||
* @param user_data a pointer passed to calls of for_each_func
|
||||
* @return TRUE on success, FALSE otherwise.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Traverse_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_hash_for_each_node(Ecore_Hash *hash,
|
||||
Ecore_For_Each for_each_func,
|
||||
void *user_data)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE);
|
||||
|
||||
while (i < ecore_prime_table[hash->size])
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
{
|
||||
for_each_func(node, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an ecore_list of all keys in the given hash.
|
||||
* @param hash The given hash.
|
||||
* @return new ecore_list on success, NULL otherwise
|
||||
* @ingroup Ecore_Data_Hash_ADT_Traverse_Group
|
||||
*/
|
||||
EAPI Ecore_List *
|
||||
ecore_hash_keys(Ecore_Hash *hash)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
Ecore_List *keys;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
|
||||
keys = ecore_list_new();
|
||||
while (i < ecore_prime_table[hash->size])
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
{
|
||||
ecore_list_append(keys, node->key);
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
ecore_list_first_goto(keys);
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the distribution of the given hash table for graphing.
|
||||
* @param hash The given hash table.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_hash_dump_graph(Ecore_Hash *hash)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ecore_prime_table[hash->size]; i++)
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
unsigned int n = 0;
|
||||
Ecore_Hash_Node *node;
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
n++;
|
||||
printf("%u\t%u", i, n);
|
||||
}
|
||||
else
|
||||
printf("%u\t0", i);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the distribution of the given hash table for graphing.
|
||||
* @param hash The given hash table.
|
||||
*/
|
||||
EAPI void
|
||||
ecore_hash_dump_stats(Ecore_Hash *hash)
|
||||
{
|
||||
unsigned int i;
|
||||
double variance, sum_n_2 = 0, sum_n = 0;
|
||||
|
||||
if (!hash->size) return;
|
||||
for (i = 0; i < ecore_prime_table[hash->size]; i++)
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
int n = 0;
|
||||
Ecore_Hash_Node *node;
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
n++;
|
||||
sum_n_2 += ((double)n * (double)n);
|
||||
sum_n += (double)n;
|
||||
}
|
||||
}
|
||||
if (i)
|
||||
{
|
||||
variance = (sum_n_2 - ((sum_n * sum_n) / (double)i)) / (double)i;
|
||||
printf("Average length: %f\n\tvariance^2: %f", (sum_n / (double)i),
|
||||
variance);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_ecore_hash_bucket_destroy(Ecore_Hash_Node *list,
|
||||
Ecore_Free_Cb keyd,
|
||||
Ecore_Free_Cb valued)
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
|
||||
|
||||
for (node = list; node; node = list)
|
||||
{
|
||||
list = list->next;
|
||||
_ecore_hash_node_destroy(node, keyd, valued);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Add the node to the hash table
|
||||
* @param hash: the hash table to add the key
|
||||
* @param node: the node to add to the hash table
|
||||
* @return Returns FALSE on error, TRUE on success
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_node_add(Ecore_Hash *hash, Ecore_Hash_Node *node)
|
||||
{
|
||||
size_t hash_val;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
|
||||
|
||||
/* Check to see if the hash needs to be resized */
|
||||
if (ECORE_HASH_INCREASE(hash))
|
||||
_ecore_hash_increase(hash);
|
||||
|
||||
/* Compute the position in the table */
|
||||
if (!hash->hash_func)
|
||||
hash_val = (size_t)node->key % ecore_prime_table[hash->size];
|
||||
else
|
||||
hash_val = ECORE_COMPUTE_HASH(hash, node->key);
|
||||
|
||||
/* Prepend the node to the list at the index position */
|
||||
node->next = hash->buckets[hash_val];
|
||||
hash->buckets[hash_val] = node;
|
||||
hash->nodes++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value associated with the given key from the given hash
|
||||
* table.
|
||||
* @param hash The given hash table.
|
||||
* @param key The key to search for.
|
||||
* @return The value corresponding to key on success, @c NULL otherwise.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_hash_get(Ecore_Hash *hash, const void *key)
|
||||
{
|
||||
void *data;
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
|
||||
node = _ecore_hash_node_get(hash, key);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
data = node->value;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the value associated with the given key in the given hash
|
||||
* table.
|
||||
* @param hash The given hash table.
|
||||
* @param key The key to search for.
|
||||
* @return The value corresponding to the key on success. @c NULL is
|
||||
* returned if there is an error.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_hash_remove(Ecore_Hash *hash, const void *key)
|
||||
{
|
||||
Ecore_Hash_Node *node = NULL;
|
||||
Ecore_Hash_Node *list;
|
||||
size_t hash_val;
|
||||
void *ret = NULL;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
|
||||
/* Compute the position in the table */
|
||||
if (!hash->hash_func)
|
||||
hash_val = (size_t)key % ecore_prime_table[hash->size];
|
||||
else
|
||||
hash_val = ECORE_COMPUTE_HASH(hash, key);
|
||||
|
||||
/*
|
||||
* If their is a list that could possibly hold the key/value pair
|
||||
* traverse it and remove the hash node.
|
||||
*/
|
||||
if (hash->buckets[hash_val])
|
||||
{
|
||||
list = hash->buckets[hash_val];
|
||||
|
||||
/*
|
||||
* Traverse the list to find the specified key
|
||||
*/
|
||||
node = list;
|
||||
if (hash->compare)
|
||||
while ((node) && (hash->compare(node->key, key) != 0))
|
||||
{
|
||||
list = node;
|
||||
node = node->next;
|
||||
}
|
||||
else
|
||||
while ((node) && (node->key != key))
|
||||
{
|
||||
list = node;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the node with the matching key and free it's memory
|
||||
*/
|
||||
if (node)
|
||||
{
|
||||
if (list == node)
|
||||
hash->buckets[hash_val] = node->next;
|
||||
else
|
||||
list->next = node->next;
|
||||
|
||||
ret = node->value;
|
||||
node->value = NULL;
|
||||
_ecore_hash_node_destroy(node, hash->free_key, NULL);
|
||||
hash->nodes--;
|
||||
}
|
||||
}
|
||||
|
||||
if (ECORE_HASH_REDUCE(hash))
|
||||
_ecore_hash_decrease(hash);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the first value that matches
|
||||
* table.
|
||||
* @param hash The given hash table.
|
||||
* @param key The key to search for.
|
||||
* @return The value corresponding to key on success, @c NULL otherwise.
|
||||
* @ingroup Ecore_Data_Hash_ADT_Data_Group
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_hash_find(Ecore_Hash *hash, Ecore_Compare_Cb compare, const void *value)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
CHECK_PARAM_POINTER_RETURN("compare", compare, NULL);
|
||||
CHECK_PARAM_POINTER_RETURN("value", value, NULL);
|
||||
|
||||
while (i < ecore_prime_table[hash->size])
|
||||
{
|
||||
if (hash->buckets[i])
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
for (node = hash->buckets[i]; node; node = node->next)
|
||||
{
|
||||
if (!compare(node->value, value))
|
||||
return node->value;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Retrieve the node associated with key
|
||||
* @param hash: the hash table to search for the key
|
||||
* @param key: the key to search for in the hash table
|
||||
* @return Returns NULL on error, node corresponding to key on success
|
||||
*/
|
||||
static Ecore_Hash_Node *
|
||||
_ecore_hash_node_get(Ecore_Hash *hash, const void *key)
|
||||
{
|
||||
size_t hash_val;
|
||||
Ecore_Hash_Node *node = NULL;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
|
||||
|
||||
if (!hash->buckets)
|
||||
return NULL;
|
||||
|
||||
/* Compute the position in the table */
|
||||
if (!hash->hash_func)
|
||||
hash_val = (size_t)key % ecore_prime_table[hash->size];
|
||||
else
|
||||
hash_val = ECORE_COMPUTE_HASH(hash, key);
|
||||
|
||||
/* Grab the bucket at the specified position */
|
||||
if (hash->buckets[hash_val])
|
||||
{
|
||||
node = _ecore_hash_bucket_get(hash, hash->buckets[hash_val], key);
|
||||
/*
|
||||
* Move matched node to the front of the list as it's likely
|
||||
* to be searched for again soon.
|
||||
*/
|
||||
if (node && node != hash->buckets[hash_val])
|
||||
{
|
||||
node->next = hash->buckets[hash_val];
|
||||
hash->buckets[hash_val] = node;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Search the hash bucket for a specified key
|
||||
* @param hash: the hash table to retrieve the comparison function
|
||||
* @param bucket: the list to search for the key
|
||||
* @param key: the key to search for in the list
|
||||
* @return Returns NULL on error or not found, the found node on success
|
||||
*/
|
||||
static inline Ecore_Hash_Node *
|
||||
_ecore_hash_bucket_get(Ecore_Hash *hash,
|
||||
Ecore_Hash_Node *bucket,
|
||||
const void *key)
|
||||
{
|
||||
Ecore_Hash_Node *prev = NULL;
|
||||
Ecore_Hash_Node *node = NULL;
|
||||
|
||||
/*
|
||||
* Traverse the list to find the desired node, if the node is in the
|
||||
* list, then return the node.
|
||||
*/
|
||||
if (hash->compare)
|
||||
for (node = bucket; node; node = node->next)
|
||||
{
|
||||
if (hash->compare(node->key, key) == 0)
|
||||
break;
|
||||
|
||||
prev = node;
|
||||
}
|
||||
else
|
||||
for (node = bucket; node; node = node->next)
|
||||
{
|
||||
if (node->key == key)
|
||||
break;
|
||||
|
||||
prev = node;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove node from the list to replace it at the beginning.
|
||||
*/
|
||||
if (node && prev)
|
||||
{
|
||||
prev->next = node->next;
|
||||
node->next = NULL;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Increase the size of the hash table by approx. 2 * current size
|
||||
* @param hash: the hash table to increase the size of
|
||||
* @return Returns TRUE on success, FALSE on error
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_increase(Ecore_Hash *hash)
|
||||
{
|
||||
void *old;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
|
||||
/* Max size reached so return FALSE */
|
||||
if ((ecore_prime_table[hash->size] == PRIME_MAX) ||
|
||||
(hash->size == PRIME_TABLE_MAX))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Increase the size of the hash and save a pointer to the old data
|
||||
*/
|
||||
hash->size++;
|
||||
old = hash->buckets;
|
||||
|
||||
/*
|
||||
* Allocate a new bucket area, of the new larger size
|
||||
*/
|
||||
hash->buckets =
|
||||
calloc(ecore_prime_table[hash->size], sizeof(Ecore_Hash_Node *));
|
||||
|
||||
/*
|
||||
* Make sure the allocation succeeded, if not replace the old data and
|
||||
* return a failure.
|
||||
*/
|
||||
if (!hash->buckets)
|
||||
{
|
||||
hash->buckets = old;
|
||||
hash->size--;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hash->nodes = 0;
|
||||
|
||||
/*
|
||||
* Now move all of the old data into the new bucket area
|
||||
*/
|
||||
if (_ecore_hash_rehash(hash, old, hash->size - 1))
|
||||
{
|
||||
FREE(old);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the old buckets regardless of success.
|
||||
*/
|
||||
FREE(old);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Decrease the size of the hash table by < 1/2 * current size
|
||||
* @param hash: the hash table to decrease the size of
|
||||
* @return Returns TRUE on success, FALSE on error
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_decrease(Ecore_Hash *hash)
|
||||
{
|
||||
Ecore_Hash_Node **old;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
|
||||
if (ecore_prime_table[hash->size] == PRIME_MIN)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Decrease the hash size and store a pointer to the old data
|
||||
*/
|
||||
hash->size--;
|
||||
old = hash->buckets;
|
||||
|
||||
/*
|
||||
* Allocate a new area to store the data
|
||||
*/
|
||||
hash->buckets = (Ecore_Hash_Node **)calloc(ecore_prime_table[hash->size],
|
||||
sizeof(Ecore_Hash_Node *));
|
||||
|
||||
/*
|
||||
* Make sure allocation succeeded otherwise rreturn to the previous
|
||||
* state
|
||||
*/
|
||||
if (!hash->buckets)
|
||||
{
|
||||
hash->buckets = old;
|
||||
hash->size++;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hash->nodes = 0;
|
||||
|
||||
if (_ecore_hash_rehash(hash, old, hash->size + 1))
|
||||
{
|
||||
FREE(old);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Rehash the nodes of a table into the hash table
|
||||
* @param hash: the hash to place the nodes of the table
|
||||
* @param table: the table to remove the nodes from and place in hash
|
||||
* @return Returns TRUE on success, FALSE on error
|
||||
*/
|
||||
static inline int
|
||||
_ecore_hash_rehash(Ecore_Hash *hash, Ecore_Hash_Node **old_table, int old_size)
|
||||
{
|
||||
unsigned int i;
|
||||
Ecore_Hash_Node *old;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
|
||||
CHECK_PARAM_POINTER_RETURN("old_table", old_table, FALSE);
|
||||
|
||||
for (i = 0; i < ecore_prime_table[old_size]; i++)
|
||||
{
|
||||
/* Hash into a new list to avoid loops of rehashing the same nodes */
|
||||
while ((old = old_table[i]))
|
||||
{
|
||||
old_table[i] = old->next;
|
||||
old->next = NULL;
|
||||
_ecore_hash_node_add(hash, old);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Create a new hash node for key and value storage
|
||||
* @param key: the key for this node
|
||||
* @param value: the value that the key references
|
||||
* @return Returns NULL on error, a new hash node on success
|
||||
*/
|
||||
static Ecore_Hash_Node *
|
||||
_ecore_hash_node_new(void *key, void *value)
|
||||
{
|
||||
Ecore_Hash_Node *node;
|
||||
|
||||
node = (Ecore_Hash_Node *)malloc(sizeof(Ecore_Hash_Node));
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
if (!_ecore_hash_node_init(node, key, value))
|
||||
{
|
||||
FREE(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Initialize a hash node to some sane default values
|
||||
* @param node: the node to set the values
|
||||
* @param key: the key to reference this node
|
||||
* @param value: the value that key refers to
|
||||
* @return Returns TRUE on success, FALSE on error
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_node_init(Ecore_Hash_Node *node, void *key, void *value)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
|
||||
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Destroy a node and call the specified callbacks to free data
|
||||
* @param node: the node to be destroyed
|
||||
* @param keyd: the function to free the key
|
||||
* @param valued: the function to free the value
|
||||
* @return Returns TRUE on success, FALSE on error
|
||||
*/
|
||||
static int
|
||||
_ecore_hash_node_destroy(Ecore_Hash_Node *node,
|
||||
Ecore_Free_Cb keyd,
|
||||
Ecore_Free_Cb valued)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
|
||||
|
||||
if (keyd)
|
||||
keyd(node->key);
|
||||
|
||||
if (valued)
|
||||
valued(node->value);
|
||||
|
||||
FREE(node);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
ecore_str_compare(const void *key1, const void *key2)
|
||||
{
|
||||
const char *k1, *k2;
|
||||
|
||||
if (!key1 || !key2)
|
||||
return ecore_direct_compare(key1, key2);
|
||||
else if (key1 == key2)
|
||||
return 0;
|
||||
|
||||
k1 = key1;
|
||||
k2 = key2;
|
||||
|
||||
return strcmp(k1, k2);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
ecore_str_hash(const void *key)
|
||||
{
|
||||
int i;
|
||||
unsigned int mask;
|
||||
unsigned int value = 0;
|
||||
const char *k = key;
|
||||
|
||||
if (!k)
|
||||
return 0;
|
||||
|
||||
mask = (sizeof(unsigned int) * 8) - 1;
|
||||
|
||||
for (i = 0; k[i] != '\0'; i++)
|
||||
{
|
||||
value ^= ((unsigned int)k[i] << ((i * 5) & mask));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Ecore_Data.h"
|
||||
|
||||
static void ecore_string_free_cb(void *data);
|
||||
|
||||
static Ecore_Hash *ecore_strings = NULL;
|
||||
static int ecore_string_init_count = 0;
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_String_Group String Instance Functions
|
||||
*
|
||||
* These functions allow you to store one copy of a string, and use it
|
||||
* throughout your program.
|
||||
*
|
||||
* This is a method to reduce the number of duplicated strings kept in
|
||||
* memory. It's pretty common for the same strings to be dynamically
|
||||
* allocated repeatedly between applications and libraries, especially in
|
||||
* circumstances where you could have multiple copies of a structure that
|
||||
* allocates the string. So rather than duplicating and freeing these
|
||||
* strings, you request a read-only pointer to an existing string and
|
||||
* only incur the overhead of a hash lookup.
|
||||
*
|
||||
* It sounds like micro-optimizing, but profiling has shown this can have
|
||||
* a significant impact as you scale the number of copies up. It improves
|
||||
* string creation/destruction speed, reduces memory use and decreases
|
||||
* memory fragmentation, so a win all-around.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialize the ecore string internal structure.
|
||||
* @return Zero on failure, non-zero on successful initialization.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_string_init(void)
|
||||
{
|
||||
/*
|
||||
* No strings have been loaded at this point, so create the hash
|
||||
* table for storing string info for later.
|
||||
*/
|
||||
if (!ecore_string_init_count)
|
||||
{
|
||||
ecore_strings = ecore_hash_new(ecore_str_hash, ecore_str_compare);
|
||||
if (!ecore_strings)
|
||||
return 0;
|
||||
|
||||
ecore_hash_free_value_cb_set(ecore_strings, ecore_string_free_cb);
|
||||
}
|
||||
|
||||
ecore_string_init_count++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an instance of a string for use in an ecore program.
|
||||
* @param string The string to retrieve an instance of.
|
||||
* @return A pointer to an instance of the string on success.
|
||||
* @c NULL on failure.
|
||||
* @ingroup Ecore_String_Group
|
||||
*/
|
||||
EAPI const char *
|
||||
ecore_string_instance(const char *string)
|
||||
{
|
||||
Ecore_String *str;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("string", string, NULL);
|
||||
|
||||
/*
|
||||
* Check for a previous instance of the string, if not found, create
|
||||
* it.
|
||||
*/
|
||||
str = ecore_hash_get(ecore_strings, string);
|
||||
if (!str)
|
||||
{
|
||||
int length;
|
||||
|
||||
/*
|
||||
* Allocate and initialize a new string reference.
|
||||
*/
|
||||
length = strlen(string) + 1;
|
||||
|
||||
str =
|
||||
(Ecore_String *)malloc(sizeof(Ecore_String) + length * sizeof(char));
|
||||
if (!str) return NULL;
|
||||
|
||||
str->string = (char *)(str + 1);
|
||||
str->references = 0;
|
||||
|
||||
memcpy(str->string, string, length);
|
||||
|
||||
ecore_hash_set(ecore_strings, str->string, str);
|
||||
}
|
||||
|
||||
str->references++;
|
||||
|
||||
return str->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes that the given string has lost an instance.
|
||||
*
|
||||
* It will free the string if no other instances are left.
|
||||
*
|
||||
* @param string The given string.
|
||||
* @ingroup Ecore_String_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_string_release(const char *string)
|
||||
{
|
||||
Ecore_String *str;
|
||||
|
||||
CHECK_PARAM_POINTER("string", string);
|
||||
|
||||
str = ecore_hash_get(ecore_strings, (char *)string);
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
str->references--;
|
||||
if (str->references < 1)
|
||||
{
|
||||
ecore_hash_remove(ecore_strings, (char *)string);
|
||||
FREE(str);
|
||||
}
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_string_hash_dump_graph(void)
|
||||
{
|
||||
ecore_hash_dump_graph(ecore_strings);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_string_hash_dump_stats(void)
|
||||
{
|
||||
ecore_hash_dump_stats(ecore_strings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the ecore string internal structures
|
||||
* @return 0 when the module is completely shut down, 1 or
|
||||
* greater otherwise.
|
||||
*/
|
||||
EAPI int
|
||||
ecore_string_shutdown(void)
|
||||
{
|
||||
--ecore_string_init_count;
|
||||
if (!ecore_string_init_count)
|
||||
{
|
||||
ecore_hash_destroy(ecore_strings);
|
||||
ecore_strings = NULL;
|
||||
}
|
||||
return ecore_string_init_count;
|
||||
}
|
||||
|
||||
static void
|
||||
ecore_string_free_cb(void *data)
|
||||
{
|
||||
Ecore_String *str;
|
||||
|
||||
str = data;
|
||||
FREE(str);
|
||||
}
|
|
@ -36,7 +36,6 @@ struct _Eina_Benchmark_Case
|
|||
};
|
||||
|
||||
static const Eina_Benchmark_Case etc[] = {
|
||||
{ "Hash", eina_bench_hash, EINA_TRUE },
|
||||
{ "Hash_Short_Key", eina_bench_crc_hash_short, EINA_TRUE },
|
||||
{ "Hash_Medium_Key", eina_bench_crc_hash_medium, EINA_TRUE },
|
||||
{ "Hash_Large_key", eina_bench_crc_hash_large, EINA_TRUE },
|
||||
|
@ -129,8 +128,6 @@ main(int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
|
||||
eina_bench_e17();
|
||||
|
||||
eina_shutdown();
|
||||
|
||||
_mempool_shutdown();
|
||||
|
|
|
@ -36,7 +36,4 @@ void eina_bench_rectangle_pool(Eina_Benchmark *bench);
|
|||
void eina_bench_quadtree(Eina_Benchmark *bench);
|
||||
void eina_bench_promise(Eina_Benchmark *bench);
|
||||
|
||||
/* Specific benchmark. */
|
||||
void eina_bench_e17(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,551 +0,0 @@
|
|||
/* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef EINA_BENCH_HAVE_GLIB
|
||||
# include <glib.h>
|
||||
#endif
|
||||
|
||||
#include "Evas_Data.h"
|
||||
#include "Ecore_Data.h"
|
||||
|
||||
#include "eina_hash.h"
|
||||
#include "eina_array.h"
|
||||
#include "eina_bench.h"
|
||||
#include "eina_rbtree.h"
|
||||
#include "eina_convert.h"
|
||||
|
||||
#ifdef CITYHASH_BENCH
|
||||
// Hash function for a byte array.
|
||||
uint64_t CityHash64(const char *buf, size_t len);
|
||||
|
||||
static int
|
||||
city_hash(const char *buf, int len)
|
||||
{
|
||||
return (int)CityHash64(buf, len);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_eina_string_key_length(const char *key)
|
||||
{
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
return (int)strlen(key) + 1;
|
||||
}
|
||||
|
||||
static int
|
||||
_eina_string_key_cmp(const char *key1, EINA_UNUSED int key1_length,
|
||||
const char *key2, EINA_UNUSED int key2_length)
|
||||
{
|
||||
return strcmp(key1, key2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _Eina_Bench_Rbtree Eina_Bench_Rbtree;
|
||||
struct _Eina_Bench_Rbtree
|
||||
{
|
||||
Eina_Rbtree node;
|
||||
char key[10];
|
||||
int value;
|
||||
};
|
||||
|
||||
static Eina_Rbtree_Direction
|
||||
_eina_bench_rbtree_cmp(const Eina_Bench_Rbtree *left,
|
||||
const Eina_Bench_Rbtree *right,
|
||||
EINA_UNUSED void *data)
|
||||
{
|
||||
if (!left)
|
||||
return EINA_RBTREE_RIGHT;
|
||||
|
||||
if (!right)
|
||||
return EINA_RBTREE_LEFT;
|
||||
|
||||
return strcmp(left->key,
|
||||
right->key) < 0 ? EINA_RBTREE_LEFT : EINA_RBTREE_RIGHT;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_eina_bench_rbtree_key(const Eina_Bench_Rbtree *node,
|
||||
const char *key,
|
||||
int length,
|
||||
EINA_UNUSED void *data)
|
||||
{
|
||||
return strncmp(node->key, key, length);
|
||||
}
|
||||
|
||||
static void
|
||||
_eina_bench_rbtree_free(Eina_Rbtree *node, EINA_UNUSED void *data)
|
||||
{
|
||||
free(node);
|
||||
}
|
||||
|
||||
static void
|
||||
eina_bench_lookup_rbtree(int request)
|
||||
{
|
||||
Eina_Rbtree *root = NULL;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < request; ++i)
|
||||
{
|
||||
Eina_Bench_Rbtree *tmp;
|
||||
|
||||
tmp = malloc(sizeof (Eina_Bench_Rbtree));
|
||||
if (!tmp)
|
||||
continue;
|
||||
|
||||
tmp->value = i;
|
||||
eina_convert_itoa(i, tmp->key);
|
||||
|
||||
root = eina_rbtree_inline_insert(root,
|
||||
&tmp->node,
|
||||
EINA_RBTREE_CMP_NODE_CB(
|
||||
_eina_bench_rbtree_cmp),
|
||||
NULL);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (j = 0; j < 200; ++j)
|
||||
for (i = 0; i < request; ++i)
|
||||
{
|
||||
Eina_Rbtree *tmp;
|
||||
char tmp_key[10];
|
||||
|
||||
eina_convert_itoa(rand() % request, tmp_key);
|
||||
|
||||
tmp = eina_rbtree_inline_lookup(root,
|
||||
tmp_key,
|
||||
10,
|
||||
EINA_RBTREE_CMP_KEY_CB(
|
||||
_eina_bench_rbtree_key),
|
||||
NULL);
|
||||
/* Suppress warnings as we really don't want to do anything. */
|
||||
(void) tmp;
|
||||
}
|
||||
|
||||
eina_rbtree_delete(root, EINA_RBTREE_FREE_CB(_eina_bench_rbtree_free), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
eina_bench_lookup_murmur(int request)
|
||||
{
|
||||
Eina_Hash *hash = NULL;
|
||||
int *tmp_val;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
hash = eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length),
|
||||
EINA_KEY_CMP(_eina_string_key_cmp),
|
||||
EINA_KEY_HASH(eina_hash_murmur3),
|
||||
free,
|
||||
8);
|
||||
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
tmp_val = malloc(sizeof (int));
|
||||
|
||||
if (!tmp_val)
|
||||
continue;
|
||||
|
||||
eina_convert_itoa(i, tmp_key);
|
||||
*tmp_val = i;
|
||||
|
||||
eina_hash_add(hash, tmp_key, tmp_val);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (j = 0; j < 200; ++j)
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
eina_convert_itoa(rand() % request, tmp_key);
|
||||
tmp_val = eina_hash_find(hash, tmp_key);
|
||||
}
|
||||
|
||||
eina_hash_free(hash);
|
||||
}
|
||||
|
||||
#ifdef CITYHASH_BENCH
|
||||
static void
|
||||
eina_bench_lookup_cityhash(int request)
|
||||
{
|
||||
Eina_Hash *hash = NULL;
|
||||
int *tmp_val;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
hash = eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length),
|
||||
EINA_KEY_CMP(_eina_string_key_cmp),
|
||||
EINA_KEY_HASH(city_hash),
|
||||
free,
|
||||
8);
|
||||
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
tmp_val = malloc(sizeof (int));
|
||||
|
||||
if (!tmp_val)
|
||||
continue;
|
||||
|
||||
eina_convert_itoa(i, tmp_key);
|
||||
*tmp_val = i;
|
||||
|
||||
eina_hash_add(hash, tmp_key, tmp_val);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (j = 0; j < 200; ++j)
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
eina_convert_itoa(rand() % request, tmp_key);
|
||||
tmp_val = eina_hash_find(hash, tmp_key);
|
||||
}
|
||||
|
||||
eina_hash_free(hash);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
eina_bench_lookup_superfast(int request)
|
||||
{
|
||||
Eina_Hash *hash = NULL;
|
||||
int *tmp_val;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
hash = eina_hash_string_superfast_new(free);
|
||||
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
tmp_val = malloc(sizeof (int));
|
||||
|
||||
if (!tmp_val)
|
||||
continue;
|
||||
|
||||
eina_convert_itoa(i, tmp_key);
|
||||
*tmp_val = i;
|
||||
|
||||
eina_hash_add(hash, tmp_key, tmp_val);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (j = 0; j < 200; ++j)
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
eina_convert_itoa(rand() % request, tmp_key);
|
||||
tmp_val = eina_hash_find(hash, tmp_key);
|
||||
}
|
||||
|
||||
eina_hash_free(hash);
|
||||
}
|
||||
|
||||
static void
|
||||
eina_bench_lookup_djb2(int request)
|
||||
{
|
||||
Eina_Hash *hash = NULL;
|
||||
int *tmp_val;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
hash = eina_hash_string_djb2_new(free);
|
||||
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
tmp_val = malloc(sizeof (int));
|
||||
|
||||
if (!tmp_val)
|
||||
continue;
|
||||
|
||||
eina_convert_itoa(i, tmp_key);
|
||||
*tmp_val = i;
|
||||
|
||||
eina_hash_add(hash, tmp_key, tmp_val);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (j = 0; j < 200; ++j)
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
eina_convert_itoa(rand() % request, tmp_key);
|
||||
|
||||
tmp_val = eina_hash_find(hash, tmp_key);
|
||||
}
|
||||
|
||||
eina_hash_free(hash);
|
||||
}
|
||||
|
||||
typedef struct _Eina_Bench_DJB2 Eina_Bench_DJB2;
|
||||
struct _Eina_Bench_DJB2
|
||||
{
|
||||
char *key;
|
||||
int value;
|
||||
};
|
||||
|
||||
static void
|
||||
eina_bench_lookup_djb2_inline(int request)
|
||||
{
|
||||
Eina_Hash *hash = NULL;
|
||||
Eina_Bench_DJB2 *elm;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
hash = eina_hash_string_djb2_new(free);
|
||||
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
int length;
|
||||
|
||||
elm = malloc(sizeof (Eina_Bench_DJB2) + 10);
|
||||
if (!elm)
|
||||
continue;
|
||||
|
||||
elm->key = (char *)(elm + 1);
|
||||
|
||||
length = eina_convert_itoa(i, elm->key) + 1;
|
||||
elm->value = i;
|
||||
|
||||
eina_hash_direct_add_by_hash(hash, elm->key, length,
|
||||
eina_hash_djb2(elm->key, length), elm);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (j = 0; j < 200; ++j)
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
int length = eina_convert_itoa(rand() % request, tmp_key) + 1;
|
||||
|
||||
elm =
|
||||
eina_hash_find_by_hash(hash, tmp_key, length,
|
||||
eina_hash_djb2(tmp_key, length));
|
||||
}
|
||||
|
||||
eina_hash_free(hash);
|
||||
}
|
||||
|
||||
#ifdef EINA_BENCH_HAVE_GLIB
|
||||
typedef struct _Eina_Bench_Glib Eina_Bench_Glib;
|
||||
struct _Eina_Bench_Glib
|
||||
{
|
||||
char *key;
|
||||
int value;
|
||||
};
|
||||
|
||||
static void
|
||||
eina_bench_lookup_ghash(int request)
|
||||
{
|
||||
Eina_Bench_Glib *elm;
|
||||
GHashTable *hash;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free);
|
||||
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
elm = malloc(sizeof (Eina_Bench_Glib) + 10);
|
||||
if (!elm)
|
||||
continue;
|
||||
|
||||
elm->key = (char *)(elm + 1);
|
||||
|
||||
eina_convert_itoa(i, elm->key);
|
||||
elm->value = i;
|
||||
|
||||
g_hash_table_insert(hash, elm->key, elm);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (j = 0; j < 200; ++j)
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
eina_convert_itoa(rand() % request, tmp_key);
|
||||
|
||||
elm = g_hash_table_lookup(hash, tmp_key);
|
||||
}
|
||||
|
||||
g_hash_table_destroy(hash);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
eina_bench_lookup_evas(int request)
|
||||
{
|
||||
Evas_Hash *hash = NULL;
|
||||
Eina_Array *array = NULL;
|
||||
int *tmp_val;
|
||||
Eina_Array_Iterator it;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
array = eina_array_new(10000);
|
||||
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
tmp_val = malloc(sizeof (int));
|
||||
|
||||
if (!tmp_val)
|
||||
continue;
|
||||
|
||||
eina_convert_itoa(i, tmp_key);
|
||||
*tmp_val = i;
|
||||
|
||||
hash = evas_hash_add(hash, tmp_key, tmp_val);
|
||||
|
||||
eina_array_push(array, tmp_val);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (j = 0; j < 200; ++j)
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
eina_convert_itoa(rand() % request, tmp_key);
|
||||
|
||||
tmp_val = evas_hash_find(hash, tmp_key);
|
||||
}
|
||||
|
||||
evas_hash_free(hash);
|
||||
|
||||
EINA_ARRAY_ITER_NEXT(array, i, tmp_val, it)
|
||||
free(tmp_val);
|
||||
|
||||
eina_array_free(array);
|
||||
}
|
||||
|
||||
typedef struct _Eina_Bench_Ecore Eina_Bench_Ecore;
|
||||
struct _Eina_Bench_Ecore
|
||||
{
|
||||
char *key;
|
||||
int value;
|
||||
};
|
||||
|
||||
static void
|
||||
eina_bench_lookup_ecore(int request)
|
||||
{
|
||||
Ecore_Hash *hash = NULL;
|
||||
Eina_Bench_Ecore *elm;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
hash = ecore_hash_new(ecore_str_hash, ecore_str_compare);
|
||||
|
||||
ecore_hash_free_key_cb_set(hash, NULL);
|
||||
ecore_hash_free_value_cb_set(hash, free);
|
||||
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
elm = malloc(sizeof (Eina_Bench_Ecore) + 10);
|
||||
if (!elm)
|
||||
continue;
|
||||
|
||||
elm->key = (char *)(elm + 1);
|
||||
eina_convert_itoa(i, elm->key);
|
||||
elm->value = i;
|
||||
|
||||
ecore_hash_set(hash, elm->key, elm);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for (j = 0; j < 200; ++j)
|
||||
for (i = 0; i < (unsigned int)request; ++i)
|
||||
{
|
||||
char tmp_key[10];
|
||||
|
||||
eina_convert_itoa(rand() % request, tmp_key);
|
||||
|
||||
elm = ecore_hash_get(hash, tmp_key);
|
||||
}
|
||||
|
||||
ecore_hash_destroy(hash);
|
||||
}
|
||||
|
||||
void eina_bench_hash(Eina_Benchmark *bench)
|
||||
{
|
||||
eina_benchmark_register(bench, "superfast-lookup",
|
||||
EINA_BENCHMARK(
|
||||
eina_bench_lookup_superfast), 10, 10000, 10);
|
||||
eina_benchmark_register(bench, "djb2-lookup",
|
||||
EINA_BENCHMARK(
|
||||
eina_bench_lookup_djb2), 10, 10000, 10);
|
||||
eina_benchmark_register(bench, "djb2-lookup-inline",
|
||||
EINA_BENCHMARK(
|
||||
eina_bench_lookup_djb2_inline), 10, 10000, 10);
|
||||
eina_benchmark_register(bench, "murmur",
|
||||
EINA_BENCHMARK(
|
||||
eina_bench_lookup_murmur), 10, 10000, 10);
|
||||
#ifdef CITYHASH_BENCH
|
||||
eina_benchmark_register(bench, "cityhash",
|
||||
EINA_BENCHMARK(
|
||||
eina_bench_lookup_cityhash), 10, 10000, 10);
|
||||
#endif
|
||||
eina_benchmark_register(bench, "rbtree",
|
||||
EINA_BENCHMARK(
|
||||
eina_bench_lookup_rbtree), 10, 10000, 10);
|
||||
#ifdef EINA_BENCH_HAVE_GLIB
|
||||
eina_benchmark_register(bench, "ghash-lookup",
|
||||
EINA_BENCHMARK(
|
||||
eina_bench_lookup_ghash), 10, 10000, 10);
|
||||
#endif
|
||||
eina_benchmark_register(bench, "evas-lookup",
|
||||
EINA_BENCHMARK(
|
||||
eina_bench_lookup_evas), 10, 10000, 10);
|
||||
eina_benchmark_register(bench, "ecore-lookup",
|
||||
EINA_BENCHMARK(
|
||||
eina_bench_lookup_ecore), 10, 10000, 10);
|
||||
|
||||
}
|
|
@ -139,14 +139,14 @@ eina_bench_ecore_job(int request)
|
|||
unsigned int j;
|
||||
int i;
|
||||
|
||||
ecore_string_init();
|
||||
//ecore_string_init();
|
||||
|
||||
for (i = 0; i < request; ++i)
|
||||
{
|
||||
char build[64] = "string_";
|
||||
|
||||
eina_convert_xtoa(i, build + 7);
|
||||
tmp = ecore_string_instance(build);
|
||||
//tmp = ecore_string_instance(build);
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
@ -157,13 +157,13 @@ eina_bench_ecore_job(int request)
|
|||
char build[64] = "string_";
|
||||
|
||||
eina_convert_xtoa(rand() % request, build + 7);
|
||||
tmp = ecore_string_instance(build);
|
||||
//tmp = ecore_string_instance(build);
|
||||
}
|
||||
|
||||
/* Suppress warnings as we really don't want to do anything. */
|
||||
(void) tmp;
|
||||
|
||||
ecore_string_shutdown();
|
||||
//ecore_string_shutdown();
|
||||
}
|
||||
|
||||
void eina_bench_stringshare(Eina_Benchmark *bench)
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
/* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef EINA_BENCH_HAVE_GLIB
|
||||
# include <glib.h>
|
||||
#endif
|
||||
|
||||
#include "Evas_Data.h"
|
||||
#include "Ecore_Data.h"
|
||||
|
||||
#include "Eina.h"
|
||||
|
||||
#if EINA_ENABLE_BENCH_E17
|
||||
|
||||
typedef struct _Eina_Stringshare_Test Eina_Stringshare_Test;
|
||||
struct _Eina_Stringshare_Test
|
||||
{
|
||||
const char *name;
|
||||
|
||||
int (*init)(void);
|
||||
const char *(*add)(const char *str);
|
||||
void (*del)(const char *str);
|
||||
int (*shutdown)(void);
|
||||
};
|
||||
|
||||
static Eina_Stringshare_Test eina_str = {
|
||||
"eina",
|
||||
eina_init,
|
||||
eina_stringshare_add,
|
||||
eina_stringshare_del,
|
||||
eina_shutdown
|
||||
};
|
||||
|
||||
static Eina_Stringshare_Test evas_str = {
|
||||
"evas",
|
||||
NULL,
|
||||
evas_stringshare_add,
|
||||
evas_stringshare_del,
|
||||
NULL
|
||||
};
|
||||
|
||||
static Eina_Stringshare_Test ecore_str = {
|
||||
"ecore",
|
||||
ecore_string_init,
|
||||
ecore_string_instance,
|
||||
ecore_string_release,
|
||||
ecore_string_shutdown
|
||||
};
|
||||
|
||||
static Eina_Stringshare_Test *tests[] = {
|
||||
&eina_str,
|
||||
&evas_str,
|
||||
&ecore_str,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
eina_bench_e17_stringshare(Eina_Stringshare_Test *str)
|
||||
{
|
||||
Eina_Counter *cnt;
|
||||
char *result;
|
||||
|
||||
cnt = eina_counter_new(str->name);
|
||||
|
||||
eina_counter_start(cnt);
|
||||
|
||||
if (str->init)
|
||||
str->init();
|
||||
|
||||
//#include "strlog"
|
||||
|
||||
if (str->shutdown)
|
||||
str->shutdown();
|
||||
|
||||
eina_counter_stop(cnt, 1);
|
||||
|
||||
result = eina_counter_dump(cnt);
|
||||
fprintf(stderr, "For `%s`:\n%s\n", str->name, result);
|
||||
free(result);
|
||||
|
||||
eina_counter_free(cnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
eina_bench_e17(void)
|
||||
{
|
||||
#if EINA_ENABLE_BENCH_E17
|
||||
int i;
|
||||
|
||||
eina_init();
|
||||
|
||||
for (i = 0; tests[i]; ++i)
|
||||
eina_bench_e17_stringshare(tests[i]);
|
||||
|
||||
eina_shutdown();
|
||||
#endif
|
||||
}
|
|
@ -1,17 +1,13 @@
|
|||
eina_bench_src = files(
|
||||
'eina_bench.c',
|
||||
'eina_bench_sort.c',
|
||||
'eina_bench_hash.c',
|
||||
'eina_bench_crc_hash.c',
|
||||
'eina_bench_stringshare.c',
|
||||
'eina_bench_convert.c',
|
||||
'eina_bench_mempool.c',
|
||||
'eina_bench_stringshare_e17.c',
|
||||
'eina_bench_array.c',
|
||||
'eina_bench_rectangle_pool.c',
|
||||
'ecore_list.c',
|
||||
'ecore_strings.c',
|
||||
'ecore_hash.c',
|
||||
'ecore_sheap.c',
|
||||
'evas_hash.c',
|
||||
'evas_list.c',
|
||||
|
|
Loading…
Reference in New Issue