// Heap.cpp : _xZkqqHx_iDeDiDjDiDhGiDiKiDiBiDjDiDgFiBfLiDfGiDiHiDjD_xHqqkZx_ _xZkqqHx_iDhEiDeAiDeDiDiL_xHqqkZx_
//

#include "stdafx.h"
#include "UtilErr.h"	// For FFThrowMiscUnknown.
#include "HeapBuffer.h"	// For FCHeapBuffer.
//#include "HeapPool.h"	// For FCHeapPool.
#include "Heap.h"		// This header.

//----- 05.12.24 Fukushiro M. _xZkqqHx_iNoNiPjMiOgO_xHqqkZx_ ()-----
//#ifdef _DEBUG
//#define new DEBUG_NEW
//#undef THIS_FILE
//static char THIS_FILE[] = __FILE__;
//#endif
//----- 05.12.24 Fukushiro M. _xZkqqHx_iNoNiPjMiPeJ_xHqqkZx_ ()-----

// _xZkqqHx_iDiBiDiCiDiKiBfLiDfOiDeDiDhGiDgPiDgCiDhEiDeAiCmMiNiHiMhGiCmMiNmFjBoFjCgMiBeCiClBiCoKiCpAjClEiCkGiCoJiCmGiDhEiDeAiDeDiDiLiDfOiDeDiDhGiCmJjDfNiKlHiBeC_xHqqkZx_
static const DWORD FD_MEMORY_BUFFER_MAX = 0xf0000;
// FreeData_xZkqqHx_iCmJiCoGiCmBiCmEiJpAjFpKiClDiCoKiClNiDfKiDePiDiBiDjDiDgHiCkKiClBiCmMjCgMiCpAjClEiCkGiCoJiCmGiOkJjDkOjDeJiCmJ_xHqqkZx_Reduce_xZkqqHx_iClDiCoKiCoJiBeC_xHqqkZx_
static const DWORD FD_REDUCE_THRESHOLD = 100;

/////////////////////////////////////////////////////////////////////////////
// FCHeapSegmentPosition

const FCHeapSegmentPosition FCHeapSegmentPosition::s_Invalid = FCHeapSegmentPosition(DWORD(-1), DWORD(-1));

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeapSegmentPosition::FCHeapSegmentPosition
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDfCiDjDiDfIiDgHiDiJiDeOiDfOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	dwHeapBufferId		:_xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID_xZkqqHx_iCpAiOhHjCoIiBeC_xHqqkZx_
 *			dwSegmentPosition	:_xZkqqHx_iDfKiDePiDiBiDjDiDgHiImKjChFiCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
FCHeapSegmentPosition::FCHeapSegmentPosition (DWORD dwHeapBufferId, DWORD dwSegmentPosition)
			:	pair<DWORD, DWORD>(dwHeapBufferId, dwSegmentPosition)
{
} // FCHeapSegmentPosition::FCHeapSegmentPosition (DWORD dwHeapBufferId, DWORD dwSegmentPosition);

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeapSegmentPosition::GetHeapBufferId
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID_xZkqqHx_iCpAjFnEiClHiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID_xZkqqHx_iBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
DWORD FCHeapSegmentPosition::GetHeapBufferId () const
{
	return first;
} // DWORD FCHeapSegmentPosition::GetHeapBufferId () const;

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeapSegmentPosition::GetSegmentPosition
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDfKiDePiDiBiDjDiDgHiImKjChFiCpAjFnEiClHiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iDfKiDePiDiBiDjDiDgHiImKjChFiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
DWORD FCHeapSegmentPosition::GetSegmentPosition () const
{
	return second;
} // DWORD FCHeapSegmentPosition::GetSegmentPosition () const;

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeapSegmentPosition::SetSegmentPosition
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDfKiDePiDiBiDjDiDgHiImKjChFiCpAjAnNjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	dwSegmentPosition	:_xZkqqHx_iDfKiDePiDiBiDjDiDgHiImKjChFiCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
void FCHeapSegmentPosition::SetSegmentPosition (DWORD dwSegmentPosition)
{
	second = dwSegmentPosition;
} // DWORD FCHeapSegmentPosition::SetSegmentPosition () const;

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeapSegmentPosition::Invalid
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_jGlDiMpIiCmIjCgMiCpAjFnEiClHiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_jGlDiMpIiCmIjCgMiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
const FCHeapSegmentPosition& FCHeapSegmentPosition::Invalid ()
{
	return s_Invalid;
} // const FCHeapSegmentPosition& FCHeapSegmentPosition::Invalid ();

/////////////////////////////////////////////////////////////////////////////
// FCHeap

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::FCHeap
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDfCiDjDiDfIiDgHiDiJiDeOiDfOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.14 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
FCHeap::FCHeap ()
	:	m_dwEmptySegment(0)
{
} // FCHeap::FCHeap.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::~FCHeap
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDgGiDfIiDgHiDiJiDeOiDfOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.14 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
FCHeap::~FCHeap ()
{
	// _xZkqqHx_jBfDiCmEiCmMiDgPiDgCiDhEiDeAiCpAiJpAjFpKiBeC_xHqqkZx_
	DWORD dwHeapBufferId;
	for (dwHeapBufferId = m_heapPool.GetFirstId();
		 dwHeapBufferId != DWORD(-1);
		 dwHeapBufferId = m_heapPool.GetNextId(dwHeapBufferId))
	{
		m_heapPool.DeleteBuffer(dwHeapBufferId);
	}
} // FCHeap::~FCHeap.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::AllocateData
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDhBiBfLiDhGiCmJiOhHjCoIiClDiCoKiClNiDgGiBfLiDfOiCpAiKgNjFnLiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	pData		:_xZkqqHx_iDgGiBfLiDfOiCpAiOhHjCoIiBeC_xHqqkZx_
 *			dwDataSize	:_xZkqqHx_iDgGiBfLiDfOiDfEiDeDiDfJiCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iKgNjFnLiClDiCoKiClNiDgGiBfLiDfOjHmMiIoGiCmMiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
DWORD FCHeap::AllocateData (const void* pData, DWORD dwDataSize)
{
	if (FD_MEMORY_BUFFER_MAX < m_heapPool.GetMemoryBufferSize())
	//----- _xZkqqHx_iDiBiDiCiDiKiBfLiDfOiDeDiDhGiCmMiDgPiDgCiDhEiDeAiNiHiMhGiCkKjAkHiMmAjCgMiCpAjClEiCkGiCoJiPoKiNiH_xHqqkZx_ -----
	{
		// _xZkqqHx_jFhDjHhGiCmIiDfKiDePiDiBiDjDiDgHiCpAiIlDiPgLiBeC_xHqqkZx_
		Reduce();
		if (FD_MEMORY_BUFFER_MAX < m_heapPool.GetMemoryBufferSize())
		//----- _xZkqqHx_iIlDiPgLiClFiCmEiCmIiCkIjAkHiMmAjCgMiCpAjClEiCkGiCoJiPoKiNiH_xHqqkZx_ -----
		{
			// _xZkqqHx_iDiBiDiCiDiKiBfLiDfOiDeDiDhGiCmMiDgPiDgCiDhEiDeAiCpAiDhEiDeAiDeDiDiLiDfOiDeDiDhGiCnGjDfNiKlHiClHiCoJiBeC_xHqqkZx_
			DWORDSet stBufferId;
			m_heapPool.ChangeMemoryTypeToFileType(stBufferId);
			// _xZkqqHx_jAfGiClFiCkNiNoMjAkMiClDiCoKiClNiDhEiDeAiDeDiDiLiDfOiDeDiDhGiCmMiDgPiDgCiDhEiDeAiCmMiDfKiDePiDiBiDjDiDgHiCpAjClCiCnHiBeB_xHqqkZx_
			// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfI_xHqqkZx_ _xZkqqHx_jEhKjHpBiCpAiPeDjAlDiClHiCoJiBeC_xHqqkZx_
			DWORDSet::const_iterator iBuffId;
			for (iBuffId = stBufferId.begin(); iBuffId != stBufferId.end(); iBuffId++)
			{
				FCHeapBuffer heapBuffer = m_heapPool.GetHeapBuffer(*iBuffId);
				DWORD dwSegmentPosition;
				for (dwSegmentPosition = 0;
					 heapBuffer.GetSegmentSize(dwSegmentPosition) != 0;
					 heapBuffer.GetNextSegment(dwSegmentPosition))
				{
					// _xZkqqHx_iNoNiPjMiPiIjHjNiCpAiKeKiOgOiClFiClNiImKjChFiCmMiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAiOoGjDlOiBeC_xHqqkZx_
					DWORD dwDataId = heapBuffer.GetDataId(dwSegmentPosition);
					// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfI_xHqqkZx_ _xZkqqHx_jEhKjHpBiCpAjCpJjAlDiBeC_xHqqkZx_
					m_vIdToHeapSegment[dwDataId] = FCHeapSegmentPosition(*iBuffId, dwSegmentPosition);
				}
			}
		}
	}

	// _xZkqqHx_iOhHjCoIiClDiCoKiClNjHmMiIoGiCkKiKgNjFnLiJmCjEfMiCmIiDhBiBfLiDhGiDgPiDgCiDhEiDeAiCpAjCfEiClHiBeC_xHqqkZx_
	DWORD dwHeapBufferId;
	for (dwHeapBufferId = m_heapPool.GetFirstId();
		 dwHeapBufferId != DWORD(-1);
		 dwHeapBufferId = m_heapPool.GetNextId(dwHeapBufferId))
	{
		if (dwDataSize <= m_heapPool.GetHeapBuffer(dwHeapBufferId).GetRestDataSize())
			break;
	}
	// _xZkqqHx_iKgNjFnLiJmCjEfMiCmIiDgPiDgCiDhEiDeAiCkKjBlGiNnNiClFiCmIiCkCiPoKiNiHiCmNiDgPiDgCiDhEiDeAiCpAiNoMjAkMiClFiCmEjCmHiJmBiBeC_xHqqkZx_
	if (dwHeapBufferId == DWORD(-1))
		dwHeapBufferId = m_heapPool.AppendBuffer(dwDataSize);

	FCHeapBuffer heapBuffer = m_heapPool.GetHeapBuffer(dwHeapBufferId);
	// _xZkqqHx_iDgPiDgCiDhEiDeAiPoDiCmJiOhHjCoIiClDiCoKiClNiDfEiDeDiDfJiCmFiDfKiDePiDiBiDjDiDgHiCpAiKgNjFnLiBeC_xHqqkZx_
	const DWORD dwSegmentPosition = heapBuffer.AllocateSegment(dwDataSize);
	// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAjEkNiNhDiClHiCoJiBeC_xHqqkZx_
	const DWORD dwDataId = IssueFreeDataId();
	// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDhBiBfLiDhGiDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfIiCmMjEhKjHpBiCpAjAnNjCoIiBeC_xHqqkZx_
	m_vIdToHeapSegment[dwDataId] = FCHeapSegmentPosition(dwHeapBufferId, dwSegmentPosition);
	// _xZkqqHx_iDfKiDePiDiBiDjDiDgHiCmJiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAjAnNjCoIiBeC_xHqqkZx_
	heapBuffer.SetDataId(dwSegmentPosition, dwDataId);
	// _xZkqqHx_iDfKiDePiDiBiDjDiDgHiCmJiOfBiPmGiDeKiDeFiDjDiDfOiCpAjAnNjCoIiBeC_xHqqkZx_
	heapBuffer.SetReferenceCount(dwSegmentPosition, 1);
	// _xZkqqHx_iDfKiDePiDiBiDjDiDgHiCmJiDgGiBfLiDfOiCpAjAnNjCoIiBeC_xHqqkZx_
	heapBuffer.SetData(dwSegmentPosition, pData);
	return dwDataId;
} // FCHeap::AllocateData.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::FreeData
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iOhHjCoIiClDiCoKiClNiDgGiBfLiDfOiCmMjHmMiIoGiCpAiJpAjFpKiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	dwDataId	:_xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
void FCHeap::FreeData (DWORD dwDataId)
{
	// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDhBiBfLiDhGiDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfIiCmMjEhKjHpBiBeC_xHqqkZx_m_vIdToHeapSegment_xZkqqHx_iCmM_xHqqkZx_
	// _xZkqqHx_jCgMiCpAjFmPiNfIiClHiCoJiCmMiCmFiOfBiPmGiBgJiBjFiBgKiOoGjDlOiClFiCmEiCmNiCkCiCkPiCmIiCkCiBeC_xHqqkZx_
	const FCHeapSegmentPosition heapSegmentPosition = m_vIdToHeapSegment[dwDataId];

	// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDhBiBfLiDhGiDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfIiCmMjEhKjHpBiCmJjGlDiMpIjCgMiCpAjAnNjCoIiBeC_xHqqkZx_
	m_vIdToHeapSegment[dwDataId] = FCHeapSegmentPosition::Invalid();
	// _xZkqqHx_iDhEiDiKiBfLiCmMiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCmGiClFiCmEjDgPjIfOiBeC_xHqqkZx_
	RegisterFreeDataId(dwDataId);

	FCHeapBuffer heapBuffer = m_heapPool.GetHeapBuffer(heapSegmentPosition.GetHeapBufferId());
	// _xZkqqHx_iDfKiDePiDiBiDjDiDgHiCpAiKeKjFpKiBeC_xHqqkZx_
	heapBuffer.FreeSegment(heapSegmentPosition.GetSegmentPosition());
	if (heapBuffer.IsEmpty())
	//----- _xZkqqHx_iDgPiDgCiDhEiDeAiCkKiLpDiCmJiCmIiCmBiClNiPoKiNiH_xHqqkZx_ -----
	{
		// _xZkqqHx_iDgPiDgCiDhEiDeAiOkJjBmMiCpAiJpAjFpKiBeC_xHqqkZx_
		m_heapPool.DeleteBuffer(heapSegmentPosition.GetHeapBufferId());
//----- 06.05.29 Fukushiro M. _xZkqqHx_jCmHiJmBiOgO_xHqqkZx_ ()-----
		// _xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID->_xZkqqHx_iLpDiDfKiDePiDiBiDjDiDgHiDgFiBfLiDhFiDiLiCkJiCoHjDgPjIfOiCpAjGjFiPmBiBeC_xHqqkZx_
		// _xZkqqHx_iClBiCoKiCpAiClFiCmIiCkCiCmGiBeB_xHqqkZx_Reduce()_xZkqqHx_iCmFiKpJiCmJ_xHqqkZx_DeleteBuffer_xZkqqHx_iClDiCoKiClNiDgPiDgCiDhEiDeAiCmJ_xHqqkZx_
		// Reduce _xZkqqHx_iCpAiCkJiCkPiCmEiClFiCnMiCkCiBeBjHiOiClPiCoJiBeC_xHqqkZx_
		m_mpBufferIdToEmptySegment.erase(heapSegmentPosition.GetHeapBufferId());
//----- 06.05.29 Fukushiro M. _xZkqqHx_jCmHiJmBiPeJ_xHqqkZx_ ()-----
	} else
	//----- _xZkqqHx_iDgPiDgCiDhEiDeAiCkKiLpDiCmFiCmNiCmIiCkCiPoKiNiH_xHqqkZx_ -----
	{
		// _xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID->_xZkqqHx_iLpDiDfKiDePiDiBiDjDiDgHiDgFiBfLiDhFiDiLiBeC_xHqqkZx_
		// _xZkqqHx_iLpDiDfKiDePiDiBiDjDiDgHiDgFiBfLiDhFiDiLiCmNiBeBiNmFiCoAiPkMiClDiCkCiDfKiDePiDiBiDjDiDgHiImKjChFiCpAiLeMjIfOiClFiCmEiCkIiCkNiBeC_xHqqkZx_
		map<DWORD, DWORD>::iterator i = m_mpBufferIdToEmptySegment.find(heapSegmentPosition.GetHeapBufferId());
		if (i != m_mpBufferIdToEmptySegment.end())
		//----- _xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID->_xZkqqHx_iLpDiDfKiDePiDiBiDjDiDgHiDgFiBfLiDhFiDiLiCmJjDgPjIfOiNmPiCnNiCmMiPoKiNiH_xHqqkZx_ -----
		{
			// _xZkqqHx_iCoGiCoIiPkMiClDiCkCiDfKiDePiDiBiDjDiDgHiImKjChFiCmMiPoKiNiHiCmNiBeBjCgMiCpAiNfIjAfGiBeC_xHqqkZx_
			if (heapSegmentPosition.GetSegmentPosition() < (*i).second)
				(*i).second = heapSegmentPosition.GetSegmentPosition();
		} else
		//----- _xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID->_xZkqqHx_iLpDiDfKiDePiDiBiDjDiDgHiDgFiBfLiDhFiDiLiCmJjGkCjDgPjIfOjDgPjIfOiCmMiPoKiNiH_xHqqkZx_ -----
		{
			// _xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID->_xZkqqHx_iLpDiDfKiDePiDiBiDjDiDgHiDgFiBfLiDhFiDiLiCmJjCmHiJmBiBeC_xHqqkZx_
			m_mpBufferIdToEmptySegment[heapSegmentPosition.GetHeapBufferId()] = heapSegmentPosition.GetSegmentPosition();
		}
		// _xZkqqHx_iLpDiCmJiCmIiCmBiClNiDfKiDePiDiBiDjDiDgHjAjEiBeCiKfEiOfKiBeC_xHqqkZx_
		m_dwEmptySegment++;
		// FreeData_xZkqqHx_iCmJiCoGiCmBiCmEiJpAjFpKiClDiCoKiClNiDfKiDePiDiBiDjDiDgHiCkKiClBiCmMjCgMiCpAjClEiCkGiCoJiCmGiOkJjDkOjDeJiCmJ_xHqqkZx_Reduce_xZkqqHx_iClDiCoKiCoJiBeC_xHqqkZx_
		if (FD_REDUCE_THRESHOLD < m_dwEmptySegment)
			Reduce();
	}
} // FCHeap::FreeData.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::Reduce
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iOgHiCoNiCoKiCmEiCkCiCmIiCkCiDfKiDePiDiBiDjDiDgHiCmMjHmMiIoGiCpAjBfDiCmEiNoNiPjMiClHiCoJiBeCiOgHiCoNiCoKiCmEiCkCiCmIiCkC_xHqqkZx_
 *			_xZkqqHx_iDgPiDgCiDhEiDeAiCmNiJpAjFpKiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
void FCHeap::Reduce ()
{
	// _xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID->_xZkqqHx_iLpDiDfKiDePiDiBiDjDiDgHiDgFiBfLiDhFiDiLiBeC_xHqqkZx_
	map<DWORD, DWORD>::const_iterator i;
	for (i = m_mpBufferIdToEmptySegment.begin();
		 i != m_mpBufferIdToEmptySegment.end(); i++)
	{
		// _xZkqqHx_iOgHiCoNiCoKiCmEiCkCiCmIiCkCiDfKiDePiDiBiDjDiDgHiCmMiDgPiDgCiDhEiDeA_xHqqkZx_ID_xZkqqHx_iCmGiDfKiDePiDiBiDjDiDgHiImKjChFiBeC_xHqqkZx_
		DWORD dwHeapBufferId = (*i).first;
		DWORD dwSegmentPosition = (*i).second;
		FCHeapBuffer heapBuffer = m_heapPool.GetHeapBuffer(dwHeapBufferId);
		// _xZkqqHx_iDgPiDgCiDhEiDeAiCkJiCoHjGkCiOgHjHhAiDfKiDePiDiBiDjDiDgHiCpAiNoNiPjMiBeC_xHqqkZx_
		heapBuffer.Reduce(dwSegmentPosition);
		if (heapBuffer.IsEmpty())
		//----- _xZkqqHx_iDgPiDgCiDhEiDeAiCkKiLpDiCmJiCmIiCmBiClNiPoKiNiH_xHqqkZx_ -----
		{
			// _xZkqqHx_iDgPiDgCiDhEiDeAiOkJjBmMiCpAiJpAjFpKiBeC_xHqqkZx_
			m_heapPool.DeleteBuffer(dwHeapBufferId);
		} else
		//----- _xZkqqHx_iDfKiDePiDiBiDjDiDgHiCkKiOgDiCmBiCmEiCkCiCoJiPoKiNiH_xHqqkZx_ -----
		{
			do
			{
				// _xZkqqHx_iNoNiPjMiPiIjHjNiCpAiKeKiOgOiClFiClNiImKjChFiCmMiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAiOoGjDlOiBeC_xHqqkZx_
				DWORD dwDataId = heapBuffer.GetDataId(dwSegmentPosition);
				// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfI_xHqqkZx_ _xZkqqHx_jEhKjHpBiCpAjCpJjAlDiBeC_xHqqkZx_
				m_vIdToHeapSegment[dwDataId].SetSegmentPosition(dwSegmentPosition);
				// _xZkqqHx_iOjPiCmMiDfKiDePiDiBiDjDiDgHiCnGiBeC_xHqqkZx_
			} while (heapBuffer.GetNextSegment(dwSegmentPosition));
		}
	}
	// _xZkqqHx_iDgPiDgCiDhEiDeA_xHqqkZx_ID->_xZkqqHx_iLpDiDfKiDePiDiBiDjDiDgHiDgFiBfLiDhFiDiLiCpAiDeOiDiKiDeBiBeC_xHqqkZx_
	m_mpBufferIdToEmptySegment.clear();
	// _xZkqqHx_iLpDiCmJiCmIiCmBiClNiDfKiDePiDiBiDjDiDgHjAjEiBeCiKfEiOfKiBeC_xHqqkZx_
	m_dwEmptySegment = 0;
} // FCHeap::Reduce.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::IncrementReference
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iOhHjCoIiClDiCoKiClNiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCmMiOfBiPmGiDeKiDeFiDjDiDfOiCpAiJmBiOfKiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	dwDataId	:_xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iJmBiOfKiMoDiCmMiOfBiPmGiDeKiDeFiDjDiDfOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
DWORD FCHeap::IncrementReference (DWORD dwDataId)
{
	// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDhBiBfLiDhGiDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfIiCmMjEhKjHpBiBeC_xHqqkZx_
	const FCHeapSegmentPosition& heapSegmentPosition = m_vIdToHeapSegment[dwDataId];
	// _xZkqqHx_iOfBiPmGiDeKiDeFiDjDiDfOiCpAiOoGjDlOiBeC_xHqqkZx_
	DWORD dwReferenceCount = m_heapPool.GetHeapBuffer(heapSegmentPosition.GetHeapBufferId()).GetReferenceCount(heapSegmentPosition.GetSegmentPosition());
	dwReferenceCount++;
	// _xZkqqHx_iOfBiPmGiDeKiDeFiDjDiDfOiCpAjAnNjCoIiBeC_xHqqkZx_
	m_heapPool.GetHeapBuffer(heapSegmentPosition.GetHeapBufferId()).SetReferenceCount(heapSegmentPosition.GetSegmentPosition(), dwReferenceCount);
	return dwReferenceCount;
} // FCHeap::IncrementReference.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::DecrementReference
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iOhHjCoIiClDiCoKiClNiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCmMiOfBiPmGiDeKiDeFiDjDiDfOiCpAiMlIiOfKiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	dwDataId	:_xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iMlIiOfKiMoDiCmMiOfBiPmGiDeKiDeFiDjDiDfOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
DWORD FCHeap::DecrementReference (DWORD dwDataId)
{
	// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDhBiBfLiDhGiDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfIiCmMjEhKjHpBiBeC_xHqqkZx_
	const FCHeapSegmentPosition& heapSegmentPosition = m_vIdToHeapSegment[dwDataId];
	// _xZkqqHx_iOfBiPmGiDeKiDeFiDjDiDfOiCpAiOoGjDlOiBeC_xHqqkZx_
	DWORD dwReferenceCount = m_heapPool.GetHeapBuffer(heapSegmentPosition.GetHeapBufferId()).GetReferenceCount(heapSegmentPosition.GetSegmentPosition());
	dwReferenceCount--;
	// _xZkqqHx_iOfBiPmGiDeKiDeFiDjDiDfOiCpAjAnNjCoIiBeC_xHqqkZx_
	m_heapPool.GetHeapBuffer(heapSegmentPosition.GetHeapBufferId()).SetReferenceCount(heapSegmentPosition.GetSegmentPosition(), dwReferenceCount);
	return dwReferenceCount;
} // FCHeap::DecrementReference.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::GetDataSize
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iOhHjCoIiClDiCoKiClNiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCmMiDgGiBfLiDfOiDfEiDeDiDfJiCpAiOoGjDlOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	dwDataId	:_xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iDgGiBfLiDfOiDfEiDeDiDfJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
DWORD FCHeap::GetDataSize (DWORD dwDataId) const
{
	// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDhBiBfLiDhGiDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfIiCmMjEhKjHpBiBeC_xHqqkZx_
	const FCHeapSegmentPosition& heapSegmentPosition = m_vIdToHeapSegment[dwDataId];
	// _xZkqqHx_iDgGiBfLiDfOiDfEiDeDiDfJiCpAiOoGjDlOiBeC_xHqqkZx_
	return m_heapPool.GetHeapBuffer(heapSegmentPosition.GetHeapBufferId()).GetDataSize(heapSegmentPosition.GetSegmentPosition());
} // FCHeap::GetDataSize.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::GetData
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iOhHjCoIiClDiCoKiClNiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCmMiDgGiBfLiDfOiCpAiOoGjDlOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	pDataBuff	:_xZkqqHx_iDgGiBfLiDfOiCpAiOpDiCkPiOoGiCoJiDgPiDgCiDhEiDeAiCpAiOhHjCoIiBeC_xHqqkZx_
 *			dwBuffSize	:_xZkqqHx_iDgPiDgCiDhEiDeAiDfEiDeDiDfJiCpAiOhHjCoIiBeCjBfDiCmEiCmMiDgGiBfLiDfOiCpA_xHqqkZx_
 *						 _xZkqqHx_iOoGjDlOiClHiCoJiPoKiNiHiCmN_xHqqkZx_ DOWRD(-1) _xZkqqHx_iCpAiOhHjCoIiClFiCmEiCoAjHmHiCkCiBeC_xHqqkZx_
 *			dwStartOffset:_xZkqqHx_iDgGiBfLiDfOiCpAjDmHiCnNiPgPiClHiKeKiOgOiImKjChFiCpAiOhHjCoIiBeCjHoBiCkGiCmO_xHqqkZx_0_xZkqqHx_iCpA_xHqqkZx_
 *						 _xZkqqHx_iOhHjCoIiClFiClNiPoKiNiHiCmNiDgPiDgCiDhEiDeAiNmFiPiJiCkJiCoHjDmHiCnNiPgPiClHiBeC_xHqqkZx_
 *			dwDataId	:_xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_jDmHiCnNiPgPiClDiCoKiClNiDgGiBfLiDfOiDfEiDeDiDfJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
DWORD FCHeap::GetData (void* pDataBuff, DWORD dwBuffSize, DWORD dwStartOffset, DWORD dwDataId) const
{
	// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDhBiBfLiDhGiDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfIiCmMjEhKjHpBiBeC_xHqqkZx_
	const FCHeapSegmentPosition& heapSegmentPosition = m_vIdToHeapSegment[dwDataId];
	return m_heapPool.GetHeapBuffer(heapSegmentPosition.GetHeapBufferId()).
			GetData(heapSegmentPosition.GetSegmentPosition(), pDataBuff, dwBuffSize, dwStartOffset);
} // FCHeap::GetData.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::IssueFreeDataId
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iOgHiCoNiCoKiCmEiCkCiCmIiCkCiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAjEkNiNhDiClHiCoJiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jFnEjCgM_xHqqkZx_>	_xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iBeC_xHqqkZx_
 *
 * <_xZkqqHx_iJpAjAoA_xHqqkZx_>	_xZkqqHx_jGkCiOgHjHhAiCmMiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAjCfEiClFiPgPiClFiCmEiBeBiOgHjHhAiPpDjBnEiCmJjFmPiNfIiClFiBeBjEkNiNhDiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
DWORD FCHeap::IssueFreeDataId ()
{
	DWORD dwDataId;
	if (m_stFreeDataId.empty())
	//----- _xZkqqHx_jGkCiOgHjHhAiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iPfHiNiHiCkKiLpDiCmMiPoKiNiH_xHqqkZx_ -----
	{
		// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDhBiBfLiDhGiDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfIiCmMjEhKjHpBiCmJjDgPjIfOiBeC_xHqqkZx_
		dwDataId = m_vIdToHeapSegment.size();
		m_vIdToHeapSegment.push_back(FCHeapSegmentPosition::Invalid());
	} else
	//----- _xZkqqHx_jGkCiOgHjHhAiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iPfHiNiHiCkKiCkAiCoJiPoKiNiH_xHqqkZx_ -----
	{
		dwDataId = *m_stFreeDataId.begin();
		// _xZkqqHx_jGkCiOgHjHhAiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iPfHiNiHiCkJiCoHjGjFiPmBiBeC_xHqqkZx_
		m_stFreeDataId.erase(m_stFreeDataId.begin());
	}
	return dwDataId;
} // FCHeap::IssueFreeDataId.

/*************************************************************************
 * <_xZkqqHx_iKnGjAjE_xHqqkZx_>	FCHeap::RegisterFreeDataId
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iOhHjCoIiClDiCoKiClNiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAjGkCiOgHjHhAiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCmGiClFiCmEjDgPjIfOiBeC_xHqqkZx_
 *
 * <_xZkqqHx_iIpIjAjE_xHqqkZx_>	dwDataId	:_xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iCpAiOhHjCoIiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	05.12.13 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
void FCHeap::RegisterFreeDataId (DWORD dwDataId)
{
	// _xZkqqHx_jGkCiOgHjHhAiDgGiBfLiDfO_xHqqkZx_ID_xZkqqHx_iPfHiNiHiCmJjCmHiJmBiBeC_xHqqkZx_
	m_stFreeDataId.insert(dwDataId);
	// _xZkqqHx_iDgGiBfLiDfO_xHqqkZx_ID->_xZkqqHx_iDhBiBfLiDhGiDfKiDePiDiBiDjDiDgHiDeBiDgIiDiMiDfIiCmMjEhKjHpBiCmMiNmFiMoDiCkKjGkCiOgHjHhAiCmMiPoKiNiHiCmNiBeB_xHqqkZx_
	// _xZkqqHx_iClLiCoKiCpAiNoNiPjMiClHiCoJiBeC_xHqqkZx_
	while (	!m_vIdToHeapSegment.empty() &&
			m_vIdToHeapSegment.back() == FCHeapSegmentPosition::Invalid())
	{
		m_stFreeDataId.erase(m_vIdToHeapSegment.size() - 1);
		m_vIdToHeapSegment.pop_back();
	}
} // FCHeap::RegisterFreeDataId.
