/*

    ========== 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_CONTAINERINFO_HPP
#define __OMS_CONTAINERINFO_HPP

#include "ggg01.h"
#include "Oms/OMS_Defines.h"
#include "Oms/OMS_GUID.hpp"
#include "Oms/OMS_ClassInfo.hpp"
#include "Oms/OMS_Trace.hpp"
#include "Oms/OMS_SinkCriticalSection.hpp"

const GUID OMS_VAR_OBJ_GUID_DEF = { 0x8fb0963d, 0xe5aa, 0x11d1, { 0xa9, 0x5c, 0x0, 0xa0, 0xc9, 0x43, 0x7, 0x31 } };
#ifdef	LIVECACHE_INTGUIDS
const ClassID OMS_VAR_OBJ_GUID  = -1;
#else
#define OMS_VAR_OBJ_GUID OMS_VAR_OBJ_GUID_DEF
#endif

class OMS_ContainerInfo;

class OMS_ContainerDumpInfo 
{
public:
  void*                m_addr;
  OMS_ContainerInfo*   m_clsidHashNext;
  OMS_ContainerInfo*   m_guidHashNext;
  OMS_ClassInfo*       m_clsInfo;
  tsp00_Int4           m_ContainerNo;
  tsp00_Int4           m_schema;
  tsp00_Int4           m_PersistentSize;
  short                m_refCnt;
  bool                 m_dropped;
  bool                 m_filler;
  tgg01_ContainerId    m_ContainerId;
};


/// Entry (containing container information) of the global container dictionary
class OMS_ContainerInfo {
public:
  int  m_eyeCatcher;

  /*! Pointer to link together entries which belong to the same hash value 
  ** (see OMS_ContainerDictionary::m_clsidHead) */
  OMS_ContainerInfo*  m_clsidHashNext;
  /*! Pointer to link together entries which belong to the same hash value 
  ** (see OMS_ContainerDictionary::m_guidHead) */
  OMS_ContainerInfo*  m_guidHashNext;
  /*! Pointer to the global class information */
  OMS_ClassInfo*      m_clsInfo;
  /*! Number of the container */
  OmsContainerNo       m_ContainerNo;
  /*! Schema identifier */
  OmsSchemaHandle      m_schema;
  tgg01_ContainerId    m_ContainerId;
  /*! Size of the object  + key - size of VTable-pointer */
  size_t               m_PersistentSize;
  /*! As a global container information may be referenced by many local container entries, 
  ** it is in general not possible to delete an entry directly, but only this flag can be set. 
  ** If the corresponding entry has been deleted in all local dictionaries 
  ** (OMS_ContainerInfo::m_refCnt == 0) then the global entry can be deleted. */  
  bool                 m_dropped;
  /*! How many references of local dictionaries to this global information exist? */
  short                m_refCnt;

  OMS_ContainerInfo ( OMS_ClassInfo* pClassInfo, const tgg01_ContainerId&, tsp00_Uint4 containerHandle, 
    size_t psz, OmsSchemaHandle sh, OmsContainerNo cno); 
  void* operator new(size_t sz);
  void           DeleteSelf();
#if defined(OMS_PLACEMENT_DELETE)
  void  operator delete (void* p);
#endif
  inline short            DecRefCnt();
  void                    Dump(OMS_ContainerDumpInfo&);
  const OMS_ClassInfo*   GetClassInfoPtr()    const { return m_clsInfo; }
  tsp00_Uint4             GetContainerHandle() const { return m_ContainerId.fileObjFileNo_gg00(); }
  const ClassIDRef        GetGuid()            const { return m_clsInfo->GetGuid(); }
  const OMS_KeyDesc&      GetKeyDesc()         const { return m_clsInfo->GetKeyDesc(); }       // PTS 1122540
  tsp00_Int4              GetObjectSize()      const { return (tsp00_Int4) m_clsInfo->GetObjectSize(); }
  OmsSchemaHandle         GetSchema()          const { return m_schema; }
  void*                   GetVirtualTablePtr() const { return m_clsInfo->GetVTPtr(); }
  void                    IncRefCnt()          { ++m_refCnt; }
  inline void             IncRefCnt(IliveCacheSink* lcSink);
  bool                    IsDropped()          const { return m_dropped; } 
  void                    MarkDropped()        { m_dropped = true; }
};

typedef OMS_ContainerInfo* OMS_ContainerInfoPtr;

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

inline short OMS_ContainerInfo::DecRefCnt() {
  --m_refCnt;
  return m_refCnt; 
}

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

inline void OMS_ContainerInfo::IncRefCnt(IliveCacheSink* lcSink) {
  OMS_SinkCriticalSection cs(lcSink, RGN_CLASS_DIR);
  ++m_refCnt;
  OMS_TRACE(omsTrContainerDir, lcSink, "ContainerInfo::IncRefCnt " << m_refCnt);
  OMS_TRACE(omsTrContainerDir, lcSink, "Name : " << GetClassInfoPtr()->GetClassName() << "Schema : " << GetSchema() << "CNo : "  << m_ContainerNo);
}

#endif  // __OMS_CONTAINERINFO_HPP
