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

📄 quickphoto.cpp

📁 大文件管理
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 #include "quickphoto.h"
#include <sys/STAT.H>
/***********************************************************************************
函数功能:构造函数
参    数:
		  char *path:	系统路径,充分系统的保存信息已经索引节点的索引信息文件
返 回 值:无
程 序 员:乔建秀
修改时间:2003.5.8
***********************************************************************************/
QuickPhoto::QuickPhoto(char *path)
{
	pBuf = new char [2<<20];
	cpUsedNode = new iNode *[20480];
	memset(cpUsedNode,0,20480*4);	
	memset(IdleFileNode,0,20*4);
	cpUsedNode[0] = new iNode[10240];
	ppFileList = new char *[10000];
	memset(ppFileList,0,40000);
	lpFileSize = new long [10000];
	memset(lpFileSize,0,40000);
	IdleMemoryNode = NULL;
	lNowFileLeftSpace = -1;
	lNowUseFileNo = -1;
	lUsedNodeFirst = 0;
	lUsedNodeSecond = 0;
	lFileListSize = 0 ;
	strcpy(syspath,path);
	InitializeCriticalSection(&comCri);
}
/***********************************************************************************
函数功能:析构函数,释放内存
参    数:none		  
返 回 值:none
程 序 员:乔建秀
修改时间:2003.5.8
***********************************************************************************/
QuickPhoto::~QuickPhoto()
{
	long i;
	if(pBuf) delete pBuf;
	if(ppFileList)
	{
		for(i=0;i<10000;i++)
		{
			if(ppFileList[i]) delete []ppFileList[i];
		}
		delete []ppFileList;
	}
	if(lpFileSize)
		delete lpFileSize;
	if(cpUsedNode)
	{
		for(i=0;i<20480;i++)
		{
			if(cpUsedNode[i])
				delete []cpUsedNode[i];
		}
		delete []cpUsedNode;
	}
}
/***********************************************************************************
函数功能:进行文本压缩
参    数:
		  char *pPage:		压缩前的文本
		  char *buf:		压缩后的文本,作为返回值
返 回 值:成功返回0,否则返回其他
程 序 员:乔建秀
修改时间:2003.5.8
***********************************************************************************/
long QuickPhoto::CompressText(char *pPage,char *buf,long lPageLen)
{
	long lRet = -1;
	buf[0] = 0;
	EnterCriticalSection(&comCri);
	if(compress2((unsigned char *)buf,(unsigned long *)&lRet,(unsigned char *)pPage,lPageLen,1))
		lRet = -1;
	LeaveCriticalSection(&comCri);
	return lRet;
} 
/***********************************************************************************
函数功能:对压缩后的文本进行解压
参    数:
		  char *pBuf:		压缩后的文本
		  long lContentLen	压缩后文本的大小
		  char *pRetPage:	解压后的结果,作为返回值
		  long lPageLen:	解压后文本的大小
返 回 值:成功返回0,否则返回其他
程 序 员:乔建秀
修改时间:2003.5.8
***********************************************************************************/
long QuickPhoto::UnCompressText(char *pBuf,long lContentLen,char *pRetPage,long lPageLen)
{
	unsigned long lLen;
	pRetPage[0] = 0;	
	lLen = 0;
	EnterCriticalSection(&comCri);
	unsigned long l = lPageLen;
//	lContentLen = 1048576;
	//if(uncompress((unsigned char*)pRetPage, &lLen,(unsigned char*)pBuf,lContentLen))
if(uncompress((unsigned char*)pRetPage, &l,(unsigned char*)pBuf,lContentLen))
	{
//		lLen = -1;
		l = -1;
	}
	LeaveCriticalSection(&comCri);
	//return (long)lLen;
	return (long)l;
}
/***********************************************************************************
函数功能:对压缩后的文本进行解压
参    数:
		  char *pBuf:		压缩后的文本
		  long lContentLen	压缩后文本的大小
		  char *pRetPage:	解压后的结果,作为返回值
		  long lPageLen:	解压后文本的大小
返 回 值:成功返回0,否则返回其他
程 序 员:乔建秀
修改时间:2003.5.8
***********************************************************************************/
long QuickPhoto::GetAntiPage(char *sPage,char *dPage,long lPageLen,char *pSearchStr)
{
	return 0;
}
/***********************************************************************************
函数功能:根据压缩后的文件大小,计算出应该分配的节点类型
参    数:
		  long lSize:压缩后的文件大小
返 回 值:应该分配的节点类型
程 序 员:乔建秀
修改时间:2003.5.8
***********************************************************************************/
long QuickPhoto::GetNodeMode(long lSize)
{
	lSize = (lSize-1)>>8;
	long i=0;
	for(;lSize && i<12;lSize>>=1,i++);
	return i;
}
/***********************************************************************************
函数功能:从文件库中申请一块空间
参    数:
		  long lFileIdx:	申请空间类型
		  long lNum:		申请空间块个数
返 回 值:返回一个有效节点,注意,其实一共申请了lNum+1个节点
注:	  节点的申请包括从内存中申请节点和从文件中申请空间
程 序 员:乔建秀
修改时间:2003.5.8
***********************************************************************************/
iNode *QuickPhoto::AllocNode(long lFileIdx,long lNum)
{
	long lLen = 256<<lFileIdx;
	iNode *pRetNode = NULL,*pNode;
	while(lNum>=0)
	{
		pNode = NULL;
		if(lNowFileLeftSpace < lLen+10 && (lNowUseFileNo == 65535 || lNowUseFileNo < lFileListSize))
		{
			lNowUseFileNo++;
			if(lNowUseFileNo >= lFileListSize)
			{
				return pRetNode;
			}
			lNowFileLeftSpace = lpFileSize[lNowUseFileNo];
		}		
		else if(lNowUseFileNo >= lFileListSize)
			return pRetNode;

		if(IdleMemoryNode == NULL)
			pNode = &cpUsedNode[lUsedNodeFirst][lUsedNodeSecond++];
		else
		{
			pNode = IdleMemoryNode;
			IdleMemoryNode = (iNode *)pNode->lContentLen;
		}		
		if(pRetNode == NULL)
		{
			pRetNode = pNode;
			pRetNode->lContentLen = 0;
		}
		else
		{
			pNode->lContentLen = (long)IdleFileNode[lFileIdx];
			IdleFileNode[lFileIdx] = pNode;
		}
		pNode->lFileSeat = lpFileSize[lNowUseFileNo] - lNowFileLeftSpace;
		pNode->usFileNo = lNowUseFileNo;
		if(lUsedNodeSecond >= 10240)
		{
			lUsedNodeFirst++;
			lUsedNodeSecond = 0;
			if(cpUsedNode[lUsedNodeFirst] == NULL)
				cpUsedNode[lUsedNodeFirst] = new iNode[10240];
		}
		lNowFileLeftSpace -= lLen;
		lNum--;
	}
	return pRetNode;
}
/***********************************************************************************
函数功能:向系统中增加一批网页快照
参    数:
		  long lPhotoNum:		增加快照的个数
		  long *ulpUrlId:		增加的快照的Id列表
		  long *lpPageLen:		增加的快照的长度列表
		  char *pPage:			增加的快照的内容,写在一起,并且每个都有0结束符
返 回 值:成功返回0,否则返回其他
程 序 员:乔建秀
修改时间:2003.5.8
***********************************************************************************/
long QuickPhoto::AddPhoto(long lPhotoNum,unsigned long *ulpUrlId,long *lpPageLen,char *pPage)
{
	long lRet;
	long lFileIdx;
	iNode *pNode=NULL;
	FILE *fpIdx[50],*fpDat=NULL;
	memset(fpIdx,0,200);
	unsigned short usLastIdx = 0xffff;
	long i;	
	char filename[300],ch;
	long lTmp,lTmp1;
	for(i = 0;i<lPhotoNum;i++)
	{
		/*对快照进行压缩*/
		lRet = CompressText(pPage,pBuf,lpPageLen[i]);
		/*指向下一篇快照的开始*/
		pPage += lpPageLen[i];
		/* 判断压缩是否成功,或者压缩后是否超长 */
		if(lRet < 0 || lRet >= 1048576)
			continue;
		/* 判断压缩后的文件长度属于什么类型 */
		lFileIdx = GetNodeMode(lRet);

		/* 申请文件空间 */
		if(IdleFileNode[lFileIdx] != NULL)
		{
			pNode = NULL;
			do
			{
				if(pNode)
				{
					pNode->lContentLen = (long)this->IdleMemoryNode;
					this->IdleMemoryNode = pNode;
				}
				pNode = IdleFileNode[lFileIdx];
				if(pNode)
					IdleFileNode[lFileIdx] = (iNode *)pNode->lContentLen;
				if(pNode && pNode->usFileNo < this->lFileListSize && pNode->lFileSeat >= 0)
					break;
			}while(1);
		}
		if(pNode == NULL)		//没有找到,分配一批空闲节点
		{
			pNode = AllocNode(lFileIdx,1);
			if(pNode == NULL)
			{
				if(fpDat) fclose(fpDat);
				for(i=0;i<50;i++)
				{
					if(fpIdx[i]) fclose(fpIdx[i]);
				}
				return -1;
			}
		}
		/* 计算文件号和索引存放位置,每个索引16个字节,每个文件可以存放67,108,864个节点 */
		lTmp = ulpUrlId[i] >> 26;
		/* 打开对应索引文件 */
		if(fpIdx[lTmp] == NULL)
		{
			sprintf(filename,"%s%c%s%d",syspath,LINKFLAG,INDEXNODEFILE,lTmp);
			fpIdx[lTmp] = fopen(filename,"rb+");
			if(fpIdx[lTmp] == NULL)
			{
//				fpIdx[lTmp] = fopen(filename,"wb+");
//				if(fpIdx[lTmp] == NULL)
				{
					printf("打开索引文件 %s 失败\n",filename);
					for(i=0;i<10;i++)
					{
						if(fpIdx[i])
							fclose(fpIdx[i]);
					}					
					pNode->lContentLen = (long)IdleFileNode[lFileIdx];
					IdleFileNode[lFileIdx] = pNode;
					return -1;
				}
			}
		}
		//文件偏移
		lTmp1 = ulpUrlId[i] & 0x3ffffff;
		pNode->lContentLen = lRet;
		//定位
		if(fseek(fpIdx[lTmp],16 * lTmp1,0))
		{
			pNode->lContentLen = (long)IdleFileNode[lFileIdx];
			IdleFileNode[lFileIdx] = pNode;
			continue;
		}
		//加锁
		if(_locking(fpIdx[lTmp]->_file,_LK_LOCK,16) == -1)
		{
			pNode->lContentLen = (long)IdleFileNode[lFileIdx];
			IdleFileNode[lFileIdx] = pNode;
			continue;
		}
		/*16个字节*/
		if(fread(&ch,1,1,fpIdx[lTmp])!=1)
			ch = 0;
		if(fseek(fpIdx[lTmp],16 * lTmp1,0) || ch == 1)
		{//判断是否该篇已经加入			
			
			_locking(fpIdx[lTmp]->_file,_LK_UNLCK,16);
			pNode->lContentLen = (long)IdleFileNode[lFileIdx];
			IdleFileNode[lFileIdx] = pNode;
			this->DelPhoto(1,&ulpUrlId[i]);
			AddPhoto(1,&ulpUrlId[i],&lpPageLen[i],pPage-lpPageLen[i]);
			continue;
		}
		ch = 1;
		fwrite(&ch,1,1,fpIdx[lTmp]);		//节点是否有效的标志
		ch = (char)lFileIdx ;				
		fwrite(&ch,1,1,fpIdx[lTmp]);		//节点类型
		fwrite(&pNode->lContentLen,4,1,fpIdx[lTmp]);	//压缩后文件长度
		fwrite(&lpPageLen[i],4,1,fpIdx[lTmp]);			//压缩前文章长度
		fwrite(&pNode->usFileNo,2,1,fpIdx[lTmp]);		//压缩后文本所在文件
		fwrite(&pNode->lFileSeat,4,1,fpIdx[lTmp]);		//文本偏移
		//定位到加锁位置准备解锁
		fseek(fpIdx[lTmp],16 * lTmp1,0);
		//打开存放对应快照的文件
		if(usLastIdx != pNode->usFileNo || fpDat == NULL)
		{
			if(fpDat) fclose(fpDat);
			fpDat = fopen(ppFileList[pNode->usFileNo],"rb+");
			if(fpDat == NULL)
			{
				_locking(fpIdx[lTmp]->_file,_LK_UNLCK,16);
				pNode->lContentLen = (long)IdleMemoryNode;
				IdleMemoryNode = pNode;
				continue;
			}
			usLastIdx = pNode->usFileNo;
		}
		fseek(fpDat,pNode->lFileSeat,0);
		fwrite(pBuf,1,lRet,fpDat);
		_locking(fpIdx[lTmp]->_file,_LK_UNLCK,16);
		pNode->lContentLen = (long)IdleMemoryNode;
		IdleMemoryNode = pNode;
	}	
	if(fpDat) fclose(fpDat);
	for(i=0;i<50;i++)
	{
		if(fpIdx[i]) fclose(fpIdx[i]);
	}
	return 0;
}
/***********************************************************************************
函数功能:从系统中删除一批网页快照
参    数:
		  long lDelNum:			要删除的网页快照的个数
		  long *ulpUrlId:		增加的快照的Id列表
返 回 值:成功返回0,否则返回其他
程 序 员:乔建秀
修改时间:2003.5.8
***********************************************************************************/
long QuickPhoto::DelPhoto(long lDelNum,unsigned long *ulUrlId)
{
	unsigned short usLastNo = 0xffff,usFileNo;
	long i,lFileSeat;
	FILE *fpIdx = NULL;
	char filename[300],cFlag;
	iNode *pNode = NULL;
	for(i=0;i<lDelNum;i++)
	{
		//计算文件号
		usFileNo = (unsigned short)(ulUrlId[i]>>26);
		//计算偏移

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -