/*

    ========== licence begin  GPL
    Copyright (c) 2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end

*/
#ifndef __OMS_CLASSIDHASHDEF_HPP
#define __OMS_CLASSIDHASHDEF_HPP

#include "Oms/OMS_ClassHash.hpp"

class OMS_DumpInterface;
class OMS_Context;
class OMS_ClassIdEntry;

/// Local container dictionary
class OMS_ClassIdHash : public OMS_IGuidHash {
  /*! Size of the hash array. (starts with  HEAD_ENTRIES = 257) */
  tsp00_Int4            headentries;
  /*! number of containers registered in local container directory */
  tsp00_Int4            m_count;
  /*! Hash array with pointers to the container entries which uses the container handle 
  ** to compute the hash value. */
  OMS_ClassIdEntry**    m_clsidHead;
  /*! Hash array with pointers to the container entries which uses the GUID, the schema, 
  ** and the container number to compute the hash value. */
  OMS_ClassIdEntry**    m_guidHead;
  /*! Starting point of a list with the headers for free-lists. For each size of object 
  ** container a header is inserted into this list and below of this header all free 
  ** object containers are linked. As the size of the object container is different for 
  ** objects which are created in a version and those which are created in a normal context, 
  ** there might be two headers per class. If several classes have the same size, then they 
  ** use a shared free-list. */
  OMS_FreeListHeader* freeListHeader;
  /*! Backward-pointer to the context, in which the instance was created */
  OMS_Context*      m_context;
  /*! A directory with local information about the classes and a pointer the corresponding
  ** global information. (In contrast to the class container entries, instanzes of classes
  ** which are assoziated with different containers or schemas are not distinguished) */
  OMS_ClassHash       m_classDir;

public:
  class Iter {
    friend class OMS_ClassIdHash;
    OMS_ClassIdHash*    hash;
    long                headIndex;
    OMS_ClassIdEntry*   curr;
  public :
    inline Iter(OMS_ClassIdHash*);
    inline Iter(const Iter&);
    inline void operator++();
    inline operator bool() const;
    inline OMS_ClassIdEntry* operator()() const;
  };
  OMS_ClassIdHash  ();
  ~OMS_ClassIdHash ();
  OMS_ClassIdEntry*        AutoRegister (const ClassIDRef guid, OmsSchemaHandle sh, OmsContainerNo ContainerNo);
  OMS_ClassIdEntry*        AutoRegisterForReg (const ClassIDRef guid, OmsSchemaHandle sh, OmsContainerNo ContainerNo);
  inline bool              CheckIfNotDropped(OMS_ClassIdEntry* curr, bool excsafe = false);
  void                     Clean();                    
  void                     Create(OMS_Context* context);
  void                     Dump(OMS_DumpInterface& dumpObj) const;
  inline Iter              First ();
  inline OMS_GuidEntry*    GetClassInfo(const ClassIDRef guid);
  inline void              HashInsert (OMS_ClassIdEntry* h);
  inline OMS_ClassIdEntry* HashFindViaContainerHandle (tsp00_Uint4 containerHandle, bool checkExistence = true, bool excsafe = false);
  inline OMS_ClassIdEntry* HashFind   (const ClassIDRef k, OmsSchemaHandle, OmsContainerNo);
  inline OMS_ClassIdEntry* HashFindForReg   (const ClassIDRef k, OmsSchemaHandle, OmsContainerNo);
  void                     HashDelete (OMS_ClassIdEntry* containerInfo);
  void                     HashDelete_Slow (OMS_ClassIdEntry* containerInfo);
  bool                     IsBaseClassOf(const ClassIDRef, const ClassIDRef);
  bool                     IsDerivedClassOf(const ClassIDRef , const ClassIDRef);
  void                     ClearCachedKeys(OMS_Context*);    // PTS 1117571
  inline void              ClearFreeLists(int caller);
  OMS_FreeListHeader*      GetFreeListHeader(size_t size);
  void                     Resize();
  void                     ThrowUnknownContainer(OMS_ClassIdEntry*);
  void                     ThrowUnknownContainer(const ClassIDRef guid, OmsSchemaHandle Schema, OmsContainerNo ContainerNo);
  void                     UnregisterAll(); /* PTS 1110149 */
  friend class OMS_ClassIdHash::Iter;
};

#endif // __OMS_CLASSIDHASHDEF_HPP