/*
===========================================================================
Copyright (C) 2000 - 2013, Raven Software, Inc.
Copyright (C) 2001 - 2013, Activision, Inc.
Copyright (C) 2013 - 2015, OpenJK contributors
This file is part of the OpenJK source code.
OpenJK is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
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, see .
===========================================================================
*/
////////////////////////////////////////////////////////////////////////////////////////
// RAVEN STANDARD TEMPLATE LIBRARY
// (c) 2002 Activision
//
//
// Hash Pool
// ---------
// The hash pool stores raw data of variable size. It uses a hash table to check for
// redundant data, and upon finding any, will return the existing handle. Otherwise
// it copies the data to memory and returns a new handle.
//
//
// NOTES:
//
//
//
////////////////////////////////////////////////////////////////////////////////////////
#if !defined(RATL_HASH_POOL_VS_INC)
#define RATL_HASH_POOL_VS_INC
////////////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////////////
#if !defined(RATL_COMMON_INC)
#include "ratl_common.h"
#endif
namespace ratl
{
////////////////////////////////////////////////////////////////////////////////////////
// The Hash Pool
////////////////////////////////////////////////////////////////////////////////////////
template
class hash_pool
{
int mHandles[SIZE_HANDLES]; // each handle holds the start index of it's data
int mDataAlloc; // where the next chunck of data will go
char mData[SIZE];
#ifdef _DEBUG
int mFinds; // counts how many total finds have run
int mCurrentCollisions; // counts how many collisions on the last find
int mTotalCollisions; // counts the total number of collisions
int mTotalAllocs;
#endif
////////////////////////////////////////////////////////////////////////////////////
// This function searches for a handle which already stores the data (assuming the
// handle is a hash within range SIZE_HANDLES).
//
// If it failes, it returns false, and the handle passed in points to the next
// free slot.
////////////////////////////////////////////////////////////////////////////////////
bool find_existing(int& handle, const void* data, int datasize)
{
#ifdef _DEBUG
mFinds++;
mCurrentCollisions = 0;
#endif
while (mHandles[handle]) // So long as a handle exists there
{
if (mem::eql((void*)(&mData[mHandles[handle]]), data, datasize))
{
return true; // found
}
handle=(handle+1)&(SIZE_HANDLES-1); // incriment the handle
#ifdef _DEBUG
mCurrentCollisions ++;
mTotalCollisions ++;
//assert(mCurrentCollisions < 16); // If We Had 16+ Collisions, Hash May Be Inefficient.
// Evaluate SIZE and SIZEHANDLES
#endif
}
return false; // failed to find
}
////////////////////////////////////////////////////////////////////////////////////
// A simple hash function for the range of [0, SIZE_HANDLES]
////////////////////////////////////////////////////////////////////////////////////
int hash(const void* data, int datasize)
{
int h=0;
for (int i=0; i=0 && handle