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

📄 selfdb.cpp

📁 股票软件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		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 + -