/**
 * @file ethHash.c
 *
 * @brief Hashtable implementation
 * 
 * @par
 * IXP400 SW Release version 2.0
 * 
 * -- Copyright Notice --
 * 
 * @par
 * Copyright 2001-2005, Intel Corporation.
 * All rights reserved.
 * 
 * @par
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Intel Corporation nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * @par
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * @par
 * -- End of Copyright Notice --
 */


#include "IxEthDB_p.h"
#include "IxEthDBLocks_p.h"

/**
 * @addtogroup EthDB
 *
 * @{
 */

/**
 * @brief initializes a hash table object
 *
 * @param hashTable uninitialized hash table structure
 * @param numBuckets number of buckets to use
 * @param entryHashFunction hash function used 
 * to hash entire hash node data block (for adding)
 * @param matchFunctions array of match functions, indexed on type,
 * used to differentiate records with the same hash value
 * @param freeFunction function used to free node data blocks
 *
 * Initializes the given hash table object.
 *
 * @internal
 */
void ixEthDBInitHash(HashTable *hashTable, 
                     UINT32 numBuckets, 
                     HashFunction entryHashFunction, 
                     MatchFunction *matchFunctions, 
                     FreeFunction freeFunction)
{
    UINT32 bucketIndex;
    UINT32 hashSize = numBuckets * sizeof(HashNode *);

    /* entry hashing, matching and freeing methods */
    hashTable->entryHashFunction  = entryHashFunction;
    hashTable->matchFunctions     = matchFunctions;
    hashTable->freeFunction       = freeFunction;

    /* buckets */
    hashTable->numBuckets = numBuckets;

    /* set to 0 all buckets */
    memset(hashTable->hashBuckets, 0, hashSize);

    /* init bucket locks - note that initially all mutexes are unlocked after MutexInit()*/
    for (bucketIndex = 0 ; bucketIndex < numBuckets ; bucketIndex++)
    {
        ixOsalFastMutexInit(&hashTable->bucketLocks[bucketIndex]);
    }
}

/**
 * @brief adds an entry to the hash table
 *
 * @param hashTable hash table to add the entry to
 * @param entry entry to add
 *
 * The entry will be hashed using the entry hashing function and added to the
 * hash table, unless a locking blockage occurs, in which case the caller
 * should retry.
 *
 * @retval IX_ETH_DB_SUCCESS if adding <i>entry</i> has succeeded
 * @retval IX_ETH_DB_NOMEM if there's no memory left in the hash node pool
 * @retval IX_ETH_DB_BUSY if there's a locking failure on the insertion path
 *
 * @internal
 */
IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry)
{
    UINT32 hashValue   = hashTable->entryHashFunction(entry);
    UINT32 bucketIndex = hashValue % hashTable->numBuckets;
    HashNode *bucket   = hashTable->hashBuckets[bucketIndex];
    HashNode *newNode;

    LockStack locks;

    INIT_STACK(&locks);

    /* lock bucket */
    PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);

    /* lock insertion element (first in chain), if any */
    if (bucket != NULL)
    {
        PUSH_LOCK(&locks, &bucket->lock);
    }

    /* get new node */
    newNode = ixEthDBAllocHashNode();

    if (newNode == NULL)
    {
        /* unlock everything */
        UNROLL_STACK(&locks);

        return IX_ETH_DB_NOMEM;
    }

    /* init lock - note that mutexes are unlocked after MutexInit */
    ixOsalFastMutexInit(&newNode->lock);

    /* populate new link */
    newNode->data = entry;

    /* add to bucket */
    newNode->next                       = bucket;
    hashTable->hashBuckets[bucketIndex] = newNode;

    /* unlock bucket and insertion point */
    UNROLL_STACK(&locks);

    return IX_ETH_DB_SUCCESS;
}

/**
 * @brief removes an entry from the hashtable
 *
 * @param hashTable hash table to remove entry from
 * @param keyType type of record key used for matching
 * @param reference reference key used to identify the entry
 *
 * The reference key will be hashed using the key hashing function,
 * the entry is searched using the hashed value and then examined
 * against the reference entry using the match function. A positive
 * match will trigger the deletion of the entry.
 * Locking failures are reported and the caller should retry.
 *
 * @retval IX_ETH_DB_SUCCESS if the removal was successful
 * @retval IX_ETH_DB_NO_SUCH_ADDR if the entry was not found
 * @retval IX_ETH_DB_BUSY if a locking failure occured during the process
 *
 * @internal
 */
IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference)
{
    UINT32 hashValue       = hashTable->entryHashFunction(reference);
    UINT32 bucketIndex     = hashValue % hashTable->numBuckets;
    HashNode *node         = hashTable->hashBuckets[bucketIndex];
    HashNode *previousNode = NULL;
    
    LockStack locks;

    INIT_STACK(&locks);

    while (node != NULL)
    {
        /* try to lock node */
        PUSH_LOCK(&locks, &node->lock);

        if (hashTable->matchFunctions[keyType](reference, node->data))
        {
            /* found entry */
            if (node->next != NULL)
            {
                PUSH_LOCK(&locks, &node->next->lock);
            }

            if (previousNode == NULL)
            {
                /* node is head of chain */
                PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);

                hashTable->hashBuckets[bucketIndex] = node->next;

                POP_LOCK(&locks);
            }
            else
            {
                /* relink */
                previousNode->next = node->next;
            }

            UNROLL_STACK(&locks);

            /* free node */
            hashTable->freeFunction(node->data);
            ixEthDBFreeHashNode(node);

            return IX_ETH_DB_SUCCESS;
        }
        else
        {
            if (previousNode != NULL)
            {
                /* unlock previous node */
                SHIFT_STACK(&locks);
            }

            /* advance to next element in chain */
            previousNode = node;
            node         = node->next;
        }
    }

    UNROLL_STACK(&locks);

    /* not found */
    return IX_ETH_DB_NO_SUCH_ADDR;
}

/**
 * @brief retrieves an entry from the hash table
 *
 * @param hashTable hash table to perform the search into
 * @param reference search key (a MAC address)
 * @param keyType type of record key used for matching
 * @param searchResult pointer where a reference to the located hash node 
 * is placed
 *
 * Searches the entry with the same key as <i>reference</i> and places the
 * pointer to the resulting node in <i>searchResult</i>.
 * An implicit write access lock is granted after a search, which gives the 
 * caller the opportunity to modify the entry.
 * Access should be released as soon as possible using @ref ixEthDBReleaseHashNode().
 *
 * @see ixEthDBReleaseHashNode()
 *
 * @retval IX_ETH_DB_SUCCESS if the search was completed successfully
 * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
 * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
 * the caller should retry
 *
 * @warning unless the return value is <b>IX_ETH_DB_SUCCESS</b> the searchResult
 * location is NOT modified and therefore using a NULL comparison test when the
 * value was not properly initialized would be an error
 *
 * @internal
 */
IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult)
{
    UINT32 hashValue;
    HashNode *node;

    hashValue = hashTable->entryHashFunction(reference);
    node      = hashTable->hashBuckets[hashValue % hashTable->numBuckets];

    while (node != NULL)
    {
        TRY_LOCK(&node->lock);

        if (hashTable->matchFunctions[keyType](reference, node->data))
        {
            *searchResult = node;

            return IX_ETH_DB_SUCCESS;
        }
        else
        {
            UNLOCK(&node->lock);

            node = node->next;
        }
    }

    /* not found */
    return IX_ETH_DB_NO_SUCH_ADDR;
}

/**
 * @brief reports the existence of an entry in the hash table
 *
 * @param hashTable hash table to perform the search into
 * @param reference search key (a MAC address)
 * @param keyType type of record key used for matching
 *
 * Searches the entry with the same key as <i>reference</i>.
 * No implicit write access lock is granted after a search, hence the 
 * caller cannot access or modify the entry. The result is only temporary.
 *
 * @see ixEthDBReleaseHashNode()
 *
 * @retval IX_ETH_DB_SUCCESS if the search was completed successfully
 * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
 * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
 * the caller should retry
 *
 * @internal
 */
IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference)
{
    UINT32 hashValue;
    HashNode *node;

    hashValue = hashTable->entryHashFunction(reference);
    node      = hashTable->hashBuckets[hashValue % hashTable->numBuckets];

    while (node != NULL)
    {
        TRY_LOCK(&node->lock);

        if (hashTable->matchFunctions[keyType](reference, node->data))
        {
            UNLOCK(&node->lock);

            return IX_ETH_DB_SUCCESS;
        }
        else
        {
            UNLOCK(&node->lock);

            node = node->next;
        }
    }

    /* not found */
    return IX_ETH_DB_NO_SUCH_ADDR;
}

/**
 * @brief releases the write access lock
 *
 * @pre the node should have been obtained via @ref ixEthDBSearchHashEntry()
 *
 * @see ixEthDBSearchHashEntry()
 *
 * @internal
 */
void ixEthDBReleaseHashNode(HashNode *node)
{
    UNLOCK(&node->lock);
}

/**
 * @brief initializes a hash iterator
 *
 * @param hashTable hash table to be iterated
 * @param iterator iterator object
 *
 * If the initialization is successful the iterator will point to the
 * first hash table record (if any).
 * Testing if the iterator has not passed the end of the table should be
 * done using the IS_ITERATOR_VALID(iteratorPtr) macro.
 * An implicit write access lock is granted on the entry pointed by the iterator.
 * The access is automatically revoked when the iterator is incremented.
 * If the caller decides to terminate the iteration before the end of the table is
 * passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
 * must be called.
 *
 * @see ixEthDBReleaseHashIterator()
 *
 * @retval IX_ETH_DB_SUCCESS if initialization was successful and the iterator points
 * to the first valid table node
 * @retval IX_ETH_DB_FAIL if the table is empty
 * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
 * should retry
 *
 * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
 * might place the database in a permanent invalid lock state
 *
 * @internal
 */
IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator)
{
    iterator->bucketIndex  = 0;
    iterator->node         = NULL;
    iterator->previousNode = NULL;

    return ixEthDBIncrementHashIterator(hashTable, iterator);
}

/**
 * @brief releases the write access locks of the iterator nodes
 *
 * @warning use of this function is required only when the caller terminates an iteration
 * before reaching the end of the table
 *
 * @see ixEthDBInitHashIterator()
 * @see ixEthDBIncrementHashIterator()
 *
 * @param iterator iterator whose node(s) should be unlocked
 *
 * @internal
 */
void ixEthDBReleaseHashIterator(HashIterator *iterator)
{
    if (iterator->previousNode != NULL)
    {
        UNLOCK(&iterator->previousNode->lock);
    }

    if (iterator->node != NULL)
    {
        UNLOCK(&iterator->node->lock);
    }
}

/**
 * @brief incremenents an iterator so that it points to the next valid entry of the table
 * (if any)
 *
 * @param hashTable hash table to iterate
 * @param iterator iterator object
 *
 * @pre the iterator object must be initialized using @ref ixEthDBInitHashIterator()
 *
 * If the increment operation is successful the iterator will point to the
 * next hash table record (if any).
 * Testing if the iterator has not passed the end of the table should be
 * done using the IS_ITERATOR_VALID(iteratorPtr) macro.
 * An implicit write access lock is granted on the entry pointed by the iterator.
 * The access is automatically revoked when the iterator is re-incremented.
 * If the caller decides to terminate the iteration before the end of the table is
 * passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
 * must be called.
 * Is is guaranteed that no other thread can remove or change the iterated entry until
 * the iterator is incremented successfully.
 *
 * @see ixEthDBReleaseHashIterator()
 *
 * @retval IX_ETH_DB_SUCCESS if the operation was successful and the iterator points
 * to the next valid table node
 * @retval IX_ETH_DB_FAIL if the iterator has passed the end of the table
 * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
 * should retry
 *
 * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
 * might place the database in a permanent invalid lock state
 *
 * @internal
 */
IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator)
{
    /* unless iterator is just initialized... */
    if (iterator->node != NULL)
    {
        /* try next in chain */
        if (iterator->node->next != NULL)
        {
            TRY_LOCK(&iterator->node->next->lock);

            if (iterator->previousNode != NULL)
            {
                UNLOCK(&iterator->previousNode->lock);
            }

            iterator->previousNode = iterator->node;
            iterator->node         = iterator->node->next;

            return IX_ETH_DB_SUCCESS;
        }
        else
        {
            /* last in chain, prepare for next bucket */
            iterator->bucketIndex++;
        }
    }

   /* try next used bucket */
    for (; iterator->bucketIndex < hashTable->numBuckets ; iterator->bucketIndex++)
    {
        HashNode **nodePtr = &(hashTable->hashBuckets[iterator->bucketIndex]);
        HashNode *node = *nodePtr;
#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince)
        if (((iterator->bucketIndex & IX_ETHDB_BUCKET_INDEX_MASK) == 0) &&
            (iterator->bucketIndex < (hashTable->numBuckets - IX_ETHDB_BUCKETPTR_AHEAD)))
        {
            /* preload next cache line (2 cache line ahead) */
            nodePtr += IX_ETHDB_BUCKETPTR_AHEAD;
            __asm__ ("pld [%0];\n": : "r" (nodePtr));
        }
#endif
        if (node != NULL)
        {
            TRY_LOCK(&node->lock);

            /* unlock last one or two nodes in the previous chain */
            if (iterator->node != NULL)
            {
                UNLOCK(&iterator->node->lock);

                if (iterator->previousNode != NULL)
                {
                    UNLOCK(&iterator->previousNode->lock);
                }
            }
            
            /* redirect iterator */
            iterator->previousNode = NULL;
            iterator->node         = node;

            return IX_ETH_DB_SUCCESS;
        }
    }

    /* could not advance iterator */
    if (iterator->node != NULL)
    {
        UNLOCK(&iterator->node->lock);

        if (iterator->previousNode != NULL)
        {
            UNLOCK(&iterator->previousNode->lock);
        }

        iterator->node = NULL;
    }

    return IX_ETH_DB_END;
}

/**
 * @brief removes an entry pointed by an iterator
 *
 * @param hashTable iterated hash table
 * @param iterator iterator object
 *
 * Removes the entry currently pointed by the iterator and repositions the iterator
 * on the next valid entry (if any). Handles locking issues automatically and
 * implicitely grants write access lock to the new pointed entry.
 * Failures due to concurrent threads having write access locks in the same region
 * preserve the state of the database and the iterator object, leaving the caller
 * free to retry without loss of access. It is guaranteed that only the thread owning
 * the iterator can remove the object pointed by the iterator.
 *
 * @retval IX_ETH_DB_SUCCESS if removal has succeeded
 * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
 * should retry
 *
 * @internal
 */
IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator)
{
    HashIterator nextIteratorPos;
    LockStack locks;

    INIT_STACK(&locks);

    /* set initial bucket index for next position */
    nextIteratorPos.bucketIndex = iterator->bucketIndex;

    /* compute iterator position before removing anything and lock ahead */
    if (iterator->node->next != NULL)
    {
        PUSH_LOCK(&locks, &iterator->node->next->lock);

        /* reposition on the next node in the chain */
        nextIteratorPos.node         = iterator->node->next;
        nextIteratorPos.previousNode = iterator->previousNode;
    }
    else
    {
        /* try next chain - don't know yet if we'll find anything */
        nextIteratorPos.node = NULL;

        /* if we find something it's a chain head */
        nextIteratorPos.previousNode = NULL;

        /* browse up in the buckets to find a non-null chain */
        while (++nextIteratorPos.bucketIndex < hashTable->numBuckets)
        {
            nextIteratorPos.node = hashTable->hashBuckets[nextIteratorPos.bucketIndex];

            if (nextIteratorPos.node != NULL)
            {
                /* found a non-empty chain, try to lock head */
                PUSH_LOCK(&locks, &nextIteratorPos.node->lock);

                break;
            }
        }
    }

    /* restore links over the to-be-deleted item */
    if (iterator->previousNode == NULL)
    {
        /* first in chain, lock bucket */
        PUSH_LOCK(&locks, &hashTable->bucketLocks[iterator->bucketIndex]);

        hashTable->hashBuckets[iterator->bucketIndex] = iterator->node->next;

        POP_LOCK(&locks);
    }
    else
    {
        /* relink */
        iterator->previousNode->next = iterator->node->next;

        /* unlock last remaining node in current chain when moving between chains */
        if (iterator->node->next == NULL)
        {
            UNLOCK(&iterator->previousNode->lock);
        }
    }

    /* delete entry */
    hashTable->freeFunction(iterator->node->data);
    ixEthDBFreeHashNode(iterator->node);

    /* reposition iterator */
    *iterator = nextIteratorPos;

    return IX_ETH_DB_SUCCESS;
}

/**
 * @}
 */
