u_handle_table.c File Reference

Generic handle table implementation. More...

Include dependency graph for u_handle_table.c:

Go to the source code of this file.

Data Structures

struct  handle_table

Defines

#define HANDLE_TABLE_INITIAL_SIZE   16

Functions

struct handle_tablehandle_table_create (void)
void handle_table_set_destroy (struct handle_table *ht, void(*destroy)(void *object))
 Set an optional destructor callback.
static int handle_table_resize (struct handle_table *ht, unsigned minimum_size)
 Resize the table if necessary.
static void handle_table_clear (struct handle_table *ht, unsigned index)
unsigned handle_table_add (struct handle_table *ht, void *object)
 Add a new object.
unsigned handle_table_set (struct handle_table *ht, unsigned handle, void *object)
 Returns zero on failure (out of memory).
void * handle_table_get (struct handle_table *ht, unsigned handle)
 Fetch an existing object.
void handle_table_remove (struct handle_table *ht, unsigned handle)
unsigned handle_table_get_next_handle (struct handle_table *ht, unsigned handle)
unsigned handle_table_get_first_handle (struct handle_table *ht)
void handle_table_destroy (struct handle_table *ht)


Detailed Description

Generic handle table implementation.

Author:
José Fonseca <jrfonseca@tungstengraphics.com>

Definition in file u_handle_table.c.


Define Documentation

#define HANDLE_TABLE_INITIAL_SIZE   16

Definition at line 43 of file u_handle_table.c.


Function Documentation

unsigned handle_table_add ( struct handle_table ht,
void *  object 
)

Add a new object.

Returns a zero handle on failure (out of memory).

Definition at line 150 of file u_handle_table.c.

References assert, handle_table::filled, handle_table_resize(), handle_table::objects, and handle_table::size.

00152 {
00153    unsigned index;
00154    unsigned handle;
00155    
00156    assert(ht);
00157    assert(object);
00158    if(!object)
00159       return 0;
00160 
00161    /* linear search for an empty handle */
00162    while(ht->filled < ht->size) {
00163       if(!ht->objects[ht->filled])
00164          break;
00165       ++ht->filled;
00166    }
00167   
00168    index = ht->filled;
00169    handle = index + 1;
00170    
00171    /* check integer overflow */
00172    if(!handle)
00173       return 0;
00174    
00175    /* grow the table if necessary */
00176    if(!handle_table_resize(ht, index))
00177       return 0;
00178 
00179    assert(!ht->objects[index]);
00180    ht->objects[index] = object;
00181    ++ht->filled;
00182    
00183    return handle;
00184 }

static void handle_table_clear ( struct handle_table ht,
unsigned  index 
) [static]

Definition at line 128 of file u_handle_table.c.

References handle_table::destroy, and handle_table::objects.

00130 {
00131    void *object;
00132    
00133    /* The order here is important so that the object being destroyed is not
00134     * present in the table when seen by the destroy callback, because the 
00135     * destroy callback may directly or indirectly call the other functions in 
00136     * this module.
00137     */
00138 
00139    object = ht->objects[index];
00140    if(object) {
00141       ht->objects[index] = NULL;
00142       
00143       if(ht->destroy)
00144          ht->destroy(object);
00145    }   
00146 }

struct handle_table* handle_table_create ( void   )  [read]

Definition at line 62 of file u_handle_table.c.

References CALLOC, handle_table::destroy, handle_table::filled, FREE, HANDLE_TABLE_INITIAL_SIZE, MALLOC_STRUCT, handle_table::objects, and handle_table::size.

00063 {
00064    struct handle_table *ht;
00065    
00066    ht = MALLOC_STRUCT(handle_table);
00067    if(!ht)
00068       return NULL;
00069    
00070    ht->objects = (void **)CALLOC(HANDLE_TABLE_INITIAL_SIZE, sizeof(void *));
00071    if(!ht->objects) {
00072       FREE(ht);
00073       return NULL;
00074    }
00075    
00076    ht->size = HANDLE_TABLE_INITIAL_SIZE;
00077    ht->filled = 0;
00078    
00079    ht->destroy = NULL;
00080    
00081    return ht;
00082 }

void handle_table_destroy ( struct handle_table ht  ) 

Definition at line 281 of file u_handle_table.c.

References assert, handle_table::destroy, FREE, handle_table_clear(), handle_table::objects, and handle_table::size.

00282 {
00283    unsigned index;
00284    assert(ht);
00285 
00286    if(ht->destroy)
00287       for(index = 0; index < ht->size; ++index)
00288          handle_table_clear(ht, index);
00289    
00290    FREE(ht->objects);
00291    FREE(ht);
00292 }

void* handle_table_get ( struct handle_table ht,
unsigned  handle 
)

Fetch an existing object.

Returns NULL for an invalid handle.

Definition at line 218 of file u_handle_table.c.

References assert, handle_table::objects, and handle_table::size.

00220 {
00221    void *object;
00222    
00223    assert(ht);
00224    assert(handle);
00225    if(!handle || handle > ht->size)
00226       return NULL;
00227 
00228    object = ht->objects[handle - 1];
00229    
00230    return object;
00231 }

unsigned handle_table_get_first_handle ( struct handle_table ht  ) 

Definition at line 274 of file u_handle_table.c.

References handle_table_get_next_handle().

00275 {
00276    return handle_table_get_next_handle(ht, 0);
00277 }

unsigned handle_table_get_next_handle ( struct handle_table ht,
unsigned  handle 
)

Definition at line 259 of file u_handle_table.c.

References handle_table::objects, and handle_table::size.

00261 {
00262    unsigned index;
00263    
00264    for(index = handle; index < ht->size; ++index) {
00265       if(ht->objects[index])
00266          return index + 1;
00267    }
00268 
00269    return 0;
00270 }

void handle_table_remove ( struct handle_table ht,
unsigned  handle 
)

Definition at line 235 of file u_handle_table.c.

References assert, handle_table::filled, handle_table_clear(), handle_table::objects, and handle_table::size.

00237 {
00238    void *object;
00239    unsigned index;
00240    
00241    assert(ht);
00242    assert(handle);
00243    if(!handle || handle > ht->size)
00244       return;
00245 
00246    index = handle - 1;
00247    object = ht->objects[index];
00248    if(!object)
00249       return;
00250    
00251    handle_table_clear(ht, index);
00252 
00253    if(index < ht->filled)
00254       ht->filled = index;
00255 }

static int handle_table_resize ( struct handle_table ht,
unsigned  minimum_size 
) [static]

Resize the table if necessary.

Definition at line 98 of file u_handle_table.c.

References assert, handle_table::objects, REALLOC, and handle_table::size.

00100 {
00101    unsigned new_size;
00102    void **new_objects;
00103 
00104    if(ht->size > minimum_size)
00105       return ht->size;
00106 
00107    new_size = ht->size;
00108    while(!(new_size > minimum_size))
00109       new_size *= 2;
00110    assert(new_size);
00111    
00112    new_objects = (void **)REALLOC((void *)ht->objects,
00113                                   ht->size*sizeof(void *),
00114                                   new_size*sizeof(void *));
00115    if(!new_objects)
00116       return 0;
00117    
00118    memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
00119    
00120    ht->size = new_size;
00121    ht->objects = new_objects;
00122    
00123    return ht->size;
00124 }

unsigned handle_table_set ( struct handle_table ht,
unsigned  handle,
void *  object 
)

Returns zero on failure (out of memory).

Definition at line 188 of file u_handle_table.c.

References assert, handle_table_clear(), handle_table_resize(), and handle_table::objects.

00191 {
00192    unsigned index;
00193    
00194    assert(ht);
00195    assert(handle);
00196    if(!handle)
00197       return 0;
00198 
00199    assert(object);
00200    if(!object)
00201       return 0;
00202    
00203    index = handle - 1;
00204 
00205    /* grow the table if necessary */
00206    if(!handle_table_resize(ht, index))
00207       return 0;
00208 
00209    handle_table_clear(ht, index);
00210 
00211    ht->objects[index] = object;
00212    
00213    return handle;
00214 }

void handle_table_set_destroy ( struct handle_table ht,
void(*)(void *object)  destroy 
)

Set an optional destructor callback.

If set, it will be called during handle_table_remove and handle_table_destroy calls.

Definition at line 86 of file u_handle_table.c.

References assert, and handle_table::destroy.

00088 {
00089    assert(ht);
00090    ht->destroy = destroy;
00091 }


Generated on Tue Sep 29 06:25:28 2009 for Gallium3D by  doxygen 1.5.4