⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grid_memory.cpp

📁 这是一个GPS相关的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}

		SG_Free(m_Values);

		m_Values	= NULL;
	}
}


///////////////////////////////////////////////////////////
//														 //
//						Cache							 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
bool CSG_Grid::Set_Cache(bool bOn)
{
	return( bOn ? _Cache_Create() : _Cache_Destroy(true) );
}

//---------------------------------------------------------
bool CSG_Grid::is_Cached(void)
{
	return( m_Memory_Type == GRID_MEMORY_Cache );
}


///////////////////////////////////////////////////////////
//														 //
//				Cache: Create / Destroy					 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
bool CSG_Grid::_Cache_Create(const SG_Char *FilePath, TSG_Grid_Type File_Type, long Offset, bool bSwap, bool bFlip)
{
	if( m_System.is_Valid() && m_Type > 0 && m_Type < GRID_TYPE_Count && m_Memory_Type == GRID_MEMORY_Normal )
	{
		Cache_Path.Printf(FilePath);

		if( m_Type == File_Type
		&&	(	Cache_Stream.Open(Cache_Path, SG_FILE_RWA, true)
			||	Cache_Stream.Open(Cache_Path, SG_FILE_R  , true)) )
		{
			m_Memory_bLock	= true;

			Cache_bTemp		= false;

			Cache_Offset	= Offset;
			Cache_bSwap		= bSwap;
			Cache_bFlip		= bFlip;

			_LineBuffer_Create();

			m_Memory_bLock	= false;
			m_Memory_Type	= GRID_MEMORY_Cache;

			_Array_Destroy();
		}
	}

	return( is_Cached() );
}

//---------------------------------------------------------
bool CSG_Grid::_Cache_Create(void)
{
	TSG_Grid_Line	Line;

	if( m_System.is_Valid() && m_Type > 0 && m_Type < GRID_TYPE_Count && m_Memory_Type == GRID_MEMORY_Normal )
	{
		Cache_Path	= SG_File_Get_TmpName(SG_T("sg_grd"), SG_Grid_Cache_Get_Directory());

		if( Cache_Stream.Open(Cache_Path, SG_FILE_RW, true) )
		{
			m_Memory_bLock	= true;

			Cache_bTemp		= true;

			Cache_Offset	= 0;
			Cache_bSwap		= false;
			Cache_bFlip		= false;

			_LineBuffer_Create();

			if( m_Values )
			{
				Line.Data	= (char *)SG_Malloc(_LineBuffer_Get_nBytes());

				for(Line.y=0; Line.y<Get_NY() && SG_UI_Process_Set_Progress(Line.y, Get_NY()); Line.y++)
				{
					Line.bModified	= true;
					memcpy(Line.Data, m_Values[Line.y], _LineBuffer_Get_nBytes());
					_Cache_LineBuffer_Save(&Line);
					SG_Free(m_Values[Line.y]);
				}

				SG_Free(Line.Data);

				SG_Free(m_Values);
				m_Values	= NULL;

				SG_UI_Process_Set_Ready();
			}

			m_Memory_bLock	= false;
			m_Memory_Type	= GRID_MEMORY_Cache;
		}
	}

	return( is_Cached() );
}

//---------------------------------------------------------
bool CSG_Grid::_Cache_Destroy(bool bMemory_Restore)
{
	int				y;
	TSG_Grid_Line	*pLine;

	if( is_Valid() && m_Memory_Type == GRID_MEMORY_Cache )
	{
		m_Memory_bLock	= true;

		if( !Cache_bTemp )
		{
			_LineBuffer_Flush();
		}

		if( bMemory_Restore && _Array_Create() )
		{
			for(y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
			{
				if( (pLine = _LineBuffer_Get_Line(y)) != NULL )
				{
					memcpy(m_Values[y], pLine->Data, _LineBuffer_Get_nBytes());
				}
			}

			SG_UI_Process_Set_Ready();
		}

		_LineBuffer_Destroy();

		m_Memory_bLock	= false;
		m_Memory_Type	= GRID_MEMORY_Normal;

		//-------------------------------------------------
		Cache_Stream.Close();

		if( Cache_bTemp )
		{
			SG_File_Delete(Cache_Path);
		}

		return( true );
	}

	return( false );
}


///////////////////////////////////////////////////////////
//														 //
//					Cache: Save / Load					 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CSG_Grid::_Cache_LineBuffer_Save(TSG_Grid_Line *pLine) const
{
	int		x, y, Line_Pos, Line_Size;
	char	*pValue;

	if( pLine && pLine->bModified )
	{
		pLine->bModified	= false;

		if( pLine->y >= 0 && pLine->y < Get_NY() )
		{
			y			= Cache_bFlip ? Get_NY() - 1 - pLine->y : pLine->y;

			Line_Size	= _LineBuffer_Get_nBytes();
			Line_Pos	= Cache_Offset + y * Line_Size;

			//-------------------------------------------------
			if( Cache_bSwap && m_Type != GRID_TYPE_Bit )
			{
				for(x=0, pValue=pLine->Data; x<Get_NX(); x++, pValue+=Get_nValueBytes())
				{
					_Swap_Bytes(pValue, Get_nValueBytes());
				}
			}

			Cache_Stream.Seek(Line_Pos);
			Cache_Stream.Write(pLine->Data, sizeof(char), Line_Size);
			Cache_Stream.Flush();

			if( Cache_bSwap && m_Type != GRID_TYPE_Bit )
			{
				for(x=0, pValue=pLine->Data; x<Get_NX(); x++, pValue+=Get_nValueBytes())
				{
					_Swap_Bytes(pValue, Get_nValueBytes());
				}
			}
		}
	}
}

//---------------------------------------------------------
void CSG_Grid::_Cache_LineBuffer_Load(TSG_Grid_Line *pLine, int y) const
{
	int		x, Line_Pos, Line_Size;
	char	*pValue;

	if( pLine )
	{
		pLine->bModified	= false;
		pLine->y			= y;

		if( pLine->y >= 0 && pLine->y < Get_NY() )
		{
			y			= Cache_bFlip ? Get_NY() - 1 - pLine->y : pLine->y;

			Line_Size	= _LineBuffer_Get_nBytes();
			Line_Pos	= Cache_Offset + y * Line_Size;

			//-------------------------------------------------
			Cache_Stream.Seek(Line_Pos);
			Cache_Stream.Read(pLine->Data, sizeof(char), Line_Size);

			if( Cache_bSwap && m_Type != GRID_TYPE_Bit )
			{
				for(x=0, pValue=pLine->Data; x<Get_NX(); x++, pValue+=Get_nValueBytes())
				{
					_Swap_Bytes(pValue, Get_nValueBytes());
				}
			}
		}
	}
}


///////////////////////////////////////////////////////////
//														 //
//					RTL - Compression					 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
bool CSG_Grid::Set_Compression(bool bOn)
{
	return( bOn ? _Compr_Create() : _Compr_Destroy(true) );
}

//---------------------------------------------------------
bool CSG_Grid::is_Compressed(void)
{
	return( m_Memory_Type == GRID_MEMORY_Compression );
}

//---------------------------------------------------------
double CSG_Grid::Get_Compression_Ratio(void)
{
	int		y;
	long	nCompression, nNoCompression;

	if( is_Compressed() )
	{
		for(y=0, nCompression=0; y<Get_NY(); y++)
		{
			nCompression	+= *((int *)m_Values[y]);
		}

		if( (nNoCompression = Get_NCells() * Get_nValueBytes()) > 0 )
		{
			return( (double)nCompression / (double)nNoCompression );
		}
	}

	return( 1.0 );
}


///////////////////////////////////////////////////////////
//														 //
//			RTL - Compression: Create / Destroy			 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
bool CSG_Grid::_Compr_Create(void)
{
	TSG_Grid_Line	Line;

	if( m_System.is_Valid() && m_Type > 0 && m_Type < GRID_TYPE_Count && m_Memory_Type == GRID_MEMORY_Normal )
	{
		m_Memory_bLock	= true;

		Line.Data		= (char *)SG_Calloc(1, _Get_nLineBytes());

		if( m_Values )	// compress loaded data...
		{
			for(Line.y=0; Line.y<Get_NY() && SG_UI_Process_Set_Progress(Line.y, Get_NY()); Line.y++)
			{
				memcpy(Line.Data, m_Values[Line.y], _LineBuffer_Get_nBytes());
				Line.bModified	= true;
				_Compr_LineBuffer_Save(&Line);
			}
		}
		else			// create empty grid...
		{
			m_Values	= (void **)SG_Malloc(Get_NY() * sizeof(void *));

			for(Line.y=0; Line.y<Get_NY() && SG_UI_Process_Set_Progress(Line.y, Get_NY()); Line.y++)
			{
				m_Values[Line.y]	= (void *)SG_Calloc(1, _LineBuffer_Get_nBytes());
				Line.bModified	= true;
				_Compr_LineBuffer_Save(&Line);
			}
		}

		SG_Free(Line.Data);

		_LineBuffer_Create();

		m_Memory_bLock	= false;
		m_Memory_Type	= GRID_MEMORY_Compression;

		SG_UI_Process_Set_Ready();
	}

	return( is_Compressed() );
}

//---------------------------------------------------------
bool CSG_Grid::_Compr_Destroy(bool bMemory_Restore)
{
	TSG_Grid_Line	Line;

	if( is_Valid() && m_Memory_Type == GRID_MEMORY_Compression )
	{
		m_Memory_bLock	= true;

		if( bMemory_Restore )
		{
			_LineBuffer_Flush();

			Line.Data		= (char *)SG_Calloc(1, _Get_nLineBytes());

			for(int y=0; y<Get_NY() && SG_UI_Process_Set_Progress(y, Get_NY()); y++)
			{
				_Compr_LineBuffer_Load(&Line, y);
				m_Values[y]	= (void *)SG_Realloc(m_Values[y], _Get_nLineBytes());
				memcpy(m_Values[y], Line.Data, _LineBuffer_Get_nBytes());
			}

			SG_Free(Line.Data);

			SG_UI_Process_Set_Ready();
		}
		else
		{
			_Array_Destroy();
		}

		_LineBuffer_Destroy();

		m_Memory_bLock	= false;
		m_Memory_Type	= GRID_MEMORY_Normal;

		return( true );
	}

	return( false );
}


///////////////////////////////////////////////////////////
//														 //
//			RTL - Compression: Save / Load				 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CSG_Grid::_Compr_LineBuffer_Save(TSG_Grid_Line *pLine) const
{
	char	*pResult, *pNoCompress, *pCompress, *pNext;
	int		x, ix, Threshold, nCompress, nNoCompress, nBytesTotal, Line_Pos;

	if( pLine && pLine->bModified )
	{
		pLine->bModified	= false;

		if( pLine->y >= 0 && pLine->y < Get_NY() )
		{
			Threshold	= 1 + (sizeof(WORD) + sizeof(bool) + Get_nValueBytes()) / Get_nValueBytes();

			nBytesTotal	= Line_Pos	= sizeof(nBytesTotal);
			pResult		= (char *)SG_Malloc(nBytesTotal);
			pNoCompress	= pLine->Data;
			nNoCompress	= 0;

			//---------------------------------------------
			for(x=0; x<Get_NX(); )
			{
				nCompress	= 1;
				pCompress	= pLine->Data + x * Get_nValueBytes();
				pNext		= pCompress + Get_nValueBytes();

				for(ix=x+1; ix<Get_NX(); ix++, pNext+=Get_nValueBytes())
				{
					if( memcmp(pCompress, pNext, Get_nValueBytes()) )
					{
						break;
					}
					else
					{
						nCompress++;
					}
				}

				//-----------------------------------------
				if( nCompress <= Threshold )
				{
					nNoCompress++;
					x++;
				}
				else
				{
					nBytesTotal	+= sizeof(WORD) + sizeof(bool) + Get_nValueBytes();

					if( nNoCompress > 0 )
					{
						nBytesTotal	+= sizeof(WORD) + sizeof(bool) + nNoCompress * Get_nValueBytes();
						pResult	= (char *)SG_Realloc(pResult, nBytesTotal);

						*((WORD *)(pResult + Line_Pos))	= nNoCompress;
						Line_Pos	+= sizeof(WORD);
						*((bool *)(pResult + Line_Pos))	= false;
						Line_Pos	+= sizeof(bool);

						memcpy(pResult + Line_Pos, pNoCompress, nNoCompress * Get_nValueBytes());
						Line_Pos	+= nNoCompress * Get_nValueBytes();

						nNoCompress	= 0;
					}
					else
					{
						pResult	= (char *)SG_Realloc(pResult, nBytesTotal);
					}

					*((WORD *)(pResult + Line_Pos))	= nCompress;
					Line_Pos	+= sizeof(WORD);
					*((bool *)(pResult + Line_Pos))	= true;
					Line_Pos	+= sizeof(bool);

					memcpy(pResult + Line_Pos, pCompress, Get_nValueBytes());
					Line_Pos	+= Get_nValueBytes();

					pNoCompress	= pCompress + nCompress * Get_nValueBytes();
					x			+= nCompress;
				}
			}

			//---------------------------------------------
			if( nNoCompress > 0 )
			{
				nBytesTotal	+= sizeof(WORD) + sizeof(bool) + nNoCompress * Get_nValueBytes();
				pResult	= (char *)SG_Realloc(pResult, nBytesTotal);

				*((WORD *)(pResult + Line_Pos))	= nNoCompress;
				Line_Pos	+= sizeof(WORD);
				*((bool *)(pResult + Line_Pos))	= false;
				Line_Pos	+= sizeof(bool);

				memcpy(pResult + Line_Pos, pNoCompress, nNoCompress * Get_nValueBytes());
			}

			//-------------------------------------------------
			memcpy(pResult, &nBytesTotal, sizeof(nBytesTotal));

			if( m_Values[pLine->y] )
			{
				SG_Free(m_Values[pLine->y]);
			}

			m_Values[pLine->y]	= pResult;
		}
	}
}

//---------------------------------------------------------
void CSG_Grid::_Compr_LineBuffer_Load(TSG_Grid_Line *pLine, int y) const
{
	bool	bCompressed;
	char	*pData, *pValue;
	int		x, iValue;
	WORD	nValues;

	if( pLine )
	{
		pLine->bModified	= false;
		pLine->y			= y;

		if( pLine->y >= 0 && pLine->y < Get_NY() )
		{
			pValue		= (char *)m_Values[y] + sizeof(int);
			pData		= pLine->Data;

			for(x=0; x<Get_NX(); )
			{
				nValues		= *((WORD *)pValue);
				pValue		+= sizeof(WORD);
				bCompressed	= *((bool *)pValue);
				pValue		+= sizeof(bool);

				if( bCompressed )
				{
					for(iValue=0; iValue<nValues && x<Get_NX(); iValue++, x++, pData+=Get_nValueBytes())
					{
						memcpy(pData, pValue, Get_nValueBytes());
					}

					pValue	+= Get_nValueBytes();
				}
				else
				{
					memcpy(pData, pValue, Get_nValueBytes() * nValues);
					x		+= nValues;
					pData	+= Get_nValueBytes() * nValues;
					pValue	+= Get_nValueBytes() * nValues;
				}
			}
		}
	}
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -