/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#if !defined(XALANDOMSTRINGHASHTABLE_HEADER_GUARD_1357924680)
#define XALANDOMSTRINGHASHTABLE_HEADER_GUARD_1357924680



// Base include file.  Must be first.
#include <xalanc/PlatformSupport/PlatformSupportDefinitions.hpp>



#include <xalanc/Include/XalanVector.hpp>



#include <xalanc/XalanDOM/XalanDOMString.hpp>



namespace XALAN_CPP_NAMESPACE {



class XALAN_PLATFORMSUPPORT_EXPORT XalanDOMStringHashTable
{
public:

    typedef XalanVector<const XalanDOMString*>  BucketType;
    typedef BucketType::size_type               bucket_size_type;
    typedef XalanVector<bucket_size_type>       BucketCountsType;
    typedef ExplicitMemoryManagedConstructionTraits<BucketType>     ConstructionTraits;
    typedef XalanVector<BucketType, ConstructionTraits>     BucketVectorType;

    enum { eDefaultBucketCount = 101, eDefaultBucketSize = 15 };


    /**
     * Create a hash table.
     *
     * @param theBucketCount The number of buckets to use for the hash table.  This should be a prime number for best results.
     * @param theBucketSize The initial size of each bucket in the hash table.
     */
    explicit
    XalanDOMStringHashTable(
            MemoryManager&  theManager,
            size_t              theBucketCount = eDefaultBucketCount,
            bucket_size_type    theBucketSize = eDefaultBucketSize);

    ~XalanDOMStringHashTable() { }

    /**
     * Clear the hash table.
     */
    void
    clear();

    /**
     * Get the number of strings in the table
     *
     * @return The number of strings in the table
     */
    size_t
    size() const
    {
        return m_count;
    }

    /**
     * Get the number of buckets in the table
     *
     * @return The number of buckets in the table
     */
    size_t
    bucketCount() const
    {
        return m_bucketCount;
    }

    /**
     * Get the size of each of the buckets in the table
     *
     * @param A vector to return the bucket counts.
     */
    void
    getBucketCounts(BucketCountsType&   theVector) const;

    /**
     * Get the collision count.  Release builds will always
     * return 0.
     *
     * @return The number of collisions.  Valid only for non-release builds.
     */
    size_t
    collisions() const
    {
        return m_collisions;
    }

    /**
     * Find a string.  If the string is not found, return null.
     *
     * @param theString The string to find.
     * @param theBucketIndex The index of the bucket for the string.
     * @return a pointer to the string, or null if not found.
     */
    const XalanDOMString*
    find(
            const XalanDOMString&   theString,
            size_t*                 theBucketIndex = 0) const;

    /**
     * Find a string.  If the string is not found, return null.
     * If theBucketIndex is not null, the variable pointed to
     * will be updated with the bucket index that was calculated
     * for the string.  This index can be used in a later call to
     * insert() to avoid recalculating the index.
     *
     * @param theString The string to find.
     * @param theLength The number of characters in the string.
     * @param theBucketIndex A pointer to a parameter to get the bucket index
     * @return a pointer to the string, or null if not found.
     */
    const XalanDOMString*
    find(
            const XalanDOMChar*         theString,
            XalanDOMString::size_type   theLength = XalanDOMString::npos,
            size_t*                     theBucketIndex = 0) const;

    /**
     * Insert a pointer to a string into the table.  If the string
     * is already present, the string will still be added, but it
     * will never be found, since it will be placed after the identical
     * string.
     *
     * Note that this class only stores a _pointer_ to a XalanDOMString.
     * It's expected that the string will be allocated and managed outside
     * of the hash table.
     *
     * @param theString The string to insert.
     */
    void
    insert(const XalanDOMString&    theString);

    /**
     * Insert a pointer to a string into the table.  If the string
     * is already present, the string will still be added, but it
     * will never be found, since it will be placed after the identical
     * string.  theBucketIndex _must_ be the index returned from a
     * previous call to find.  If not, then the behavior is undefined.
     * This is meant as an optimization to avoid re-hashing the string.
     *
     * Note that this class only stores a _pointer_ to a XalanDOMString.
     * It's expected that the string will be allocated and managed outside
     * of the hash table.
     *
     * @param theString The string to insert.
     * @param theBucketIndex The index of the bucket for the string.
     */
    void
    insert(
            const XalanDOMString&   theString,
            size_t                  theBucketIndex);

    MemoryManager&
    getMemoryManager()
    {
        return m_buckets.getMemoryManager();
    }

    const MemoryManager&
    getMemoryManager() const
    {
        return m_buckets.getMemoryManager();
    }

private:

    // Not implemented, for now...
    XalanDOMStringHashTable(const XalanDOMStringHashTable&);

    XalanDOMStringHashTable&
    operator=(const XalanDOMStringHashTable&);

    bool
    operator==(const XalanDOMStringHashTable&) const;


    // Data members...
    const size_t            m_bucketCount;

    const bucket_size_type  m_bucketSize;

    BucketVectorType        m_buckets;

    size_t                  m_count;

    size_t                  m_collisions;       
};



}



#endif  // !defined(XALANDOMSTRINGPOOL_HEADER_GUARD_1357924680)
