/*

    ========== 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_CONTAINERDICTIONARY_HPP
#define __OMS_CONTAINERDICTIONARY_HPP

#include "Oms/OMS_IGuidHash.hpp"
#include "ggg00.h"

class OMS_ClassInfo;
class OMS_ContainerInfo;
class OMS_DumpInterface;
class OMS_ContainerDictionary;

class OMS_ContainerDictionaryIterator {
  OMS_ContainerDictionary* m_clsDir;
  int                      m_index;
  OMS_ContainerInfo*       m_curr;
public :
  OMS_ContainerDictionaryIterator() : m_clsDir(NULL), m_index(0), m_curr(NULL) {}
  OMS_ContainerDictionaryIterator(OMS_ContainerDictionary*);
  void reset(OMS_ContainerDictionary*);
  void operator++();
  inline operator bool() const;
  inline OMS_ContainerInfo* operator()() const;
};

/// Global Dictionary for classes and containers
class OMS_ContainerDictionary : public OMS_IGuidHash {
  enum { MaxHeadEntries = 2013 };
  /*! This counter is used to synchronize the local container dictionaries with the global 
  ** dictionary. This counter is increased every time a global container info is dropped. 
  ** Every context has a member OMS_Context::m_lastDropId and if the value of this 
  ** member is smaller than this member, then there is a inconsistency and a method to 
  ** synchronize the local dictionary is started */
  tsp00_Uint4         m_dropId;
  /*! Hash array with pointers to the global class information. The class guid is used to 
  ** compute the hash value */
  OMS_ClassInfo*      m_classInfoHead[MaxHeadEntries];
  /*! Hash array with pointers to the global container information. The container handle is 
  ** used to compute the hash value. (see also OMS_ContainerDictionary::m_guidHead) */
  OMS_ContainerInfo* m_clsidHead[MaxHeadEntries];
  /*! Hash array with pointers to the global container information. The GUID, the schema, 
  ** and the container number are used to compute the hash value.  
  ** (see also OMS_ContainerDictionary::m_clsidHead).*/
  OMS_ContainerInfo* m_guidHead [MaxHeadEntries];

  OMS_ClassInfo*     FindGuid (const ClassIDRef guid); 
  OMS_ContainerInfo* FindGuid (const ClassIDRef guid, OmsSchemaHandle sh, OmsContainerNo cno);
  void                Insert   (OMS_ContainerInfo* pClassInfo);
  void                Init();
public :

  OMS_ContainerDictionary();
  void                Delete (IliveCacheSink* lcSink, OMS_ContainerInfo* pContainerInfo);
  tgg00_BasisError    DropContainer          (IliveCacheSink* lcSink, const ClassIDRef guid, OmsSchemaHandle Schema, OmsContainerNo cno, size_t arrayByteSize);
  tgg00_BasisError    DropSchema             (IliveCacheSink* lcSink, OmsSchemaHandle Schema);
  void                Dump                   (OMS_DumpInterface& dumpObj);
  OMS_ClassInfo*     FindGuid               (IliveCacheSink* lcSink, const ClassIDRef guid); 
  OMS_ContainerInfo* FindViaContainerHandle (IliveCacheSink* lcSink, tsp00_Uint4 containerHandle);
  tsp00_Uint4         GetLastDropId() const  { return m_dropId; }
  OMS_ContainerInfo* FindViaGuid (IliveCacheSink* lcSink, const ClassIDRef guid, OmsSchemaHandle sh, OmsContainerNo cno);
  void               MarkDropped (const ClassIDRef guid, OmsSchemaHandle sh, OmsContainerNo cno); // PTS 1134184
  OMS_ClassInfo* RegisterClass (IliveCacheSink* lcSink, 
    const char* ClassName,
    const ClassIDRef guid,
    const ClassIDPtr pBaseClass,
    tsp00_Int4      keyPos,            // PTS 1122540
    tsp00_Int4      keyLen,            // PTS 1122540
    bool            paritionedKey,     // PTS 1122540
    size_t ObjectSize, 
    void* vtptr);
  OMS_ContainerInfo* RegisterContainer (IliveCacheSink* lcSink, 
    const ClassIDRef guid, 
    const char* ClassName, 
    size_t PersistentSize, 
    size_t ObjectSize, 
    const ClassIDPtr pBaseClass,
    tsp00_Int4      keyPos,            // PTS 1122540
    tsp00_Int4      keyLen,            // PTS 1122540
    bool            paritionedKey,     // PTS 1122540
    OmsSchemaHandle sh,
    OmsContainerNo cno,
    void* vtptr,
    size_t arrayByteSize = 0);

  void ReleaseContainerInfo(IliveCacheSink* lcSink, OMS_ContainerInfo*);
  void Shutdown();
  friend class OMS_ContainerDictionaryIterator;
};

/*----------------------------------------------------------------------------------*/

inline OMS_ContainerDictionaryIterator::operator bool() const {
  return (NULL != m_curr);
}

/*----------------------------------------------------------------------------------*/

inline OMS_ContainerInfo* OMS_ContainerDictionaryIterator::operator()() const {
  return m_curr;
}

#endif // __OMS_CONTAINERDICTIONARY_HPP
