Minor tweaks to help out at a driver level.
[mesa.git] / src / mesa / main / hash.c
index 03050e7fc6966a61cbecb87567e8954c687d5493..78be122aab5cf6385c8464adde14a0fd83946fbf 100644 (file)
@@ -1,10 +1,20 @@
-/* $Id: hash.c,v 1.11 2001/11/02 00:57:04 brianp Exp $ */
+/**
+ * \file hash.c
+ * Generic hash table. 
+ *
+ * Used for display lists and texture objects.  The hash functions are
+ * thread-safe.
+ * 
+ * \note key=0 is illegal.
+ *
+ * \author Brian Paul
+ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  */
 
 
-#ifdef PC_HEADER
-#include "all.h"
-#else
 #include "glheader.h"
+#include "imports.h"
 #include "glthread.h"
 #include "hash.h"
-#include "mem.h"
-#endif
+#include "context.h"
 
 
-/*
- * Generic hash table.
+#define TABLE_SIZE 1023  /**< Size of lookup table/array */
+
+/**
+ * An entry in the hash table.  
  *
- * This is used to implement display list and texture object lookup.
- * NOTE: key=0 is illegal.
+ * This struct is private to this file.
  */
-
-
-#define TABLE_SIZE 1024
-
 struct HashEntry {
-   GLuint Key;
-   void *Data;
-   struct HashEntry *Next;
+   GLuint Key;             /**< the entry's key */
+   void *Data;             /**< the entry's data */
+   struct HashEntry *Next; /**< pointer to next entry */
 };
 
+/**
+ * The hash table data structure.  
+ *
+ * This is an opaque types (it's not defined in hash.h file).
+ */
 struct _mesa_HashTable {
-   struct HashEntry *Table[TABLE_SIZE];
-   GLuint MaxKey;
-   _glthread_Mutex Mutex;
+   struct HashEntry *Table[TABLE_SIZE];  /**< the lookup table */
+   GLuint MaxKey;                        /**< highest key inserted so far */
+   _glthread_Mutex Mutex;                /**< mutual exclusion lock */
 };
 
 
 
-/*
- * Return pointer to a new, empty hash table.
+/**
+ * Create a new hash table.
+ * 
+ * \return pointer to a new, empty hash table.
  */
 struct _mesa_HashTable *_mesa_NewHashTable(void)
 {
@@ -73,8 +84,12 @@ struct _mesa_HashTable *_mesa_NewHashTable(void)
 
 
 
-/*
+/**
  * Delete a hash table.
+ * 
+ * \param table the hash table to delete.
+ *
+ * Frees each entry on the hash table and then the hash table structure itself.
  */
 void _mesa_DeleteHashTable(struct _mesa_HashTable *table)
 {
@@ -88,16 +103,21 @@ void _mesa_DeleteHashTable(struct _mesa_HashTable *table)
         entry = next;
       }
    }
+   _glthread_DESTROY_MUTEX(table->Mutex);
    FREE(table);
 }
 
 
 
-/*
+/**
  * Lookup an entry in the hash table.
- * Input:  table - the hash table
- *         key - the key
- * Return:  user data pointer or NULL if key not in table
+ * 
+ * \param table the hash table.
+ * \param key the key.
+ * 
+ * \return pointer to user's data or NULL if key not in table
+ *
+ * Walks through the hash entry until finding the matching key.
  */
 void *_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key)
 {
@@ -120,12 +140,17 @@ void *_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key)
 
 
 
-/*
- * Insert into the hash table.  If an entry with this key already exists
- * we'll replace the existing entry.
- * Input:  table - the hash table
- *         key - the key (not zero)
- *         data - pointer to user data
+/**
+ * Insert into the hash table.  
+ *
+ * If an entry with this key already exists we'll replace the existing entry.
+ * 
+ * \param table the hash table.
+ * \param key the key (not zero).
+ * \param data pointer to user data.
+ *
+ * While holding the hash table's lock, walk through the hash entry list replacing the data if a
+ * matching key is found, or inserts a new table entry otherwise.
  */
 void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
 {
@@ -165,10 +190,14 @@ void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
 
 
 
-/*
+/**
  * Remove an entry from the hash table.
- * Input:  table - the hash table
- *         key - key of entry to remove
+ * 
+ * \param table the hash table.
+ * \param key key of entry to remove.
+ *
+ * While holding the hash table's lock, searches the entry with the matching
+ * key and unlinks it.
  */
 void _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key)
 {
@@ -205,10 +234,18 @@ void _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key)
 
 
 
-/*
- * Return the key of the "first" entry in the hash table.
+/**
+ * Get the key of the "first" entry in the hash table.
+ * 
  * This is used in the course of deleting all display lists when
  * a context is destroyed.
+ * 
+ * \param table the hash table
+ * 
+ * \return key for the "first" entry in the hash table.
+ *
+ * While holding the lock, walks through all table positions until finding
+ * the first entry of the first non-empty one.
  */
 GLuint _mesa_HashFirstEntry(struct _mesa_HashTable *table)
 {
@@ -227,8 +264,10 @@ GLuint _mesa_HashFirstEntry(struct _mesa_HashTable *table)
 
 
 
-/*
+/**
  * Dump contents of hash table for debugging.
+ * 
+ * \param table the hash table.
  */
 void _mesa_HashPrint(const struct _mesa_HashTable *table)
 {
@@ -237,7 +276,7 @@ void _mesa_HashPrint(const struct _mesa_HashTable *table)
    for (i=0;i<TABLE_SIZE;i++) {
       const struct HashEntry *entry = table->Table[i];
       while (entry) {
-        printf("%u %p\n", entry->Key, entry->Data);
+        _mesa_debug(NULL, "%u %p\n", entry->Key, entry->Data);
         entry = entry->Next;
       }
    }
@@ -245,11 +284,18 @@ void _mesa_HashPrint(const struct _mesa_HashTable *table)
 
 
 
-/*
- * Find a block of 'numKeys' adjacent unused hash keys.
- * Input:  table - the hash table
- *         numKeys - number of keys needed
- * Return:  starting key of free block or 0 if failure
+/**
+ * Find a block of adjacent unused hash keys.
+ * 
+ * \param table the hash table.
+ * \param numKeys number of keys needed.
+ * 
+ * \return Starting key of free block or 0 if failure.
+ *
+ * If there are enough free keys between the maximum key existing in the table
+ * (_mesa_HashTable::MaxKey) and the maximum key possible, then simply return
+ * the adjacent key. Otherwise do a full search for a free key block in the
+ * allowable key range.
  */
 GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys)
 {
@@ -294,17 +340,19 @@ int main(int argc, char *argv[])
    int a, b, c;
    struct HashTable *t;
 
-   printf("&a = %p\n", &a);
-   printf("&b = %p\n", &b);
+   _mesa_printf("&a = %p\n", &a);
+   _mesa_printf("&b = %p\n", &b);
 
    t = _mesa_NewHashTable();
    _mesa_HashInsert(t, 501, &a);
    _mesa_HashInsert(t, 10, &c);
    _mesa_HashInsert(t, 0xfffffff8, &b);
    _mesa_HashPrint(t);
-   printf("Find 501: %p\n", _mesa_HashLookup(t,501));
-   printf("Find 1313: %p\n", _mesa_HashLookup(t,1313));
-   printf("Find block of 100: %d\n", _mesa_HashFindFreeKeyBlock(t, 100));
+
+   _mesa_printf("Find 501: %p\n", _mesa_HashLookup(t,501));
+   _mesa_printf("Find 1313: %p\n", _mesa_HashLookup(t,1313));
+   _mesa_printf("Find block of 100: %d\n", _mesa_HashFindFreeKeyBlock(t, 100));
+
    _mesa_DeleteHashTable(t);
 
    return 0;