/*
 * 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.
 */

/*
 * $Id$
 */

#if !defined(XERCESC_INCLUDE_GUARD_REFHASH2KEYSTABLEOF_HPP)
#define XERCESC_INCLUDE_GUARD_REFHASH2KEYSTABLEOF_HPP


#include <xercesc/util/Hashers.hpp>
#include <xercesc/util/IllegalArgumentException.hpp>
#include <xercesc/util/NoSuchElementException.hpp>
#include <xercesc/util/RuntimeException.hpp>
#include <xercesc/util/PlatformUtils.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// This hash table is similar to RefHashTableOf with an additional integer as key2

//  Forward declare the enumerator so it can be our friend.
//
template <class TVal, class THasher = StringHasher>
class RefHash2KeysTableOfEnumerator;

//
//  This should really be a nested class, but some of the compilers we
//  have to support cannot deal with that!
//
template <class TVal>
struct RefHash2KeysTableBucketElem
{
    RefHash2KeysTableBucketElem(void* key1, int key2, TVal* const value, RefHash2KeysTableBucketElem<TVal>* next)
		: fData(value), fNext(next), fKey1(key1), fKey2(key2)
        {
        }
    ~RefHash2KeysTableBucketElem() {};

    TVal*                                fData;
    RefHash2KeysTableBucketElem<TVal>*   fNext;
    void*                                fKey1;
    int                                  fKey2;

private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    RefHash2KeysTableBucketElem(const RefHash2KeysTableBucketElem<TVal>&);
    RefHash2KeysTableBucketElem<TVal>& operator=(const RefHash2KeysTableBucketElem<TVal>&);
};


template <class TVal, class THasher = StringHasher>
class RefHash2KeysTableOf : public XMemory
{
public:
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------

    RefHash2KeysTableOf(
      const XMLSize_t modulus,
      MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);

    RefHash2KeysTableOf(
      const XMLSize_t modulus,
      const THasher& hasher,
      MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);

    RefHash2KeysTableOf(
      const XMLSize_t modulus,
      const bool adoptElems,
      MemoryManager* const manager =  XMLPlatformUtils::fgMemoryManager);

    RefHash2KeysTableOf(
      const XMLSize_t modulus,
      const bool adoptElems,
      const THasher& hasher,
      MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);

    ~RefHash2KeysTableOf();


    // -----------------------------------------------------------------------
    //  Element management
    // -----------------------------------------------------------------------
    bool isEmpty() const;
    bool containsKey(const void* const key1, const int key2) const;
    void removeKey(const void* const key1, const int key2);
    void removeKey(const void* const key1);
    void removeAll();
    void transferElement(const void* const key1, void* key2);

    // -----------------------------------------------------------------------
    //  Getters
    // -----------------------------------------------------------------------
    TVal* get(const void* const key1, const int key2);
    const TVal* get(const void* const key1, const int key2) const;

    MemoryManager* getMemoryManager() const;
    XMLSize_t      getHashModulus()   const;

    // -----------------------------------------------------------------------
    //  Putters
    // -----------------------------------------------------------------------
	void put(void* key1, int key2, TVal* const valueToAdopt);

private :
    // -----------------------------------------------------------------------
    //  Declare our friends
    // -----------------------------------------------------------------------
    friend class RefHash2KeysTableOfEnumerator<TVal, THasher>;


private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    RefHash2KeysTableOf(const RefHash2KeysTableOf<TVal, THasher>&);
    RefHash2KeysTableOf<TVal>& operator=(const RefHash2KeysTableOf<TVal, THasher>&);

    // -----------------------------------------------------------------------
    //  Private methods
    // -----------------------------------------------------------------------
    RefHash2KeysTableBucketElem<TVal>* findBucketElem(const void* const key1, const int key2, XMLSize_t& hashVal);
    const RefHash2KeysTableBucketElem<TVal>* findBucketElem(const void* const key1, const int key2, XMLSize_t& hashVal) const;
    void initialize(const XMLSize_t modulus);
    void rehash();


    // -----------------------------------------------------------------------
    //  Data members
    //
    //  fAdoptedElems
    //      Indicates whether the values added are adopted or just referenced.
    //      If adopted, then they are deleted when they are removed from the
    //      hash table.
    //
    //  fBucketList
    //      This is the array that contains the heads of all of the list
    //      buckets, one for each possible hash value.
    //
    //  fHashModulus
    //      The modulus used for this hash table, to hash the keys. This is
    //      also the number of elements in the bucket list.
    //
    //  fCount
    //      The number of elements currently in the map
    //
    //  fHash
    //      The hasher for the key1 data type.
    // -----------------------------------------------------------------------
    MemoryManager*                      fMemoryManager;
    bool                                fAdoptedElems;
    RefHash2KeysTableBucketElem<TVal>** fBucketList;
    XMLSize_t                           fHashModulus;
    XMLSize_t                           fCount;
    THasher                             fHasher;
};



//
//  An enumerator for a value array. It derives from the basic enumerator
//  class, so that value vectors can be generically enumerated.
//
template <class TVal, class THasher>
class RefHash2KeysTableOfEnumerator : public XMLEnumerator<TVal>, public XMemory
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    RefHash2KeysTableOfEnumerator(RefHash2KeysTableOf<TVal, THasher>* const toEnum
                                  , const bool adopt = false
                                  , MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    virtual ~RefHash2KeysTableOfEnumerator();


    // -----------------------------------------------------------------------
    //  Enum interface
    // -----------------------------------------------------------------------
    bool hasMoreElements() const;
    TVal& nextElement();
    void Reset();

    // -----------------------------------------------------------------------
    //  New interface
    // -----------------------------------------------------------------------
    void nextElementKey(void*&, int&);
    void setPrimaryKey(const void* key);

private :
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    RefHash2KeysTableOfEnumerator(const RefHash2KeysTableOfEnumerator<TVal, THasher>&);
    RefHash2KeysTableOfEnumerator<TVal, THasher>& operator=(const RefHash2KeysTableOfEnumerator<TVal, THasher>&);

    // -----------------------------------------------------------------------
    //  Private methods
    // -----------------------------------------------------------------------
    void findNext();


    // -----------------------------------------------------------------------
    //  Data Members
    //
    //  fAdopted
    //      Indicates whether we have adopted the passed vector. If so then
    //      we delete the vector when we are destroyed.
    //
    //  fCurElem
    //      This is the current bucket bucket element that we are on.
    //
    //  fCurHash
    //      The is the current hash buck that we are working on. Once we hit
    //      the end of the bucket that fCurElem is in, then we have to start
    //      working this one up to the next non-empty bucket.
    //
    //  fToEnum
    //      The value array being enumerated.
    //
    //  fLockPrimaryKey
    //      Indicates that we are requested to iterate over the secondary keys
    //      associated with the given primary key
    //
    // -----------------------------------------------------------------------
    bool                                    fAdopted;
    RefHash2KeysTableBucketElem<TVal>*      fCurElem;
    XMLSize_t                               fCurHash;
    RefHash2KeysTableOf<TVal, THasher>*     fToEnum;
    MemoryManager* const                    fMemoryManager;
    const void*                             fLockPrimaryKey;
};

XERCES_CPP_NAMESPACE_END

#if !defined(XERCES_TMPLSINC)
#include <xercesc/util/RefHash2KeysTableOf.c>
#endif

#endif
