📄 quickphoto.cpp
字号:
#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 + -