📄 grid_memory.cpp
字号:
}
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 + -