Merge Ewd code into Ecore.

The new functions (Ecore_Data.h) have not been tested yet, be warned! :)


SVN revision: 9384
This commit is contained in:
xcomputerman 2004-03-18 05:29:54 +00:00 committed by xcomputerman
parent 002beaf9a6
commit 1034f13443
19 changed files with 4541 additions and 67 deletions

View File

@ -6,12 +6,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <Ecore_Data.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Convenience macros */
/* FIXME: [deprecated] Convenience macros */
#define ECORE_MIN(x, y) (((x) > (y)) ? (y) : (x))
#define ECORE_MAX(x, y) (((x) > (y)) ? (x) : (y))

View File

@ -0,0 +1,546 @@
#ifndef _ECORE_DATA_H
#define _ECORE_DATA_H
#define PRIME_TABLE_MAX 21
#define PRIME_MIN 17
#define PRIME_MAX 16777213
extern const unsigned int ecore_prime_table[];
typedef void (*Ecore_For_Each) (void *value);
#define ECORE_FOR_EACH(function) ((Ecore_For_Each)function)
typedef void (*Ecore_Free_Cb) (void *data);
#define ECORE_FREE_CB(func) ((Ecore_Free_Cb)func)
typedef unsigned int (*Ecore_Hash_Cb) (void *key);
#define ECORE_HASH_CB(function) ((Ecore_Hash_Cb)function)
typedef int (*Ecore_Compare_Cb) (void *data1, void *data2);
#define ECORE_COMPARE_CB(function) ((Ecore_Compare_Cb)function)
int ecore_direct_compare(void *key1, void *key2);
int ecore_str_compare(void *key1, void *key2);
unsigned int ecore_direct_hash(void *key);
unsigned int ecore_str_hash(void *key);
#ifdef HAVE_PTHREADS /* pthreads are installed */
#include <pthread.h>
#define ECORE_DECLARE_LOCKS \
int readers; \
pthread_mutex_t readers_mutex; \
pthread_mutex_t writers_mutex; \
pthread_cond_t readers_cond;
#define ECORE_INIT_LOCKS(structure) \
if (structure) { \
structure->readers = 0; \
pthread_mutex_init(&structure->readers_mutex, NULL); \
pthread_mutex_init(&structure->writers_mutex, NULL); \
pthread_cond_init(&structure->readers_cond, NULL); \
}
#define ECORE_DESTROY_LOCKS(structure) \
if (structure) { \
pthread_mutex_destroy(&structure->readers_mutex); \
pthread_mutex_destroy(&structure->writers_mutex); \
pthread_cond_destroy(&structure->readers_cond); \
}
#define ECORE_READ_LOCK(structure) \
if (structure) { \
pthread_mutex_lock(&structure->readers_mutex); \
structure->readers++; \
pthread_mutex_unlock(&structure->readers_mutex); \
}
#define ECORE_READ_UNLOCK(structure) \
if (structure) { \
pthread_mutex_lock(&structure->readers_mutex); \
if (--structure->readers == 0) \
pthread_cond_broadcast(&structure->readers_cond); \
pthread_mutex_unlock(&structure->readers_mutex); \
}
#define ECORE_WRITE_LOCK(structure) \
if (structure) { \
pthread_mutex_lock(&structure->readers_mutex); \
pthread_mutex_lock(&structure->writers_mutex); \
while (structure->readers > 0) \
pthread_cond_wait(&structure->readers_cond, \
&structure->readers_mutex); \
pthread_mutex_unlock(&structure->readers_mutex); \
}
#define ECORE_WRITE_UNLOCK(structure) \
if (structure) \
pthread_mutex_unlock(&structure->writers_mutex); \
#define ECORE_THREAD_CREATE(function, arg) \
if (function) { \
pthread_t thread; \
pthread_create(&thread, NULL, function, arg); \
pthread_detach(thread); \
}
#define ECORE_NO_THREADS(function, arg)
#else /* No pthreads available */
#define ECORE_DECLARE_LOCKS
#define ECORE_INIT_LOCKS(structure)
#define ECORE_READ_LOCK(structure)
#define ECORE_READ_UNLOCK(structure)
#define ECORE_WRITE_LOCK(structure)
#define ECORE_WRITE_UNLOCK(structure)
#define ECORE_THREAD_CREATE(function, args)
#define ECORE_DESTROY_LOCKS(structure)
#define ECORE_NO_THREADS(function, arg) if (function) function(arg);
#endif /* HAVE_PTHREADS */
typedef struct _ecore_list Ecore_List;
#define ECORE_LIST(list) ((Ecore_List *)list)
typedef struct _ecore_list_node Ecore_List_Node;
#define ECORE_LIST_NODE(node) ((Ecore_List_Node *)node)
struct _ecore_list_node {
void *data;
struct _ecore_list_node *next;
ECORE_DECLARE_LOCKS;
};
struct _ecore_list {
Ecore_List_Node *first; /* The first node in the list */
Ecore_List_Node *last; /* The last node in the list */
Ecore_List_Node *current; /* The current node in the list */
Ecore_Free_Cb free_func; /* The callback to free data in nodes */
int nodes; /* The number of nodes in the list */
int index; /* The position from the front of the
list of current node */
ECORE_DECLARE_LOCKS;
};
/* Creating and initializing new list structures */
Ecore_List *ecore_list_new();
int ecore_list_init(Ecore_List *list);
/* Adding items to the list */
inline int ecore_list_append(Ecore_List * list, void *_data);
inline int ecore_list_prepend(Ecore_List * list, void *_data);
inline int ecore_list_insert(Ecore_List * list, void *_data);
/* Removing items from the list */
inline int ecore_list_remove_destroy(Ecore_List *list);
inline void *ecore_list_remove(Ecore_List * list);
inline void *ecore_list_remove_first(Ecore_List * list);
inline void *ecore_list_remove_last(Ecore_List * list);
/* Retrieve the current position in the list */
inline void *ecore_list_current(Ecore_List * list);
int ecore_list_index(Ecore_List * list);
int ecore_list_nodes(Ecore_List * list);
/* Traversing the list */
int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function);
inline void *ecore_list_goto_first(Ecore_List * list);
inline void *ecore_list_goto_last(Ecore_List * list);
inline void *ecore_list_goto_index(Ecore_List * list, int index);
inline void *ecore_list_goto(Ecore_List * list, void *_data);
/* Traversing the list and returning data */
inline void *ecore_list_next(Ecore_List * list);
/* Check to see if there is any data in the list */
int ecore_list_is_empty(Ecore_List * list);
/* Remove every node in the list without freeing the list itself */
int ecore_list_clear(Ecore_List * list);
/* Free the list and it's contents */
void ecore_list_destroy(Ecore_List *list);
/* Creating and initializing list nodes */
Ecore_List_Node *ecore_list_node_new();
int ecore_list_node_init(Ecore_List_Node *newNode);
/* Destroying nodes */
int ecore_list_node_destroy(Ecore_List_Node * _e_node, Ecore_Free_Cb free_func);
int ecore_list_set_free_cb(Ecore_List * list, Ecore_Free_Cb free_func);
typedef Ecore_List Ecore_DList;
#define ECORE_DLIST(dlist) ((Ecore_DList *)dlist)
typedef struct _ecore_dlist_node Ecore_DList_Node;
#define ECORE_DLIST_NODE(dlist) ((Ecore_DList_Node *)dlist)
struct _ecore_dlist_node {
Ecore_List_Node single;
Ecore_DList_Node *previous;
};
/* Creating and initializing new list structures */
Ecore_DList *ecore_dlist_new();
int ecore_dlist_init(Ecore_DList *list);
void ecore_dlist_destroy(Ecore_DList *list);
/* Adding items to the list */
int ecore_dlist_append(Ecore_DList * _e_dlist, void *_data);
int ecore_dlist_prepend(Ecore_DList * _e_dlist, void *_data);
int ecore_dlist_insert(Ecore_DList * _e_dlist, void *_data);
/* Info about list's state */
void *ecore_dlist_current(Ecore_DList *list);
int ecore_dlist_index(Ecore_DList *list);
#define ecore_dlist_nodes(list) ecore_list_nodes(ECORE_LIST(list))
/* Removing items from the list */
void *ecore_dlist_remove(Ecore_DList * _e_dlist);
void *ecore_dlist_remove_first(Ecore_DList * _e_dlist);
void *ecore_dlist_remove_last(Ecore_DList * _e_dlist);
/* Traversing the list */
#define ecore_dlist_for_each(list, function) \
ecore_list_for_each(ECORE_LIST(list), function)
inline void *ecore_dlist_goto_first(Ecore_DList * _e_dlist);
inline void *ecore_dlist_goto_last(Ecore_DList * _e_dlist);
inline void *ecore_dlist_goto_index(Ecore_DList * _e_dlist, int index);
inline void *ecore_dlist_goto(Ecore_DList * _e_dlist, void *_data);
/* Traversing the list and returning data */
inline void *ecore_dlist_next(Ecore_DList * list);
inline void *ecore_dlist_previous(Ecore_DList * list);
/* Check to see if there is any data in the list */
int ecore_dlist_is_empty(Ecore_DList * _e_dlist);
/* Remove every node in the list without free'ing it */
int ecore_dlist_clear(Ecore_DList * _e_dlist);
/* Creating and initializing list nodes */
Ecore_DList_Node *ecore_dlist_node_new();
/* Destroying nodes */
int ecore_dlist_node_destroy(Ecore_DList_Node * node, Ecore_Free_Cb free_func);
int ecore_dlist_set_free_cb(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 {
void *key; /* The key for the data node */
void *value; /* The value associated with this node */
ECORE_DECLARE_LOCKS
};
typedef struct _ecore_hash Ecore_Hash;
#define ECORE_HASH(hash) ((Ecore_Hash *)hash)
struct _ecore_hash {
Ecore_List **buckets;
int size; /* An index into the table of primes to
determine size */
int nodes; /* The number of nodes currently in the hash */
Ecore_Compare_Cb compare; /* The function used to compare node values */
Ecore_Hash_Cb hash_func; /* The function used to compare node values */
Ecore_Free_Cb free_key; /* The callback function to free key */
Ecore_Free_Cb free_value; /* The callback function to determine hash */
ECORE_DECLARE_LOCKS
};
/* Create and initialize a hash */
Ecore_Hash *ecore_hash_new(Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare);
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 */
int ecore_hash_set_free_key(Ecore_Hash *hash, Ecore_Free_Cb function);
int ecore_hash_set_free_value(Ecore_Hash *hash, Ecore_Free_Cb function);
void ecore_hash_destroy(Ecore_Hash *hash);
int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func);
/* Retrieve and store data into the hash */
void *ecore_hash_get(Ecore_Hash *hash, void *key);
int ecore_hash_set(Ecore_Hash *hash, void *key, void *value);
void *ecore_hash_remove(Ecore_Hash *hash, void *key);
void ecore_hash_dump_graph(Ecore_Hash *hash);
inline void ecore_print_warning(char *function, char *sparam);
/* Wrappers around free() that helps debug free() bugs such as freeing NULL
* or accessing a pointer that has already been freed */
#ifndef IF_FREE
#define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL;
#endif
#ifndef FREE
#define FREE(ptr) free(ptr); ptr = NULL;
#endif
/* Debugging printf, basically a wrapper to fprintf that checks the level
* of the message and checks that it is to be printed at the current debugging
* level */
#ifndef DPRINTF
#define DPRINTF(debug, format, args...) \
if (debug >= DEBUG_LEVEL) \
fprintf(stderr, format, args);
#endif
/* convenience macros for checking pointer parameters for non-NULL */
#ifndef CHECK_PARAM_POINTER_RETURN
#define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \
if (!(param)) \
{ \
ecore_print_warning(__FUNCTION__, sparam); \
return ret; \
}
#endif
#ifndef CHECK_PARAM_POINTER
#define CHECK_PARAM_POINTER(sparam, param) \
if (!(param)) \
{ \
ecore_print_warning(__FUNCTION__, sparam); \
return; \
}
#endif
/* Use the larger of a and b */
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
/* Use the smaller of a and b */
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
typedef struct _ecore_path_group Ecore_Path_Group;
struct _ecore_path_group
{
int id;
char *name;
Ecore_List *paths;
};
/*
* Create a new path group
*/
int ecore_path_group_new(char *group_name);
/*
* Destroy a previous path group
*/
void ecore_path_group_del(int group_id);
/*
* Add a directory to be searched for files
*/
void ecore_path_group_add(int group_id, char *path);
/*
* Remove a directory to be searched for files
*/
void ecore_path_group_remove(int group_id, char *path);
/*
* Find the absolute path if it exists in the group of paths
*/
char * ecore_path_group_find(int group_id, char *name);
/*
* Get a list of all the available files in a path set
*/
Ecore_List * ecore_path_group_available(int group_id);
typedef struct _ecore_plugin Ecore_Plugin;
struct _ecore_plugin
{
int group;
char *name;
void *handle;
};
/*
* Load the specified plugin
*/
Ecore_Plugin *ecore_plugin_load(int group_id, char *plugin);
/*
* Unload the specified plugin
*/
void ecore_plugin_unload(Ecore_Plugin * plugin);
/*
* Lookup the specified symbol for the plugin
*/
void *ecore_plugin_call(Ecore_Plugin * plugin, char *symbol_name);
Ecore_List *ecore_plugin_get_available(int group_id);
#define ECORE_SHEAP_MIN 0
#define ECORE_SHEAP_MAX 1
#define HEAP_INCREMENT 4096
#define PARENT(i) (i / 2)
#define LEFT(i) (2 * i)
#define RIGHT(i) (2 * i + 1)
typedef struct _ecore_heap Ecore_Sheap;
#define ECORE_HEAP(heap) ((Ecore_Sheap *)heap)
struct _ecore_heap {
void **data;
int size;
int space;
char order, sorted;
Ecore_Compare_Cb compare;
};
Ecore_Sheap *ecore_sheap_new(Ecore_Compare_Cb compare, int size);
void ecore_sheap_destroy(Ecore_Sheap *heap);
int ecore_sheap_init(Ecore_Sheap *heap, Ecore_Compare_Cb compare, int size);
int ecore_sheap_insert(Ecore_Sheap *heap, void *data);
void *ecore_sheap_extract(Ecore_Sheap *heap);
void *ecore_sheap_extreme(Ecore_Sheap *heap);
int ecore_sheap_change(Ecore_Sheap *heap, void *item, void *newval);
void ecore_sheap_destroy(Ecore_Sheap *heap);
void ecore_sheap_sort(Ecore_Sheap *heap);
inline void *ecore_sheap_item(Ecore_Sheap *heap, int i);
typedef struct _ecore_string Ecore_String;
struct _ecore_string {
char *string;
int references;
};
char *ecore_string_instance(char *string);
void ecore_string_release(char *string);
typedef struct _Ecore_Tree_Node Ecore_Tree_Node;
#define ECORE_TREE_NODE(object) ((Ecore_Tree_Node *)object)
struct _Ecore_Tree_Node {
/* The actual data for each node */
void *key;
void *value;
/* Pointers to surrounding nodes */
Ecore_Tree_Node *parent;
Ecore_Tree_Node *left_child;
Ecore_Tree_Node *right_child;
/* Book keeping information for quicker balancing of the tree */
int max_right;
int max_left;
ECORE_DECLARE_LOCKS;
};
typedef struct _Ecore_Tree Ecore_Tree;
#define ECORE_TREE(object) ((Ecore_Tree *)object)
struct _Ecore_Tree {
/* Nodes of the tree */
Ecore_Tree_Node *tree;
/* Callback for comparing node values, default is direct comparison */
Ecore_Compare_Cb compare_func;
/* Callback for freeing node data, default is NULL */
Ecore_Free_Cb free_func;
ECORE_DECLARE_LOCKS;
};
/* Some basic tree functions */
/* Allocate and initialize a new tree */
Ecore_Tree *ecore_tree_new(Ecore_Compare_Cb compare_func);
/* Initialize a new tree */
int ecore_tree_init(Ecore_Tree * tree, Ecore_Compare_Cb compare_func);
/* Free the tree */
int ecore_tree_destroy(Ecore_Tree * tree);
/* Check to see if the tree has any nodes in it */
int ecore_tree_is_empty(Ecore_Tree * tree);
/* Retrieve the value associated with key */
void *ecore_tree_get(Ecore_Tree * tree, void *key);
Ecore_Tree_Node *ecore_tree_get_node(Ecore_Tree * tree, void *key);
/* Retrieve the value of node with key greater than or equal to key */
void *ecore_tree_get_closest_larger(Ecore_Tree * tree, void *key);
/* Retrieve the value of node with key less than or equal to key */
void *ecore_tree_get_closest_smaller(Ecore_Tree * tree, void *key);
/* Set the value associated with key to value */
int ecore_tree_set(Ecore_Tree * tree, void *key, void *value);
/* Remove the key from the tree */
int ecore_tree_remove(Ecore_Tree * tree, void *key);
/* Add a node to the tree */
int ecore_tree_add_node(Ecore_Tree * tree, Ecore_Tree_Node * node);
/* Remove a node from the tree */
int ecore_tree_remove_node(Ecore_Tree * tree, Ecore_Tree_Node * node);
/* For each node in the tree perform the for_each_func function */
/* For this one pass in the node */
int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func);
/* And here pass in the node's value */
int ecore_tree_for_each_node_value(Ecore_Tree * tree,
Ecore_For_Each for_each_func);
/* Some basic node functions */
/* Initialize a node */
int ecore_tree_node_init(Ecore_Tree_Node * new_node);
/* Allocate and initialize a new node */
Ecore_Tree_Node *ecore_tree_node_new();
/* Free the desired node */
int ecore_tree_node_destroy(Ecore_Tree_Node * node, Ecore_Free_Cb free_data);
/* Set the node's key to key */
int ecore_tree_node_key_set(Ecore_Tree_Node * node, void *key);
/* Retrieve the key in node */
void *ecore_tree_node_key_get(Ecore_Tree_Node * node);
/* Set the node's value to value */
int ecore_tree_node_value_set(Ecore_Tree_Node * node, void *value);
/* Retrieve the value in node */
void *ecore_tree_node_value_get(Ecore_Tree_Node * node);
/* Add a function to free the data stored in nodes */
int ecore_tree_set_free_cb(Ecore_Tree * tree, Ecore_Free_Cb free_func);
#endif /* _ECORE_DATA_H */

View File

@ -4,22 +4,30 @@ INCLUDES =
lib_LTLIBRARIES = libecore.la
include_HEADERS = \
Ecore.h
Ecore.h \
Ecore_Data.h
libecore_la_SOURCES = \
ecore.c \
ecore_app.c \
ecore_events.c \
ecore_exe.c \
ecore_hash.c \
ecore_idle_enterer.c \
ecore_idle_exiter.c \
ecore_idler.c \
ecore_list.c \
ecore_main.c \
ecore_path.c \
ecore_plugin.c \
ecore_sheap.c \
ecore_signal.c \
ecore_strings.c \
ecore_time.c \
ecore_timer.c \
ecore_tree.c \
ecore_value.c \
ecore_private.h
libecore_la_LIBADD =
libecore_la_LIBADD = -lm @dlopen_libs@
libecore_la_LDFLAGS = -version-info 1:0:0

View File

@ -353,20 +353,20 @@ _ecore_event_del(Ecore_Event *event)
void
_ecore_event_call(void)
{
Ecore_List *l;
Ecore_Oldlist *l;
for (l = (Ecore_List *)event_filters; l; l = l->next)
for (l = (Ecore_Oldlist *)event_filters; l; l = l->next)
{
Ecore_Event_Filter *ef;
ef = (Ecore_Event_Filter *)l;
if (!ef->delete_me)
{
Ecore_List *ll;
Ecore_Oldlist *ll;
if (ef->func_start)
ef->loop_data = ef->func_start(ef->data);
for (ll = (Ecore_List *)events; ll; ll = ll->next)
for (ll = (Ecore_Oldlist *)events; ll; ll = ll->next)
{
Ecore_Event *e;
@ -381,7 +381,7 @@ _ecore_event_call(void)
}
if (event_filters_delete_me)
{
for (l = (Ecore_List *)event_filters; l;)
for (l = (Ecore_Oldlist *)event_filters; l;)
{
Ecore_Event_Filter *ef;
@ -396,9 +396,9 @@ _ecore_event_call(void)
}
event_filters_delete_me = 0;
}
for (l = (Ecore_List *)events; l; l = l->next)
for (l = (Ecore_Oldlist *)events; l; l = l->next)
{
Ecore_List *ll;
Ecore_Oldlist *ll;
Ecore_Event *e;
e = (Ecore_Event *)l;
@ -409,7 +409,7 @@ _ecore_event_call(void)
handle_count = 0;
ecore_raw_event_type = e->type;
ecore_raw_event_event = e->event;
for (ll = (Ecore_List *)event_handlers; ll; ll = ll->next)
for (ll = (Ecore_Oldlist *)event_handlers; ll; ll = ll->next)
{
Ecore_Event_Handler *eh;
@ -434,7 +434,7 @@ _ecore_event_call(void)
}
while (events) _ecore_event_del(events);
if (!event_handlers_delete_me) return;
for (l = (Ecore_List *)event_handlers; l;)
for (l = (Ecore_Oldlist *)event_handlers; l;)
{
Ecore_Event_Handler *eh;

View File

@ -237,9 +237,9 @@ _ecore_exe_shutdown(void)
Ecore_Exe *
_ecore_exe_find(pid_t pid)
{
Ecore_List *l;
Ecore_Oldlist *l;
for (l = (Ecore_List *)exes; l; l = l->next)
for (l = (Ecore_Oldlist *)exes; l; l = l->next)
{
Ecore_Exe *exe;

View File

@ -0,0 +1,648 @@
#include <Ecore.h>
#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 && hash->size < PRIME_MAX) ? \
(hash->nodes / ecore_prime_table[hash->size]) > \
ECORE_HASH_CHAIN_MAX : FALSE)
#define ECORE_HASH_REDUCE(hash) ((hash && hash->size > PRIME_MIN) ? \
(double)hash->nodes / (double)ecore_prime_table[hash->size-1] \
< ((double)ECORE_HASH_CHAIN_MAX * 0.375) : FALSE)
/* Private hash manipulation functions */
static int _ecore_hash_add_node(Ecore_Hash *hash, Ecore_Hash_Node *node);
static Ecore_Hash_Node * _ecore_hash_get_node(Ecore_Hash *hash, void *key);
static int _ecore_hash_increase(Ecore_Hash *hash);
static int _ecore_hash_decrease(Ecore_Hash *hash);
inline int _ecore_hash_rehash(Ecore_Hash *hash, Ecore_List **old_table, int old_size);
static int _ecore_hash_bucket_destroy(Ecore_List *list, Ecore_Free_Cb keyd,
Ecore_Free_Cb valued);
inline Ecore_Hash_Node * _ecore_hash_get_bucket(Ecore_Hash *hash, Ecore_List *bucket,
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);
/**
* ecore_hash_new - create and initialize a new hash
* @hash_func: the function for determining hash position
* @compare: the function for comparing node keys
*
* Returns NULL on error, a new hash on success
*/
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;
}
/**
* ecore_hash_init - initialize a hash to some sane starting values
* @hash: the hash table to initialize
* @hash_func: the function for hashing node keys
* @compare: the function for comparing node keys
*
* Returns TRUE on success, FALSE on an error.
*/
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_List **)malloc(ecore_prime_table[0] *
sizeof(Ecore_List *));
memset(hash->buckets, 0, ecore_prime_table[0] * sizeof(Ecore_List *));
ECORE_INIT_LOCKS(hash);
return TRUE;
}
/**
* ecore_hash_set_free_key - set the function to destroy the keys of entries
* @hash: the hash that this will affect
* @function: the function that will free the node keys
*
* Returns TRUE on success, FALSE on error
*/
int ecore_hash_set_free_key(Ecore_Hash *hash, Ecore_Free_Cb function)
{
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
CHECK_PARAM_POINTER_RETURN("function", function, FALSE);
ECORE_WRITE_LOCK(hash);
hash->free_key = function;
ECORE_WRITE_UNLOCK(hash);
return TRUE;
}
/**
* ecore_hash_set_free_value - set the function to destroy the value
* @hash: the hash that this will affect
* @function: the function that will free the node values
*
* Returns TRUE on success, FALSE on error
*/
int ecore_hash_set_free_value(Ecore_Hash *hash, Ecore_Free_Cb function)
{
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
CHECK_PARAM_POINTER_RETURN("function", function, FALSE);
ECORE_WRITE_LOCK(hash);
hash->free_value = function;
ECORE_WRITE_UNLOCK(hash);
return TRUE;
}
/**
* ecore_hash_set - set the key/value pair in the hash table
* @hash: the hash table to set the the value in
* @key: the key for this value pair
* @value: the value corresponding with the key
*
* Returns TRUE if successful, FALSE if not
*/
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);
ECORE_WRITE_LOCK(hash);
node = _ecore_hash_get_node(hash, key);
if (node)
node->value = value;
else {
node = _ecore_hash_node_new(key, value);
if (node)
ret = _ecore_hash_add_node(hash, node);
}
ECORE_WRITE_UNLOCK(hash);
return ret;
}
/**
* ecore_hash_destroy - free the hash table and the data contained inside it
* @hash: the hash table to destroy
*
* Returns TRUE on success, FALSE on error
*/
void ecore_hash_destroy(Ecore_Hash *hash)
{
int i = 0;
CHECK_PARAM_POINTER("hash", hash);
ECORE_WRITE_LOCK(hash);
while (i < ecore_prime_table[hash->size]) {
if (hash->buckets[i])
_ecore_hash_bucket_destroy(hash->buckets[i],
hash->free_key, hash->free_value);
i++;
}
FREE(hash->buckets);
ECORE_WRITE_UNLOCK(hash);
ECORE_DESTROY_LOCKS(hash);
FREE(hash);
return;
}
/**
* ecore_hash_for_each - iterate over the entries in the hash table
*/
int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func)
{
int i = 0;
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE);
ECORE_READ_LOCK(hash);
while (i < ecore_prime_table[hash->size]) {
if (hash->buckets[i]) {
Ecore_Hash_Node *node;
ecore_list_goto_first(hash->buckets[i]);
while ((node = ecore_list_next(hash->buckets[i]))) {
for_each_func(node);
}
}
i++;
}
ECORE_READ_UNLOCK(hash);
return TRUE;
}
/**
* ecore_hash_dump_graph - print the distribution of the hash table for graphing
* @hash: the hash table to print
*
* Returns no value.
*/
void
ecore_hash_dump_graph(Ecore_Hash *hash)
{
int i;
for (i = 0; i < ecore_prime_table[hash->size]; i++)
if (hash->buckets[i])
printf("%d\t%u\n", i, ecore_list_nodes(hash->buckets[i]));
else
printf("%d\t0\n", i);
}
static int
_ecore_hash_bucket_destroy(Ecore_List *list, Ecore_Free_Cb keyd, Ecore_Free_Cb valued)
{
Ecore_Hash_Node *node;
CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
while ((node = ecore_list_remove_first(list)) != NULL)
_ecore_hash_node_destroy(node, keyd, valued);
ecore_list_destroy(list);
return TRUE;
}
/*
* Description: Add the node to the hash table
* Parameters: 1. hash - the hash table to add the key
* 2. node - the node to add to the hash table
* Returns: FALSE on error, TRUE on success
*/
static int
_ecore_hash_add_node(Ecore_Hash *hash, Ecore_Hash_Node *node)
{
unsigned int 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 = (unsigned int)node->key %
ecore_prime_table[hash->size];
else
hash_val = ECORE_COMPUTE_HASH(hash, node->key);
/* Create the list if it's not already present */
if (!hash->buckets[hash_val])
hash->buckets[hash_val] = ecore_list_new();
/* Append the node to the list at the index position */
if (!ecore_list_prepend(hash->buckets[hash_val], node))
return FALSE;
hash->nodes++;
return TRUE;
}
/**
* ecore_hash_get - retrieve the value associated with key
* @hash: the hash table to search for the key
* @key: the key to search for in the hash table
*
* Returns NULL on error, value corresponding to key on success
*/
void *ecore_hash_get(Ecore_Hash *hash, void *key)
{
void *data;
Ecore_Hash_Node *node;
CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
node = _ecore_hash_get_node(hash, key);
if (!node)
return NULL;
ECORE_READ_LOCK(node);
data = node->value;
ECORE_READ_UNLOCK(node);
return data;
}
/**
* ecore_hash_remove - remove the value associated with key
* @hash: the hash table to remove the key from
* @key: the key to search for in the hash table
*
* Returns NULL on error, value corresponding to key on success
*/
void *ecore_hash_remove(Ecore_Hash *hash, void *key)
{
Ecore_Hash_Node *node = NULL;
Ecore_List *list;
unsigned int hash_val;
void *ret = NULL;
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
ECORE_WRITE_LOCK(hash);
/* Compute the position in the table */
if (!hash->hash_func)
hash_val = (unsigned int)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];
ecore_list_goto_first(list);
/*
* Traverse the list to find the specified key
*/
if (hash->compare) {
while ((node = ecore_list_current(list)) &&
hash->compare(node->key, key) != 0)
ecore_list_next(list);
}
else {
while ((node = ecore_list_current(list)) &&
node->key != key)
ecore_list_next(list);
}
if (node) {
ecore_list_remove(list);
ret = node->value;
FREE(node);
}
}
if (ECORE_HASH_REDUCE(hash))
_ecore_hash_decrease(hash);
ECORE_WRITE_UNLOCK(hash);
return ret;
}
/*
* Description: Retrieve the node associated with key
* Parameters: 1. hash - the hash table to search for the key
* 2. key - the key to search for in the hash table
* Returns: NULL on error, node corresponding to key on success
*/
static Ecore_Hash_Node *
_ecore_hash_get_node(Ecore_Hash *hash, void *key)
{
unsigned int hash_val;
Ecore_Hash_Node *node = NULL;
CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);
ECORE_READ_LOCK(hash);
/* Compute the position in the table */
if (!hash->hash_func)
hash_val = (unsigned int)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_get_bucket(hash, hash->buckets[hash_val], key);
ECORE_READ_UNLOCK(hash);
return node;
}
/*
* Description: Search the hash bucket for a specified key
* Parameters: 1. hash - the hash table to retrieve the comparison function
* 2. bucket - the list to search for the key
* 3. key - the key to search for in the list
* Returns: NULL on error or not found, the found node on success
*/
inline Ecore_Hash_Node *
_ecore_hash_get_bucket(Ecore_Hash *hash, Ecore_List *bucket, void *key)
{
Ecore_Hash_Node *node = NULL;
ECORE_READ_LOCK(hash);
ecore_list_goto_first(bucket);
/*
* Traverse the list to find the desired node, if the node is in the
* list, then return the node.
*/
if (hash->compare) {
while ((node = ecore_list_next(bucket)) != NULL) {
ECORE_READ_LOCK(node);
if (hash->compare(node->key, key) == 0) {
ECORE_READ_UNLOCK(node);
ECORE_READ_UNLOCK(hash);
return node;
}
ECORE_READ_UNLOCK(node);
}
}
else {
while ((node = ecore_list_next(bucket)) != NULL) {
ECORE_READ_LOCK(node);
if (node->key == key) {
ECORE_READ_UNLOCK(node);
ECORE_READ_UNLOCK(hash);
return node;
}
ECORE_READ_UNLOCK(node);
}
}
ECORE_READ_UNLOCK(hash);
return NULL;
}
/*
* Description: Increase the size of the hash table by approx. 2 * current size
* Parameters: 1. hash - the hash table to increase the size of
* 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 (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 = (Ecore_List **)calloc(ecore_prime_table[hash->size],
sizeof(Ecore_List *));
/*
* 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;
}
/*
* Description: Decrease the size of the hash table by < 1/2 * current size
* Parameters: 1. hash - the hash table to decrease the size of
* Returns: TRUE on success, FALSE on error
*/
static int
_ecore_hash_decrease(Ecore_Hash *hash)
{
Ecore_List **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_List **)malloc(ecore_prime_table[hash->size] *
sizeof(Ecore_List *));
/*
* Make sure allocation succeeded otherwise rreturn to the previous
* state
*/
if (!hash->buckets) {
hash->buckets = old;
hash->size++;
return FALSE;
}
/*
* Zero out the new area
*/
memset(hash->buckets, 0, ecore_prime_table[hash->size]
* sizeof(Ecore_List *));
hash->nodes = 0;
if (_ecore_hash_rehash(hash, old, hash->size - 1)) {
FREE(old);
return TRUE;
}
return FALSE;
}
/*
* Description: Rehash the nodes of a table into the hash table
* Parameters: 1. hash - the hash to place the nodes of the table
* 2. table - the table to remove the nodes from and place in hash
* Returns: TRUE on success, FALSE on success
*/
inline int
_ecore_hash_rehash(Ecore_Hash *hash, Ecore_List **old_table, int old_size)
{
int i;
Ecore_Hash_Node *node;
Ecore_List *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 */
old = old_table[i];
old_table[i] = NULL;
/* Loop through re-adding each node to the hash table */
while (old && (node = ecore_list_remove_last(old))) {
_ecore_hash_add_node(hash, node);
}
/* Now free up the old list space */
if (old)
ecore_list_destroy(old);
}
return TRUE;
}
/*
* Description: Create a new hash node for key and value storage
* Parameters: 1. key - the key for this node
* 2. value - the value that the key references
* 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;
}
/*
* Description: Initialize a hash node to some sane default values
* Parameters: 1. node - the node to set the values
* 2. key - the key to reference this node
* 3. value - the value that key refers to
* 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);
ECORE_INIT_LOCKS(node);
node->key = key;
node->value = value;
return TRUE;
}
/*
* Description: Destroy a node and call the specified callbacks to free data
* Parameters: 1. node - the node to be destroyed
* 2. keyd - the function to free the key
* 3. valued - the function to free the value
* 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;
}

View File

@ -75,9 +75,9 @@ _ecore_idle_enterer_shutdown(void)
void
_ecore_idle_enterer_call(void)
{
Ecore_List *l;
Ecore_Oldlist *l;
for (l = (Ecore_List *)idle_enterers; l; l = l->next)
for (l = (Ecore_Oldlist *)idle_enterers; l; l = l->next)
{
Ecore_Idle_Enterer *ie;
@ -89,7 +89,7 @@ _ecore_idle_enterer_call(void)
}
if (idle_enterers_delete_me)
{
for (l = (Ecore_List *)idle_enterers; l;)
for (l = (Ecore_Oldlist *)idle_enterers; l;)
{
Ecore_Idle_Enterer *ie;

View File

@ -72,9 +72,9 @@ _ecore_idle_exiter_shutdown(void)
void
_ecore_idle_exiter_call(void)
{
Ecore_List *l;
Ecore_Oldlist *l;
for (l = (Ecore_List *)idle_exiters; l; l = l->next)
for (l = (Ecore_Oldlist *)idle_exiters; l; l = l->next)
{
Ecore_Idle_Exiter *ie;
@ -86,7 +86,7 @@ _ecore_idle_exiter_call(void)
}
if (idle_exiters_delete_me)
{
for (l = (Ecore_List *)idle_exiters; l;)
for (l = (Ecore_Oldlist *)idle_exiters; l;)
{
Ecore_Idle_Exiter *ie;

View File

@ -76,9 +76,9 @@ _ecore_idler_shutdown(void)
int
_ecore_idler_call(void)
{
Ecore_List *l;
Ecore_Oldlist *l;
for (l = (Ecore_List *)idlers; l; l = l->next)
for (l = (Ecore_Oldlist *)idlers; l; l = l->next)
{
Ecore_Idler *ie;
@ -90,7 +90,7 @@ _ecore_idler_call(void)
}
if (idlers_delete_me)
{
for (l = (Ecore_List *)idlers; l;)
for (l = (Ecore_Oldlist *)idlers; l;)
{
Ecore_Idler *ie;

File diff suppressed because it is too large Load Diff

View File

@ -239,7 +239,7 @@ _ecore_main_select(double timeout)
fd_set rfds, wfds, exfds;
int max_fd;
int ret;
Ecore_List *l;
Ecore_Oldlist *l;
t = NULL;
if (timeout > 0.0)
@ -262,7 +262,7 @@ _ecore_main_select(double timeout)
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&exfds);
for (l = (Ecore_List *)fd_handlers; l; l = l->next)
for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next)
{
Ecore_Fd_Handler *fdh;
@ -291,7 +291,7 @@ _ecore_main_select(double timeout)
}
if (ret > 0)
{
for (l = (Ecore_List *)fd_handlers; l; l = l->next)
for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next)
{
Ecore_Fd_Handler *fdh;
@ -315,10 +315,10 @@ _ecore_main_select(double timeout)
static void
_ecore_main_fd_handlers_cleanup(void)
{
Ecore_List *l;
Ecore_Oldlist *l;
if (!fd_handlers_delete_me) return;
for (l = (Ecore_List *)fd_handlers; l;)
for (l = (Ecore_Oldlist *)fd_handlers; l;)
{
Ecore_Fd_Handler *fdh;
@ -337,9 +337,9 @@ _ecore_main_fd_handlers_cleanup(void)
static void
_ecore_main_fd_handlers_call(void)
{
Ecore_List *l;
Ecore_Oldlist *l;
for (l = (Ecore_List *)fd_handlers; l; l = l->next)
for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next)
{
Ecore_Fd_Handler *fdh;
@ -366,11 +366,11 @@ _ecore_main_fd_handlers_call(void)
static int
_ecore_main_fd_handlers_buf_call(void)
{
Ecore_List *l;
Ecore_Oldlist *l;
int ret;
ret = 0;
for (l = (Ecore_List *)fd_handlers; l; l = l->next)
for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next)
{
Ecore_Fd_Handler *fdh;

View File