vmkdrivers/BLD/build/HEADERS/vmkapi-current-all-public-bincomp/generic/release/lib/vmkapi_hash.h
2015-10-23 18:39:55 -04:00

508 lines
17 KiB
C

/* **********************************************************
* Copyright 2006 - 2013 VMware, Inc. All rights reserved.
* **********************************************************/
/*
* @VMKAPIMOD_LICENSE@
*/
/*
***********************************************************************
* Hash */ /**
* \addtogroup Lib
* @{
* \defgroup Hash Hash
*
* The following are interfaces for a hash abstraction which enables
* arbitrary key-value pair storage.
*
* @{
***********************************************************************
*/
#ifndef _VMKAPI_HASH_H_
#define _VMKAPI_HASH_H_
/** \cond never */
#ifndef VMK_HEADER_INCLUDED_FROM_VMKAPI_H
#error This vmkapi file should never be included directly but only via vmkapi.h
#endif
/** \endcond never */
#include "base/vmkapi_heap.h"
/**
* \brief Invalid hash handle
*/
#define VMK_INVALID_HASH_HANDLE NULL
/**
* \brief Handle to a hash table
*/
typedef void *vmk_HashTable;
/**
* \brief Key used to store key-value pair. A key can really be anything ranging
* from a string to integer to whatever data structure one would like
* to use as a key.
*/
typedef void *vmk_HashKey;
/**
* \brief Hash implementation uses these flags to process key.
*/
typedef vmk_uint64 vmk_HashKeyFlags;
/** No flags. */
#define VMK_HASH_KEY_FLAGS_NONE 0x0
/**
* Hash implementation should do a local copy of the key on insertion
* and do not assume the memory backing up the key will be persistent.
*/
#define VMK_HASH_KEY_FLAGS_LOCAL_COPY 0x1
/**
* \brief Key length.
*/
typedef vmk_uint32 vmk_HashKeyLen;
/**
* \brief Value used as part of a key-value pair. There is no restriction
* related to the internal value representation.
*/
typedef void *vmk_HashValue;
/**
* \brief Key iterator commands.
*/
typedef vmk_uint64 vmk_HashKeyIteratorCmd;
/**
* Key type supported
*/
typedef enum vmk_HashKeyType {
/* Integer key */
VMK_HASH_KEY_TYPE_INT = 0,
/* String key */
VMK_HASH_KEY_TYPE_STR,
/* Opaque key */
VMK_HASH_KEY_TYPE_OPAQUE,
} vmk_HashKeyType;
/** Keep iterating through the hash table. */
#define VMK_HASH_KEY_ITER_CMD_CONTINUE 0x0
/** Stop iterating through the hash table. */
#define VMK_HASH_KEY_ITER_CMD_STOP 0x1
/** Delete the iterated key-value pair. */
#define VMK_HASH_KEY_ITER_CMD_DELETE 0x2
/*
*******************************************************************************
* vmk_HashValueAcquire -- */ /**
*
* \brief Atomically acquire a reference to a value stored in the hash table.
*
* \note This function must not block.
*
* \param[in] value Value.
*
*******************************************************************************
*/
typedef void (*vmk_HashValueAcquire)(vmk_HashValue value);
/*
*******************************************************************************
* vmk_HashValueRelease -- */ /**
*
* \brief Atomically release a reference to a value stored in the hash table.
*
* \note This function must not block.
*
* \param[in] value Value.
*
*******************************************************************************
*/
typedef void (*vmk_HashValueRelease)(vmk_HashValue value);
/**
* Properties for allocating a hash table.
*/
typedef struct vmk_HashProperties {
/** Module ID request the hash table */
vmk_ModuleID moduleID;
/** The heap used for hash table internal allocation */
vmk_HeapID heapID;
/** Type of keys to be used */
vmk_HashKeyType keyType;
/** Flags relating to keys */
vmk_HashKeyFlags keyFlags;
/**
* Key size:
*
* (1) must be 0 for VMK_HASH_KEY_TYPE_INT
* (2) maximum string length expected if VMK_HASH_KEY_TYPE_STR
* (3) opaque object size expected if VMK_HASH_KEY_TYPE_OPAQUE
*/
vmk_uint32 keySize;
/** A "best guess" number of expected entries for hash bucket sizing */
vmk_uint32 nbEntries;
/** Function to acquire a reference to a value */
vmk_HashValueAcquire acquire;
/** Function to release a reference to a value */
vmk_HashValueRelease release;
} vmk_HashProperties;
/*
*******************************************************************************
* vmk_HashGetAllocSize -- */ /**
*
* \brief Return a best estimate amount of memory necessary to operate the
* hash table.
*
* \param[in] nbEntries A "best guess" number of expected entries for hash
* buckets sizing.
*
* \retval Best estimate amount of memory in bytes.
*
*******************************************************************************
*/
vmk_ByteCount
vmk_HashGetAllocSize(vmk_uint32 nbEntries);
/*
*******************************************************************************
* vmk_HashAlloc -- */ /**
*
* \brief Allocate a new hash table with provided properties.
*
* \note vmk_HashRelease() needs to be called once done with the hash table.
*
* \note The hash table returned does not come with locking, it is the
* caller's responsibility to provide such mechanism. Lookups can be
* lockless, however, if the hash table has functions to atomically
* acquire and release references to values. Callers must provide locking
* for operations which insert or remove entries from the hash table.
*
* \param[in] props Properties for the new hash table.
* \param[out] hdl Hash handle allocated for later operations.
*
* \retval VMK_OK Hash table initialization was successful.
* \retval VMK_NO_MEMORY Allocation failure.
* \retval VMK_BAD_PARAM If hdl pointer equals to NULL.
* If props pointer equals to NULL.
* If hash properties are invalid.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashAlloc(vmk_HashProperties *props,
vmk_HashTable *hdl);
/*
*******************************************************************************
* vmk_HashRelease -- */ /**
*
* \brief Release a hash table.
*
* \note This function may block.
*
* \param[in] hdl Hash handle.
*
* \retval VMK_OK Hash table was released successful.
* \retval VMK_BUSY If the hash table is not empty.
* \retval VMK_BAD_PARAM If hdl equals to VMK_INVALID_HASH_HANDLE.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashRelease(vmk_HashTable hdl);
/*
*******************************************************************************
* vmk_HashDeleteAll -- */ /**
*
* \brief Delete every entry in a hash table.
*
* \note If the hash table does not have a value release function, the client
* should make sure that the right clean up is done beforehand.
*
* \note A subsequent call to vmk_HashIsEmpty() on the given hash table should
* return VMK_TRUE.
*
* \param[in] hdl Hash handle.
*
* \retval VMK_OK Every single entry of the hash table was deleted.
* \retval VMK_BAD_PARAM If hdl equals to VMK_INVALID_HASH_HANDLE.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashDeleteAll(vmk_HashTable hdl);
/*
*******************************************************************************
* vmk_HashKeysCount-- */ /**
*
* \brief Count the number of keys present in a given hash table.
*
* \param[in] hdl Hash handle.
* \param[out] keysCnt The number of keys in the hash table.
*
* \retval VMK_OK Hash table counting operation succeeded.
* \retval VMK_BAD_PARAM If hdl equals to VMK_INVALID_HASH_HANDLE or if keysCnt
* is NULL.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashKeysCount(vmk_HashTable hdl,
vmk_uint64 *keysCnt);
/*
*******************************************************************************
* vmk_HashIsEmpty -- */ /**
*
* \brief Check if a given hash table is empty.
*
* \param[in] hdl Hash handle.
*
* \retval VMK_TRUE Hash is empty.
* \retval VMK_FALSE Hash has at least one key-value pair.
*
*******************************************************************************
*/
vmk_Bool
vmk_HashIsEmpty(vmk_HashTable hdl);
/*
*******************************************************************************
* vmk_HashKeyIterator -- */ /**
*
* \brief Iterator used to iterate the key-value pairs on a given hash table.
*
* \note The return value is a command set given back to the iterator engine to
* let it know what to do next. It can be a binary union of any of the
* vmk_HashKeyIteratorCmd defined above.
*
* \note VMK_HASH_KEY_ITER_CMD_DELETE requires that the caller of
* vmk_HashKeyIterate() has the hash table locked.
*
* \param[in] hdl Hash handle.
* \param[in] key Key.
* \param[in] value Value.
* \param[in] data Private data passed while calling vmk_HashKeyIterate.
*
* \retval VMK_HASH_KEY_ITER_CMD_CONTINUE Move to the next key-value pair.
* \retval VMK_HASH_KEY_ITER_CMD_STOP Stop iterating.
* \retval VMK_HASH_KEY_ITER_CMD_DELETE Delete the current key-value pair.
*
*******************************************************************************
*/
typedef vmk_HashKeyIteratorCmd (*vmk_HashKeyIterator)(vmk_HashTable hdl,
vmk_HashKey key,
vmk_HashValue value,
vmk_AddrCookie data);
/*
*******************************************************************************
* vmk_HashKeyIterate -- */ /**
*
* \brief Iterate through the key-value pairs from a given hash table.
*
* \param[in] hdl Hash handle.
* \param[in] iterator Iterator callback.
* \param[in] data Private data passed to the iterator for each key-value
* pair.
*
* \retval VMK_OK Iterator went through the entire hash table or until
* stop command was issued.
* \retval VMK_BAD_PARAM If hdl equals to VMK_INVALID_HASH_HANDLE.
* If iterator equals to NULL.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashKeyIterate(vmk_HashTable hdl,
vmk_HashKeyIterator iterator,
vmk_AddrCookie data);
/*
*******************************************************************************
* vmk_HashKeyInsert -- */ /**
*
* \brief Insert a key-value pair into a given hash table.
*
* \note The key passed will be copied locally only if the flag
* VMK_HASH_KEY_FLAGS_LOCAL_COPY was passed while creating the hash.
*
* \note The value passed won't be copied, but if the hash has an acquire
* function, a new reference to the value will be acquired.
*
* \param[in] hdl Hash handle.
* \param[in] key Key.
* \param[in] value Value. A NULL value is valid.
*
* \retval VMK_OK Key-value pair insertion successful.
* \retval VMK_NO_MEMORY Allocation failure.
* \retval VMK_BAD_PARAM If hdl pointer equals to VMK_INVALID_HASH_HANDLE.
* If key equals to NULL on a string or opaque keys hash.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashKeyInsert(vmk_HashTable hdl,
vmk_HashKey key,
vmk_HashValue value);
/*
*******************************************************************************
* vmk_HashKeyUpdate -- */ /**
*
* \brief Update a key-value pair on a given hash table and return the previous
* associated value.
*
* \note The newValue passed won't be copied, but if the hash has an acquire
* function, a new reference to newValue will be acquired.
*
* \note If the hash has a release function, that function will be called
* asynchronously for the prior value.
*
* \param[in] hdl Hash handle.
* \param[in] key Key.
* \param[in] newValue Updated value. A NULL value is valid.
* \param[out] oldValue Value before update. A NULL value would mean that the
* caller is not interested in getting the previous
* associated value. If the caller is interested and
* the hash provides an acquire function, a new reference
* to the old value will be acquired.
*
* \retval VMK_OK Key-value pair update successful.
* \retval VMK_NOT_FOUND If there is no key-value pair matching the key
* parameter.
* \retval VMK_BAD_PARAM If hdl pointer equals to VMK_INVALID_HASH_HANDLE.
* If key equals to NULL on a string or opaque keys hash.
* \retval VMK_NO_MEMORY Allocation failure.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashKeyUpdate(vmk_HashTable hdl,
vmk_HashKey key,
vmk_HashValue newValue,
vmk_HashValue *oldValue);
/*
*******************************************************************************
* vmk_HashKeyDelete -- */ /**
*
* \brief Delete a key-value pair from a given hash table and return the current
* value.
*
* \note If the hash has a release function, that function will be called
* asynchronously for the removed value.
*
* \param[in] hdl Hash handle.
* \param[in] key Key.
* \param[out] value Value before remove. A NULL value would mean that the
* caller is not interested in getting the current
* associated value. If the caller is interested and
* the hash provides an acquire function, a new reference
* to the old value will be acquired.
*
* \retval VMK_OK Key-value pair removal successful.
* \retval VMK_NOT_FOUND If there is no key-value pair matching the key
* parameter.
* \retval VMK_BAD_PARAM If hdl pointer equals to VMK_INVALID_HASH_HANDLE.
* If key equals to NULL on a string or opaque keys hash.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashKeyDelete(vmk_HashTable hdl,
vmk_HashKey key,
vmk_HashValue *value);
/*
*******************************************************************************
* vmk_HashKeyFind -- */ /**
*
* \brief Find a key-value pair and return the current associated value.
*
* \param[in] hdl Hash handle.
* \param[in] key Key.
* \param[out] value Value associated to the key. A NULL value would mean
* that the caller is not interested in getting the current
* associated value. If the caller is interested in
* getting the current associated value, a new reference
* will be acquired if the hash has an acquire function.
*
* \retval VMK_OK Key-value pair found successfully.
* \retval VMK_NOT_FOUND If there is no key-value pair matching the key
* parameter.
* \retval VMK_BAD_PARAM If hdl pointer equals to VMK_INVALID_HASH_HANDLE.
* If key equals to NULL on a string or opaque keys hash.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashKeyFind(vmk_HashTable hdl,
vmk_HashKey key,
vmk_HashValue *value);
/*
*******************************************************************************
* vmk_HashBytes -- */ /**
*
* \brief Calculate 64 bit hash for an array of bytes.
*
* \note This API is not used as part of a hash table allocated with the
* vmk_HashAlloc() function. It is provided as a helper routine for
* callers that need to calculate hashes for their own purpose.
*
* \param[in] key Byte array pointer.
* \param[in] keySize Array Size in byte.
* \param[out] hash The calculated hash value.
*
* \retval VMK_OK Hash calculated successfully.
* \retval VMK_BAD_PARAM If key or hash is NULL, or keySize equal zero.
*
*******************************************************************************
*/
VMK_ReturnStatus
vmk_HashBytes(const vmk_uint8 *key,
vmk_uint32 keySize,
vmk_uint64 *hash);
#endif /* _VMKAPI_HASH_H_ */
/** @} */
/** @} */