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

📄 selfdb.cpp.svn-base

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