/*

    ========== 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

*/
#include "Oms/OMS_ClassHash.hpp"
#include "Oms/OMS_Context.hpp"
#include "Oms/OMS_DumpInterface.hpp"
#include "Oms/OMS_Session.hpp"

OMS_ClassHash::OMS_ClassHash() : OMS_IGuidHash(), m_context(NULL)
{
  for (int ix = 0; ix < GUID_HASH_ENTRIES_CO13; ++ix) {
    m_head[ix] = NULL;
  }
}

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

OMS_ClassHash::~OMS_ClassHash() 
{
  for (int ix = 0; ix < GUID_HASH_ENTRIES_CO13; ++ix) {
    OMS_GuidEntryPtr pDel;
    OMS_GuidEntryPtr curr = m_head[ix];
    m_head[ix] = NULL;
    while (NULL != curr) {
      pDel = curr;
      curr = curr->m_hashNext;
      pDel->DeleteSelf(m_context);
    }
  }
  new(this) OMS_ClassHash();
}

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

void OMS_ClassHash::Create(OMS_Context* context)
{
  m_context = context;
}

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

void OMS_ClassHash::Dump(OMS_DumpInterface& dumpObj) const
{
  struct ClassHashDumpInfo 
  {
    OMS_GuidEntry*      m_this;
    OMS_GuidEntry*      m_hashNext;
    OMS_ClassInfo*       m_classInfo;
    OMS_FreeListHeader* m_freeHead;
    OMS_FreeListHeader* m_freeHeadInVersion;
    tsp00_Int4            m_slot;
    tsp00_Int4            m_filler;
  } classHashDumpInfo;

  dumpObj.SetDumpLabel(LABEL_OMS_LOCAL_CLASS);
  for (int ix = 0; ix < GUID_HASH_ENTRIES_CO13; ++ix) {
    OMS_GuidEntryPtr curr = m_head[ix];
    while (NULL != curr) {
      classHashDumpInfo.m_this      = curr;
      classHashDumpInfo.m_hashNext  = curr->m_hashNext;
      classHashDumpInfo.m_classInfo = curr->m_classInfo;
      classHashDumpInfo.m_freeHead  = curr->m_freeHead;
      classHashDumpInfo.m_freeHeadInVersion  = curr->m_freeHeadInVersion;
      classHashDumpInfo.m_slot      = ix;
      dumpObj.Dump(&classHashDumpInfo, sizeof(classHashDumpInfo));
      curr = curr->m_hashNext;
    }
  }
}

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


void OMS_ClassHash::HashInsert(OMS_ClassInfo* pClassInfo, OMS_FreeListHeader* freeHead,
                                 OMS_FreeListHeader* freeHeadInVersion)
{
  if (!HashFind(pClassInfo->GetGuid())) {
    int slot = HashValue(pClassInfo->GetGuid(), GUID_HASH_ENTRIES_CO13);
    m_head[slot] = new(m_context) OMS_GuidEntry(m_head[slot], pClassInfo, freeHead, freeHeadInVersion); 
  }
}

/*----------------------------------------------------------------------*/
 
OMS_GuidEntryPtr OMS_ClassHash::HashFind(const ClassIDRef guid) 
{
  int slot = HashValue(guid, GUID_HASH_ENTRIES_CO13);
  OMS_GuidEntryPtr p = m_head[slot];
  while (NULL != p) {
    if (p->m_classInfo->GetGuid() == guid) {
      return p;
    }
    p = p->m_hashNext;
  }
  return NULL;
}

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

