/** \ingroup dbprim_hash * \brief Find an entry in a hash table. * * This function looks up an entry matching the given \p key. * * \param table A pointer to a #hash_table_t. * \param entry_p * A pointer to a pointer to a #hash_entry_t. This is a * result parameter. If \c NULL is passed, the lookup * will be performed and an appropriate error code * returned. * \param key A pointer to a #db_key_t describing the item to find. * * \retval DB_ERR_BADARGS An argument was invalid. * \retval DB_ERR_NOENTRY No matching entry was found. */ unsigned long ht_find(hash_table_t *table, hash_entry_t **entry_p, db_key_t *key) { unsigned long hash; link_elem_t *elem; initialize_dbpr_error_table(); /* initialize error table */ if (!ht_verify(table) || !key) /* verify arguments */ return DB_ERR_BADARGS; if (!table->ht_count) /* no entries in table... */ return DB_ERR_NOENTRY; hash = (*table->ht_func)(table, key) % table->ht_modulus; /* get hash */ /* walk through each element in that section */ for (elem = ll_first(&table->ht_table[hash]); elem; elem = le_next(elem)) /* compare keys... */ if (!(*table->ht_comp)(table, key, he_key((hash_entry_t *)le_object(elem)))) { /* found one, return it */ if (entry_p) *entry_p = le_object(elem); return 0; } return DB_ERR_NOENTRY; /* couldn't find a matching entry */ }
/** \ingroup dbprim_hash * \brief Iterate over each entry in a hash table. * * This function iterates over every entry in a hash table (in an * unspecified order), executing the given \p iter_func on each entry. * * \param table A pointer to a #hash_table_t. * \param iter_func * A pointer to a callback function used to perform * user-specified actions on an entry in a hash table. \c * NULL is an invalid value. See the documentation for * #hash_iter_t for more information. * \param extra A \c void pointer that will be passed to \p * iter_func. * * \retval DB_ERR_BADARGS An argument was invalid. * \retval DB_ERR_FROZEN The hash table is frozen. */ unsigned long ht_iter(hash_table_t *table, hash_iter_t iter_func, void *extra) { unsigned long retval; int i; link_elem_t *elem; initialize_dbpr_error_table(); /* initialize error table */ if (!ht_verify(table) || !iter_func) /* verify arguments */ return DB_ERR_BADARGS; if (table->ht_flags & HASH_FLAG_FREEZE) /* don't mess with frozen tables */ return DB_ERR_FROZEN; table->ht_flags |= HASH_FLAG_FREEZE; /* freeze the table */ /* walk through all the elements and call the iteration function */ for (i = 0; i < table->ht_modulus; i++) for (elem = ll_first(&table->ht_table[i]); elem; elem = le_next(elem)) if ((retval = (*iter_func)(table, le_object(elem), extra))) { table->ht_flags &= ~HASH_FLAG_FREEZE; /* unfreeze the table */ return retval; } table->ht_flags &= ~HASH_FLAG_FREEZE; /* unfreeze the table */ return 0; }
static unsigned long _sh_flush_iter(link_head_t *head, link_elem_t *elem, void *extra) { unsigned long retval = 0; struct _sh_flush_s *sf; sf = extra; /* Remove the object from all lists first */ if (_st_remove(sf->sf_table, le_object(elem), ST_REM_HASH | (sf->sf_elem == SMAT_LOC_FIRST ? ST_REM_SECOND : ST_REM_FIRST))) return DB_ERR_UNRECOVERABLE; /* call the user flush function if so desired */ if (sf->sf_flush) retval = (*sf->sf_flush)(sf->sf_table, le_object(elem), sf->sf_extra); _smat_free(le_object(elem)); /* destroy the entry */ return retval; }