?? selfdb.cpp
字號:
if (CLK_FHEADER_VERMAJOR == file.m_header.m_dwVerMajor
&& CLK_FHEADER_VERMINOR == file.m_header.m_dwVerMinor) // 版本相同
{
if (ft.GetYear() == tNow.GetYear() && ft.GetMonth() == tNow.GetMonth() && ft.GetDay() == tNow.GetDay())
return FALSE;
int nDayOfWeek = tNow.GetDayOfWeek();
if (1 == nDayOfWeek || 7 == nDayOfWeek)
return FALSE;
BOOL bEmpty = FALSE; // file.EmptyAll();
file.Close();
if (!bEmpty)
return ::DeleteFile(lpszFileName);
return TRUE;
}
else
{
file.Close();
return ::DeleteFile(lpszFileName);
}
}
return FALSE;
}
static CSPMutex g_mutexClkFile;
BOOL CTSKFile::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 CTSKFile::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 CTSKFile::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 CTSKFile::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 CTSKFile::Hash(LPCTSTR key, DWORD dwMax)
{
DWORD dwHash = 0;
while (*key)
dwHash = (dwHash<<5) + dwHash + *key++;
return dwHash % dwMax;
}
// 得到某一股票的索引區信息,如果bAddIfNotExists并且不存在,則添加
BOOL CTSKFile::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 CTSKFile::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 CTSKFile::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 CTSKFile::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 CTSKFile::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 CTSKFile::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;
}
//=============================================================================
// CSelfDB
CSelfDB::CSelfDB(const char * rootpath, BOOL bOK) : CQianlong(rootpath, bOK)
{
}
CSelfDB::~CSelfDB()
{
}
BOOL CSelfDB::GetFileName(CSPString& sFileName, int nDataType, CStockInfo* pInfo, int nKType)
{
if (nDataType == CStock::dataOutline)
{
sFileName = GetRootPath();
sFileName += self_outline;
return TRUE;
}
if (pInfo== NULL || !pInfo->IsValidStock())
return FALSE;
// 如果錢龍文件存在,就返回錢龍文件名
CSPString sFileNameQL;
if (CStock::dataDR != nDataType
&& CQianlong::GetFileName(sFileNameQL, nDataType, pInfo, nKType)
&& access(sFileNameQL,0) == 0)
{
sFileName = sFileNameQL;
return TRUE;
}
// 確定市場類型
if (pInfo->GetMarket() == CStock::marketUnknown)
pInfo->ResolveTypeAndMarket();
// 如果在 ml_sh 目錄下找到文件,就返回找到的文件名
// 否則,若錢龍文件名長度大于0,就返回錢龍文件名,等于0就返回 ml_sh 下的文件名
if (nDataType == CStock::dataBasetext)
{
sFileName = GetRootPath();
sFileName += ml_sh_base;
sFileName += CSPString(pInfo->GetStockCode()) + ml_ext_base;
if (access(sFileName, 0) != 0 && sFileNameQL.GetLength() > 0)
sFileName = sFileNameQL;
return TRUE;
}
else if (nDataType == CStock::dataK)
{
sFileName = GetRootPath();
sFileName += ml_sh;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -