gallium: Add a new handle_table_set that accepts an arbitrary handle.
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Wed, 12 Mar 2008 22:39:13 +0000 (22:39 +0000)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Thu, 13 Mar 2008 10:23:02 +0000 (10:23 +0000)
src/gallium/auxiliary/util/u_handle_table.c
src/gallium/auxiliary/util/u_handle_table.h

index 8a298f7c413efdded329996d5193a1c0664ad9ab..ab427ee371da0f010f16ea38998379a023e2aa9d 100644 (file)
@@ -26,6 +26,7 @@
  **************************************************************************/
 
 /**
+ * @file
  * Generic handle table implementation.
  *  
  * @author José Fonseca <jrfonseca@tungstengraphics.com>
@@ -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)
index 51fc273865feefb5284485c00687ffe78ada0de8..a2f1f604ade2c051a0449d4dca7c1d0e38d8ca79 100644 (file)
@@ -26,6 +26,7 @@
  **************************************************************************/
 
 /**
+ * @file
  * Generic handle table.
  *  
  * @author José Fonseca <jrfonseca@tungstengraphics.com>
@@ -42,6 +43,8 @@ extern "C" {
    
 /**
  * Abstract data type to map integer handles to objects.
+ * 
+ * Also referred as "pointer array".
  */
 struct handle_table;
 
@@ -70,6 +73,14 @@ unsigned
 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.
  *