summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/util/u_handle_table.c85
-rw-r--r--src/gallium/auxiliary/util/u_handle_table.h11
2 files changed, 75 insertions, 21 deletions
diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c
index 8a298f7c413..ab427ee371d 100644
--- a/src/gallium/auxiliary/util/u_handle_table.c
+++ b/src/gallium/auxiliary/util/u_handle_table.c
@@ -26,6 +26,7 @@
**************************************************************************/
/**
+ * @file
* Generic handle table implementation.
*
* @author José Fonseca <[email protected]>
@@ -90,6 +91,39 @@ handle_table_set_destroy(struct handle_table *ht,
}
+/**
+ * Resize the table if necessary
+ */
+static INLINE int
+handle_table_resize(struct handle_table *ht,
+ unsigned minimum_size)
+{
+ unsigned new_size;
+ void **new_objects;
+
+ if(ht->size > minimum_size)
+ return ht->size;
+
+ new_size = ht->size;
+ while(!(new_size > minimum_size))
+ new_size *= 2;
+ assert(new_size);
+
+ new_objects = (void **)REALLOC((void *)ht->objects,
+ ht->size*sizeof(void *),
+ new_size*sizeof(void *));
+ if(!new_objects)
+ return 0;
+
+ memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
+
+ ht->size = new_size;
+ ht->objects = new_objects;
+
+ return ht->size;
+}
+
+
unsigned
handle_table_add(struct handle_table *ht,
void *object)
@@ -109,34 +143,17 @@ handle_table_add(struct handle_table *ht,
++ht->filled;
}
- /* grow the table */
- if(ht->filled == ht->size) {
- unsigned new_size;
- void **new_objects;
-
- new_size = ht->size*2;
- assert(new_size);
-
- new_objects = (void **)REALLOC((void *)ht->objects,
- ht->size*sizeof(void *),
- new_size*sizeof(void *));
- if(!new_objects)
- return 0;
-
- memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
-
- ht->size = new_size;
- ht->objects = new_objects;
- }
-
index = ht->filled;
-
handle = index + 1;
/* check integer overflow */
if(!handle)
return 0;
+ /* grow the table if necessary */
+ if(!handle_table_resize(ht, index))
+ return 0;
+
assert(!ht->objects[index]);
ht->objects[index] = object;
++ht->filled;
@@ -145,6 +162,32 @@ handle_table_add(struct handle_table *ht,
}
+unsigned
+handle_table_set(struct handle_table *ht,
+ unsigned handle,
+ void *object)
+{
+ unsigned index;
+
+ assert(ht);
+ assert(handle > 0);
+ assert(handle <= ht->size);
+ if(!handle || handle > ht->size)
+ return 0;
+
+ index = handle - 1;
+
+ /* grow the table if necessary */
+ if(!handle_table_resize(ht, index))
+ return 0;
+
+ assert(!ht->objects[index]);
+ ht->objects[index] = object;
+
+ return handle;
+}
+
+
void *
handle_table_get(struct handle_table *ht,
unsigned handle)
diff --git a/src/gallium/auxiliary/util/u_handle_table.h b/src/gallium/auxiliary/util/u_handle_table.h
index 51fc273865f..a2f1f604ade 100644
--- a/src/gallium/auxiliary/util/u_handle_table.h
+++ b/src/gallium/auxiliary/util/u_handle_table.h
@@ -26,6 +26,7 @@
**************************************************************************/
/**
+ * @file
* Generic handle table.
*
* @author José Fonseca <[email protected]>
@@ -42,6 +43,8 @@ extern "C" {
/**
* Abstract data type to map integer handles to objects.
+ *
+ * Also referred as "pointer array".
*/
struct handle_table;
@@ -71,6 +74,14 @@ handle_table_add(struct handle_table *ht,
void *object);
/**
+ * Returns zero on failure (out of memory).
+ */
+unsigned
+handle_table_set(struct handle_table *ht,
+ unsigned handle,
+ void *object);
+
+/**
* Fetch an existing object.
*
* Returns NULL for an invalid handle.