📄 selfdb.cpp.svn-base
字号:
file.Close();
return ::DeleteFile( lpszFileName );
}
}
return FALSE;
}
static CSPMutex g_mutexClkFile;
BOOL CClkFile::EmptyAll( )
{
CSPMutex::Scoped locker(g_mutexClkFile);
SP_ASSERT( CSPFile::hFileNull != m_file.m_hFile );
if( CSPFile::hFileNull == m_file.m_hFile )
return FALSE;
// 顺序寻找
DWORD dwCount = 0;
for( DWORD i=0; i<m_header.m_dwIndexRecordCount; i++ )
{
DWORD dwPosIndex = m_header.m_dwPosFirstIndex + m_header.m_dwIndexRecordSize * i;
if( m_file.GetPosition() != dwPosIndex )
m_file.Seek( dwPosIndex, CSPFile::begin );
CLK_INDEXRECORD index;
if( sizeof(index) != m_file.Read(&index,sizeof(index)) )
return FALSE;
if( CLK_INDEXRECORD_MAGIC != index.m_dwMagic )
return FALSE;
if( strlen(index.m_szCode) <= 0 )
continue;
EmptyBlockChain( index.m_dwPosFirstBlock );
index.m_dwDataRecordCountTotal = 0;
m_file.Seek( dwPosIndex, CSPFile::begin );
m_file.Write( &index, sizeof(index) );
dwCount ++;
}
m_file.Flush();
SP_ASSERT( dwCount == m_header.m_dwStockCount );
return dwCount > 0; // == m_header.m_dwStockCount;
}
// 保存数据,并修改相应索引信息
DWORD CClkFile::StoreDataRecord(DWORD dwMarket, const char * szCode,
void * pData, DWORD dwDataElementSize, DWORD dwDataElementCount,
BOOL bOverWrite ) // 返回成功保存记录数
{
CSPMutex::Scoped locker(g_mutexClkFile);
SP_ASSERT( CSPFile::hFileNull != m_file.m_hFile );
if( CSPFile::hFileNull == m_file.m_hFile )
return 0;
CLK_INDEXRECORD index;
DWORD dwPosIndexFind = -1;
if( !GetDataInfo( dwMarket, szCode, index, dwPosIndexFind, TRUE ) )
return 0;
if( bOverWrite )
{
EmptyBlockChain( index.m_dwPosFirstBlock );
index.m_dwDataRecordCountTotal = 0;
}
if( -1 == index.m_dwPosFirstBlock || 0 == index.m_dwPosFirstBlock )
index.m_dwPosFirstBlock = GetFirstBlankBlockPos( TRUE, TRUE );
DWORD dwCount = WriteData( index.m_dwPosFirstBlock, pData, dwDataElementSize, dwDataElementCount, FALSE );
index.m_dwDataRecordCountTotal += dwCount;
SetDataInfo( dwPosIndexFind, index, FALSE );
// m_file.Flush();
return dwCount;
}
// 得到某一股票的数据记录数
DWORD CClkFile::GetDataRecordCount( DWORD dwMarket, const char * szCode )
{
CSPMutex::Scoped locker(g_mutexClkFile);
CLK_INDEXRECORD index;
DWORD dwPosIndexFind = -1;
if( GetDataInfo( dwMarket, szCode, index, dwPosIndexFind, FALSE ) )
return index.m_dwDataRecordCountTotal;
return 0;
}
// 读取某一股票的数据记录
DWORD CClkFile::LoadDataRecord( DWORD dwMarket, const char * szCode,
void * pData, DWORD dwDataElementSize, DWORD dwMaxDataElement )// 返回成功读取记录数
{
CSPMutex::Scoped locker(g_mutexClkFile);
SP_ASSERT( CSPFile::hFileNull != m_file.m_hFile );
if( CSPFile::hFileNull == m_file.m_hFile )
return 0;
CLK_INDEXRECORD index;
DWORD dwPosIndexFind = -1;
if( !GetDataInfo( dwMarket, szCode, index, dwPosIndexFind, FALSE ) )
return 0;
if( dwMaxDataElement < index.m_dwDataRecordCountTotal )
return 0;
return ReadData( index.m_dwPosFirstBlock, pData, dwDataElementSize, dwMaxDataElement );
}
DWORD CClkFile::Hash( LPCTSTR key, DWORD dwMax )
{
DWORD dwHash = 0;
while (*key)
dwHash = (dwHash<<5) + dwHash + *key++;
return dwHash % dwMax;
}
// 得到某一股票的索引区信息,如果bAddIfNotExists并且不存在,则添加
BOOL CClkFile::GetDataInfo( DWORD dwMarket, const char * szCode, CLK_INDEXRECORD & idxRet, DWORD & dwPosIndexFind, BOOL bAddIfNotExists )
{
SP_ASSERT( CSPFile::hFileNull != m_file.m_hFile );
if( CSPFile::hFileNull == m_file.m_hFile )
return FALSE;
// 是否当前Cache
if( m_CurIndexRecord.m_dwMarket == dwMarket
&& 0 == strcmp( m_CurIndexRecord.m_szCode, szCode ) )
{
idxRet = m_CurIndexRecord;
dwPosIndexFind = m_dwPosCurIndex;
return TRUE;
}
DWORD posBegin = Hash( szCode, m_header.m_dwIndexRecordCount );
// Hash顺序寻找
for( DWORD i=posBegin; i<m_header.m_dwIndexRecordCount; i++ )
{
DWORD dwPosIndex = m_header.m_dwPosFirstIndex + m_header.m_dwIndexRecordSize * i;
if( m_file.GetPosition() != dwPosIndex )
m_file.Seek( dwPosIndex, CSPFile::begin );
CLK_INDEXRECORD index;
if( sizeof(index) != m_file.Read(&index,sizeof(index))
|| CLK_INDEXRECORD_MAGIC != index.m_dwMagic )
{
SP_ASSERT( FALSE );
return FALSE;
}
if( dwMarket == index.m_dwMarket
&& 0 == strcmp( szCode, index.m_szCode ) )
{
idxRet = index;
dwPosIndexFind = dwPosIndex;
m_CurIndexRecord = index;
m_dwPosCurIndex = dwPosIndex;
return TRUE;
}
if( 0 == strlen(index.m_szCode) )
{
if( bAddIfNotExists )
{
index.m_dwMarket = dwMarket;
strncpy( index.m_szCode, szCode, min(sizeof(index.m_szCode)-1,strlen(szCode)) );
index.m_dwDataRecordCountTotal = 0;
index.m_dwPosFirstBlock = GetFirstBlankBlockPos( TRUE, TRUE );
m_file.Seek( dwPosIndex, CSPFile::begin );
m_file.Write( &index, sizeof(index) );
// 文件头
m_header.m_dwStockCount += 1;
m_file.Seek( 0, CSPFile::begin );
m_file.Write( &m_header, sizeof(m_header) );
// m_file.Flush();
// return
idxRet = index;
dwPosIndexFind = dwPosIndex;
m_CurIndexRecord = index;
m_dwPosCurIndex = dwPosIndex;
return TRUE;
}
return FALSE;
}
// 循环
if( m_header.m_dwIndexRecordCount-1 == i )
i = -1;
if( posBegin-1 == i )
break;
}
return FALSE;
}
// 保存某一股票的索引区信息
BOOL CClkFile::SetDataInfo( DWORD dwPosIndex, CLK_INDEXRECORD idx, BOOL bFlush )
{
SP_ASSERT( CSPFile::hFileNull != m_file.m_hFile );
if( CSPFile::hFileNull == m_file.m_hFile )
return FALSE;
// 是否当前Cache
if( m_CurIndexRecord.m_dwMarket == idx.m_dwMarket
&& 0 == strcmp( m_CurIndexRecord.m_szCode, idx.m_szCode ) )
{
m_CurIndexRecord = idx;
}
if( -1 != dwPosIndex )
{
m_file.Seek( dwPosIndex, CSPFile::begin );
m_file.Write( &idx, sizeof(idx) );
if( bFlush )
m_file.Flush();
return TRUE;
}
return FALSE;
}
// 得到某一空数据块
DWORD CClkFile::GetFirstBlankBlockPos( BOOL bAddIfNotExists, BOOL bUseIt )
{
SP_ASSERT( CSPFile::hFileNull != m_file.m_hFile );
if( CSPFile::hFileNull == m_file.m_hFile )
return -1;
DWORD dwPosBlock = m_header.m_dwPosFirstBlankBlock;
if( -1 != dwPosBlock && 0 != dwPosBlock )
{
m_file.Seek( dwPosBlock, CSPFile::begin );
CLK_BLOCKHEADER bheader;
if( sizeof(bheader) == m_file.Read(&bheader,sizeof(bheader)) )
{
SP_ASSERT( CLK_BLOCKHEADER_MAGIC == bheader.m_dwMagic );
SP_ASSERT( !bheader.m_bUsed );
if( bUseIt )
{
bheader.m_bUsed = bUseIt;
bheader.m_dwDataRecordCount = 0;
bheader.m_dwPosNextBlock = -1;
m_file.Seek( dwPosBlock, CSPFile::begin );
m_file.Write( &bheader, sizeof(bheader) );
m_header.m_dwPosFirstBlankBlock = bheader.m_dwPosNextBlock;
m_file.Seek( 0, CSPFile::begin );
m_file.Write( &m_header, sizeof(m_header) );
// m_file.Flush();
}
return dwPosBlock;
}
}
// Add
if( bAddIfNotExists )
{
SP_ASSERT( bUseIt ); // Must Use It
DWORD dwDataSize = m_header.m_dwDataRecordSize*m_header.m_dwRecordPerBlock;
if( dwDataSize <= 0 )
return -1;
m_file.SeekToEnd( );
dwPosBlock = m_file.GetPosition();
CLK_BLOCKHEADER bheader;
memset( &bheader, 0, sizeof(bheader) );
bheader.m_dwMagic = CLK_BLOCKHEADER_MAGIC;
bheader.m_bUsed = bUseIt;
bheader.m_dwPosNextBlock = -1;
bheader.m_dwPosFirstRecord = dwPosBlock + sizeof(bheader);
m_file.Write( &bheader, sizeof(bheader) );
char * temp = new char[dwDataSize];
if( !temp )
return -1;
memset( temp, 0, m_header.m_dwDataRecordSize );
m_file.Write( temp, dwDataSize );
delete [] temp;
// m_file.Flush();
}
return dwPosBlock;
}
// 清空数据Block链中的数据,并将除第一个Block外的其他Block置为未用
DWORD CClkFile::EmptyBlockChain( DWORD dwPosFirstBlock )
{
SP_ASSERT( CSPFile::hFileNull != m_file.m_hFile );
if( CSPFile::hFileNull == m_file.m_hFile )
return FALSE;
DWORD dwCount = 0;
DWORD dwPosBlock = dwPosFirstBlock;
while( -1 != dwPosBlock && 0 != dwPosBlock )
{
m_file.Seek( dwPosBlock, CSPFile::begin );
DWORD dwPosNextBlock = -1;
CLK_BLOCKHEADER bheader;
if( sizeof(bheader) != m_file.Read(&bheader,sizeof(bheader))
|| CLK_BLOCKHEADER_MAGIC != bheader.m_dwMagic )
{
SP_ASSERT( FALSE );
}
else
{
dwPosNextBlock = bheader.m_dwPosNextBlock;
}
// Empty it
bheader.m_bUsed = (dwPosFirstBlock == dwPosBlock); // 第一块继续使用
bheader.m_dwDataRecordCount = 0;
bheader.m_dwPosNextBlock = -1;
if( !bheader.m_bUsed )
bheader.m_dwPosNextBlock = m_header.m_dwPosFirstBlankBlock;
m_file.Seek( dwPosBlock, CSPFile::begin );
m_file.Write( &bheader, sizeof(bheader) );
// 加入Blank Block Chain
if( !bheader.m_bUsed )
{
m_header.m_dwPosFirstBlankBlock = dwPosBlock;
m_file.Seek( 0, CSPFile::begin );
m_file.Write( &m_header, sizeof(m_header) );
}
// m_file.Flush();
dwCount ++;
dwPosBlock = dwPosNextBlock;
}
return dwCount;
}
// 读数据记录
DWORD CClkFile::ReadData( DWORD dwPosBlock, void * pData, DWORD dwDataElementSize, DWORD dwMaxDataElement )
{
SP_ASSERT( CSPFile::hFileNull != m_file.m_hFile );
if( CSPFile::hFileNull == m_file.m_hFile )
return FALSE;
if( NULL == pData || dwMaxDataElement == 0 )
return 0;
DWORD dwCount = 0;
while( -1 != dwPosBlock && 0 != dwPosBlock )
{
m_file.Seek( dwPosBlock, CSPFile::begin );
CLK_BLOCKHEADER bheader;
if( sizeof(bheader) != m_file.Read(&bheader,sizeof(bheader))
|| CLK_BLOCKHEADER_MAGIC != bheader.m_dwMagic )
{
SP_ASSERT( FALSE );
return dwCount;
}
for( DWORD i=0; i<bheader.m_dwDataRecordCount; i++ )
{
DWORD dwPos = bheader.m_dwPosFirstRecord + i * m_header.m_dwDataRecordSize;
if( m_file.GetPosition() != dwPos )
m_file.Seek( dwPos, CSPFile::begin );
m_file.Read( ((BYTE *)pData)+dwDataElementSize*dwCount, min(dwDataElementSize,m_header.m_dwDataRecordSize) );
dwCount ++;
if( dwCount >= dwMaxDataElement )
return dwCount;
}
dwPosBlock = bheader.m_dwPosNextBlock;
}
return dwCount;
}
// 写数据记录
DWORD CClkFile::WriteData( DWORD dwPosBlock, void * pData, DWORD dwDataElementSize, DWORD dwDataElementCount, BOOL bFlush )
{
SP_ASSERT( CSPFile::hFileNull != m_file.m_hFile );
if( CSPFile::hFileNull == m_file.m_hFile )
return 0;
SP_ASSERT( -1 != dwPosBlock && 0 != dwPosBlock );
if( -1 == dwPosBlock || 0 == dwPosBlock )
return 0;
DWORD dwCount = 0;
while( dwCount < dwDataElementCount && -1 != dwPosBlock && 0 != dwPosBlock )
{
m_file.Seek( dwPosBlock, CSPFile::begin );
CLK_BLOCKHEADER bheader;
if( sizeof(bheader) != m_file.Read(&bheader,sizeof(bheader))
|| CLK_BLOCKHEADER_MAGIC != bheader.m_dwMagic )
{
SP_ASSERT( FALSE );
return dwCount;
}
if( -1 != bheader.m_dwPosNextBlock && 0 != bheader.m_dwPosNextBlock )
{
SP_ASSERT( bheader.m_dwDataRecordCount == m_header.m_dwRecordPerBlock );
if( bheader.m_dwDataRecordCount == m_header.m_dwRecordPerBlock )
{
dwPosBlock = bheader.m_dwPosNextBlock;
continue;
}
}
// Write
DWORD dwCountOld = dwCount;
for( DWORD i=bheader.m_dwDataRecordCount; i<m_header.m_dwRecordPerBlock; i++ )
{
DWORD dwPos = bheader.m_dwPosFirstRecord + i * m_header.m_dwDataRecordSize;
if( m_file.GetPosition() != dwPos )
m_file.Seek( dwPos, CSPFile::begin );
m_file.Write( ((BYTE *)pData)+dwDataElementSize*dwCount, min(dwDataElementSize,m_header.m_dwDataRecordSize) );
dwCount ++;
if( dwCount >= dwDataElementCount )
break;
}
// 修改Block Header
bheader.m_bUsed = TRUE;
bheader.m_dwDataRecordCount += (dwCount-dwCountOld);
bheader.m_dwPosNextBlock = -1;
if( dwCount < dwDataElementCount )
bheader.m_dwPosNextBlock = GetFirstBlankBlockPos( TRUE, TRUE );
m_file.Seek( dwPosBlock, CSPFile::begin );
m_file.Write( &bheader, sizeof(bheader) );
// 新Block
dwPosBlock = bheader.m_dwPosNextBlock;
}
if( bFlush )
m_file.Flush();
return dwCount;
}
/////////////////////////////////////////////////////////////////////////////////////
// class CSelfDB
CSelfDB::CSelfDB( const char * rootpath, BOOL bOK )
: CQianlong( rootpath, bOK )
{
}
CSelfDB::~CSelfDB( )
{
}
CSPString CSelfDB::GetNewsPath( DWORD dwMarket )
{
CSPString strPath = AfxGetProfile().GetSelfDBPath();
strPath += self_news;
return strPath;
}
CSPString CSelfDB::GetBasePath( DWORD dwMarket )
{
CSPString strPath = AfxGetProfile().GetSelfDBPath();
switch( dwMarket )
{
case CStock::marketSHSE:
strPath += ml_sh_base;
break;
case CStock::marketSZSE:
strPath += ml_sz_base;
break;
default:
strPath += ml_sh_base;
SP_ASSERT( FALSE );
}
return strPath;
}
BOOL CSelfDB::CreateSelfDB( const char * rootpath )
{
if( NULL == rootpath || strlen(rootpath) == 0 )
return FALSE;
// get rootpath
CSPString strRoot = rootpath;
int nLen = strRoot.GetLength();
if( strRoot[nLen-1] != '\\' && strRoot[nLen-1] != '/' )
strRoot += CHAR_DIRSEP;
nLen = strRoot.GetLength();
if( 0 != access( strRoot, 0 ) )
return FALSE;
if( 0 != access( strRoot + ml_dat, 0 ) )
mkdir( strRoot + ml_dat );
if( 0 != access( strRoot + ml_data, 0 ) )
mkdir( strRoot + ml_data );
if( 0 != access( strRoot + ml_sh, 0 ) )
mkdir( strRoot + ml_sh );
if( 0 != access( strRoot + ml_sh_base, 0 ) )
mkdir( strRoot + ml_sh_base );
if( 0 != access( strRoot + ml_sh_month, 0 ) )
mkdir( strRoot + ml_sh_month );
if( 0 != access( strRoot + ml_sh_week, 0 ) )
mkdir( strRoot + ml_sh_week );
if( 0 != access( strRoot + ml_sh_day, 0 ) )
mkdir( strRoot + ml_sh_day );
if( 0 != access( strRoot + ml_sh_min, 0 ) )
mkdir( strRoot + ml_sh_min );
if( 0 != access( strRoot + self_sh_xdr, 0 ) )
mkdir( strRoot + self_sh_xdr );
if( 0 != access( strRoot + ml_sz, 0 ) )
mkdir( strRoot + ml_sz );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -