/*
===========================================================================
ARX FATALIS GPL Source Code
Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
Arx Fatalis Source Code 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 3 of the License, or (at your option) any later version.
Arx Fatalis Source Code 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 Arx Fatalis Source Code. If not, see
.
In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
// Code: Didier Pédreno
// todo remover les strIcmp
#include "ARX_LocHash.h"
#define _CRTDBG_MAP_ALLOC
#include
//-----------------------------------------------------------------------------
CLocalisationHash::CLocalisationHash(int _iSize)
{
pTab = new CLocalisation* [_iSize];
iSize = _iSize;
iFill = 0;
iMask = iSize - 1;
for (unsigned long i = 0; i < iSize; i++)
{
pTab[i] = NULL;
}
iNbCollisions = iNbNoInsert = 0;
}
//-----------------------------------------------------------------------------
CLocalisationHash::~CLocalisationHash()
{
while (iSize--)
{
if (pTab[iSize] != NULL)
{
delete pTab[iSize];
pTab[iSize] = NULL;
}
}
delete [] pTab;
pTab = NULL;
}
//-----------------------------------------------------------------------------
int CLocalisationHash::FuncH1(int _iKey)
{
return _iKey;
}
//-----------------------------------------------------------------------------
int CLocalisationHash::FuncH2(int _iKey)
{
return ((_iKey >> 1) | 1);
}
//-----------------------------------------------------------------------------
int CLocalisationHash::GetKey(const _TCHAR * _lpszUText)
{
int iKey = 0;
int iLenght = _tcslen((const _TCHAR *)_lpszUText);
int iLenght2 = iLenght;
while (iLenght--)
{
iKey += _lpszUText[iLenght] * (iLenght + 1) + _lpszUText[iLenght] * iLenght2;
}
return iKey;
}
//-----------------------------------------------------------------------------
void CLocalisationHash::ReHash()
{
ULONG iNewSize = iSize << 1;
long iNewMask = iNewSize - 1;
CLocalisation ** pTab2 = new CLocalisation *[iNewSize];
for (unsigned long i = 0 ; i < iNewSize ; i++)
{
pTab2[i] = NULL;
}
for (UINT i = 0 ; i < iSize ; i++)
{
if (pTab[i] != NULL)
{
int iKey = GetKey(pTab[i]->lpszUSection);
int iH1 = FuncH1(iKey);
int iH2 = FuncH2(iKey);
UINT iNbSolution = 0;
while (iNbSolution < iNewSize)
{
iH1 &= iNewMask;
if (pTab2[iH1] == NULL)
{
pTab2[iH1] = pTab[i];
pTab[i] = NULL;
//iFill ++;
}
iNbCollisions ++;
iH1 += iH2;
iNbSolution ++;
}
iNbNoInsert ++;
}
}
iSize = iNewSize;
iMask = iNewMask;
delete [] pTab;
pTab = pTab2;
}
//-----------------------------------------------------------------------------
bool CLocalisationHash::AddElement(CLocalisation * _pLoc)
{
if (iFill >= iSize * 0.75)
{
ReHash();
}
if (!(_pLoc && _pLoc->lpszUSection)) return false;
int iKey = GetKey(_pLoc->lpszUSection);
int iH1 = FuncH1(iKey);
int iH2 = FuncH2(iKey);
unsigned long iNbSolution = 0;
while (iNbSolution < iSize)
{
iH1 &= iMask;
if (pTab[iH1] == NULL)
{
pTab[iH1] = _pLoc;
iFill ++;
return true;
}
iNbCollisions ++;
iH1 += iH2;
iNbSolution ++;
}
iNbNoInsert ++;
return false;
}
//-----------------------------------------------------------------------------
_TCHAR * CLocalisationHash::GetPtrWithString(const _TCHAR * _lpszUText)
{
int iKey = GetKey(_lpszUText);
int iH1 = FuncH1(iKey);
int iH2 = FuncH2(iKey);
unsigned long iNbSolution = 0;
while (iNbSolution < iSize)
{
iH1 &= iMask;
if (pTab[iH1])
{
if (!_tcsicmp(_lpszUText, pTab[iH1]->lpszUSection))
{
if (pTab[iH1]->vUKeys.size() > 0)
{
return pTab[iH1]->vUKeys[0];
}
return NULL;
}
}
iH1 += iH2;
iNbSolution++;
}
return NULL;
}
//-----------------------------------------------------------------------------
unsigned long CLocalisationHash::GetKeyCount(const _TCHAR * _lpszUText)
{
int iKey = GetKey(_lpszUText);
int iH1 = FuncH1(iKey);
int iH2 = FuncH2(iKey);
unsigned long iNbSolution = 0;
while (iNbSolution < iSize)
{
iH1 &= iMask;
if (pTab[iH1])
{
if (!_tcsicmp(_lpszUText, pTab[iH1]->lpszUSection))
{
return pTab[iH1]->vUKeys.size();
return 0;
}
}
iH1 += iH2;
iNbSolution++;
}
return 0;
}