?? audcreindex.cpp
字號:
/* 根據查重關鍵字格式化輸出 */
/* 索引文件格式 msisdn+skey1+skye2 */
void formatKey(char * buf,char * callDate,int pos,int key1,int key2)
{
sprintf(buf,"%05d%04d %2.2s%04d %09d\n",key1/10000,pos,callDate+8,key1%10000,key2);
buf[27]='\0';
}
/* 根據通話日期判斷屬于哪個循環次數 */
int checkDate(char * callDate,char * indexPath,char * idxNamePrefix)
{
int k;
for(k=0;k<1280;k++){
if(strlen(pIndexName[k].callDate) == 0){
memcpy(pIndexName[k].callDate,callDate,10);
pIndexName[k].callDate[10] = '\0';
totalIndexFiles++;
return k;
}
if(strncmp(pIndexName[k].callDate,callDate,10) == 0) return k;
}
return -1;
}
/* 每一個循環結束輸出索引數據到臨時目錄下 */
/* 索引文件格式 msisdn+skey1+skye2 */
void writeIndexToBuf(int loopTimes,char * tmpPath,char * idxNamePrefix)
{
int k,i,n;
char fullPathName[128+1];
FILE * fpIdx;
typeMoreKeyList * p;
typeOneKeyList * tp;
char buf[128+1];
for(k=loopTimes*MAXLOADINDEXNUMB+0;k<loopTimes*MAXLOADINDEXNUMB+MAXLOADINDEXNUMB;k++){
if( strlen(pIndexName[k].callDate) == 0 ) continue;
p = pIndexName[k].pMoreKeyList;
memset(fullPathName,0,sizeof(fullPathName));
if ((strncmp(orgfileName,"p",1) == 0) || (strncmp(orgfileName,"m",1) == 0))
sprintf(fullPathName,"%s/%s%10.10s.idx01",tmpPath,idxNamePrefix,pIndexName[k].callDate);
if ((strncmp(orgfileName,"q",1) == 0) || (strncmp(orgfileName,"w",1) == 0))
sprintf(fullPathName,"%s/%s%10.10s.idx02",tmpPath,idxNamePrefix,pIndexName[k].callDate);
if( (fpIdx=fopen(fullPathName,"w")) == NULL){
memset(buf,0,sizeof(buf));
sprintf(buf,"Can't write index file %s to tmp path!\n",fullPathName);
throw (char *)buf;
}
/* 依次循環從0-9999 */
for(i=0;i<10000;i++){
/* 書寫定長數組存貯的關鍵字 */
for(n=0;n<4*ONEDAYONEUSERCDR;n++){
if((p[i].pKeyArray[n]).key1 == 0 && (p[i].pKeyArray[n]).key2 == 0)
break;
memset(buf,0,sizeof(buf));
formatKey(buf,pIndexName[k].callDate,i,(p[i].pKeyArray[n]).key1,(p[i].pKeyArray[n]).key2);
fputs(buf,fpIdx);
}
/* 書寫動態鏈表存貯的關鍵字 */
for(tp=p[i].pKeyList;tp!=NULL;tp=tp->p){
memset(buf,0,sizeof(buf));
formatKey(buf,pIndexName[k].callDate,i,tp->key1,tp->key2);
fputs(buf,fpIdx);
}
}
fclose(fpIdx);
}
}
/* 刪除索引所占空間 */
void delIndexBuf(int loopTimes)
{
int k;
int i;
typeMoreKeyList * tp;
typeOneKeyList * mp;
typeOneKeyList * lp;
for(k=loopTimes*MAXLOADINDEXNUMB+0;k<loopTimes*MAXLOADINDEXNUMB+MAXLOADINDEXNUMB;k++){
if( strlen(pIndexName[k].callDate) == 0 ) continue;
tp = pIndexName[k].pMoreKeyList ;
for(i=0;i<10000;i++){
mp=tp[i].pKeyList;
while(mp!=NULL){
lp = mp;
mp = mp->p;
delete lp;
lp = NULL;
}
}
delete [] tp;
pIndexName[k].pMoreKeyList = NULL;
}
}
/* 針對一個文件查重具體實現邏輯 */
void checkDupFile(char * fullPathName,char * tmpPath,char * indexPath,char * errorPath,char * idxNamePrefix)
{
char errFileName[128+1];
char tmpFileName[128+1];
char indexFileName[128+1];
char fileName[128+1];
char oriFileName[24+1];
char buf[384+1];
int totalRecord;
int validRecord;
int retValue;
char callDate[14+1];
char msisdn[11+1];
char otherParty[24+1];
int loopTimes;
int k;
int i;
char tmpBuf[16+1];
int pos;
char sKey1[9+1];
char sKey2[9+1];
clock_t startClock,stopClock;
FILE * fpErr; /* 錯單文件 */
FILE * fpTmp; /* 臨時文件 */
FILE * fp; /* 輸入文件 */
/* 去掉文件名尾.lst */
memset(fileName,0,sizeof(fileName));
baseName(fileName,fullPathName);
fileName[strlen(fileName)-4]='\0';
if( (fp=fopen(fullPathName,"r")) == NULL ){
writeLog(&pLogBuf,"Can't open %s for read input!\n",fullPathName);
throw (char *)"Open File Fail!";
}
memset(tmpFileName,0,sizeof(tmpFileName));
sprintf(tmpFileName,"%s/%s.chk",tmpPath,fileName);
if( (fpTmp=fopen(tmpFileName,"w")) == NULL ){
writeLog(&pLogBuf,"Can't open %s for write tmp!\n",tmpFileName);
throw (char *)"Open File Fail!";
}
memset(errFileName,0,sizeof(errFileName));
sprintf(errFileName,"%s/%s.dup",tmpPath,fileName);
if( (fpErr=fopen(errFileName,"w")) == NULL ){
writeLog(&pLogBuf,"Can't open %s for write error!\n",errFileName);
throw (char *)"Open File Fail!";
}
/* 初始化計數器 */
totalRecord = 0;
validRecord = 0;
startClock = clock();
// 初始化日志輸出記錄
memset(pLogCkDpBuf,0,1024 * sizeof(typeChkDupLogBuf));
totalLogBuf = 0;
/* 初始化索引文件名緩沖 */
for(k=0;k<1280;k++){
memset(pIndexName[k].callDate,0,sizeof(pIndexName[k].callDate));
pIndexName[k].pMoreKeyList = NULL;
}
totalIndexFiles = 0;
/* 循環次數初始化為0 */
/* 引入循環次數是考慮極端情況 */
/* 防止申請內存不夠,一次只申請存貯7天的索引數據 */
loopTimes = 0;
do{
/* 處理前先將文件指針移到文件頭 */
fseek(fp,0L,SEEK_SET);
//writeLog("Loop One %d\n",loopTimes);
while(memset(buf,0,sizeof(buf)),fgets(buf,280,fp)!=NULL){
/* 去掉字符串末尾的換行符 */
if( buf[strlen(buf)-1]=='\n' ) buf[strlen(buf)-1]='\0';
//printf("buf=%s\n",buf);
subStrCpy(oriFileName,buf,86,24);
memset(callDate,0,sizeof(callDate));
subStrCpy(callDate,buf,43,14);
/* 不在本次循環處理范圍內 */
if((k=checkDate(callDate,indexPath,idxNamePrefix))/MAXLOADINDEXNUMB != loopTimes) continue;
/* 該通話日期第一條清單,初始化索引 */
if( pIndexName[k].pMoreKeyList == NULL) {
//writeLog("Read Index File %8.8s ...\n",callDate);
readIndexFile(callDate,indexPath,&(pIndexName[k].pMoreKeyList),idxNamePrefix);
//writeLog("Read Index File %10.10s Finished...\n",callDate);
}
totalRecord++;
subStrCpy(msisdn,buf,4,11);
rtrim(msisdn);
/* 確定下標,4位msisdn */
subStrCpy(tmpBuf,msisdn,7,4);
pos = atoi(tmpBuf);
/* 拼寫查重關鍵字 sKey1 = msisdn(5)+callTime(4) */
memset(sKey1,0,sizeof(sKey1));
sprintf(sKey1,"%5.5s%4.4s",msisdn+2,callDate+10);
sKey1[9]='\0';
/* 拼寫查重關鍵字 sKey2 = otherParty+2(7) */
memset(sKey2,0,sizeof(sKey2));
if((strncmp(orgfileName,"m",1) == 0)||(strncmp(orgfileName,"w",1) == 0)){
if(strncmp(&buf[19],"0000",4) == 0){
sprintf(sKey2,"00%7.7s",buf+23);
}
else if((strncmp(&buf[19],"000",3) == 0)||(strncmp(&buf[19],"010",3) == 0)||
(strncmp(&buf[19],"02", 2) == 0)){
sprintf(sKey2,"0%8.8s",buf+22);
}
else if(strncmp(&buf[19],"00",2) == 0){
sprintf(sKey2,"%9.9s",buf+21);
}
else if(strncmp(&buf[19],"0",1 ) == 0){
sprintf(sKey2,"00%7.7s",buf+23);
}
else if(strncmp(&buf[19],"13",2) == 0){
sprintf(sKey2,"%9.9s",buf+21);
}
else{
sprintf(sKey2,"00%7.7s",buf+19);
}
}
else{
sprintf(sKey2,"%9.9s",buf+21);
}
//subStrCpy(sKey2,buf,21,9);
sKey2[9]='\0';
/* 對關鍵字二進行檢查 */
for(i=0;i<9;i++){
if( sKey2[i]>'9'||sKey2[i]<'0' ) sKey2[i] = '0';
}
/* 檢查是否為重單 */
if( addToIndexList(pIndexName[k].pMoreKeyList,pos,sKey1,sKey2) < 0){
fprintf(fpErr,"E%03d:%s",(-1)*ERROR_DUP_CDR,buf);
addToLogBuf(oriFileName,1);
continue;
}
addToLogBuf(oriFileName,0);
fputs(buf,fpTmp);
fputs("\n",fpTmp);
validRecord++;
}
writeIndexToBuf(loopTimes,tmpPath,idxNamePrefix);
delIndexBuf(loopTimes);
loopTimes++;
} while (loopTimes * MAXLOADINDEXNUMB < totalIndexFiles);
/* 輸出日志,依次為文件名,總話單數,正確話單數,錯誤話單數 */
writeLog(&pLogBuf,"Process File %s,%d,%d,%d\n",fileName,totalRecord,validRecord,(totalRecord-validRecord));
fclose(fpErr);
fclose(fpTmp);
fclose(fp);
stopClock=clock();
writeLog(&pLogBuf,"Record %9d Speed %12.02f\n",totalRecord,totalRecord/((float)(stopClock-startClock)/CLOCKS_PER_SEC));
/* 記錄對應于原始清單的日志 */
for(i=0;i<1024;i++) {
if( strlen(pLogCkDpBuf[i].origenName) == 0 ) break;
writeLog(&pLogBuf,"orifiles,%s,%s,%d,%d,%d\n",fileName,pLogCkDpBuf[i].origenName,\
pLogCkDpBuf[i].totalNum,pLogCkDpBuf[i].curNum,pLogCkDpBuf[i].totalNum-pLogCkDpBuf[i].curNum);
}
}
/* 主函數實現 */
int main(int argc,char * argv[])
{
/* 通用變量定義部分 */
/* 配置參數和日志定義 */
typeCfgParam pCfgParam[128]; // 程序運行配置文件內容鏈表
typeFileList pFileList[1024];
/* 程序調度狀態 */
/* 0 正常,1 重新初始化數據,2 退出 */
int programStatu;
char fullPathName[128+1];
char tmpBuf[128+1];
char fileName[128+1];
int k;
/* 對計費系統程序命名進行統一編碼 */
/* 用于對配置文件描述,日志進行匹配 */
/* 該處必須填寫,如標準批價為rate */
char programName[32+1]="audCreIndex";
/* 命令行參數檢查 */
if(argc != 2){
printf("Usage: %s configureFileName \n",argv[0]);
exit(0);
}
/* 根據第一個輸入參數打開配置文件 */
if( openCfgFile(pCfgParam,argv[1]) ){
printf("Can't open %s for read configure!\n",argv[1]);
exit(0);
}
/* 從配置文件讀取相關配置參數 */
if( readCfgFile(argv[1],pCfgParam) ){
printf("Read configure fail!\n");
exit(0);
}
/* 如果運行參數為守護進程方式,進入守護進程 */
if ( runFlag == 1 || runFlag == 3 )
daemonInit();
/* 考慮查重程序并發可能性,追加處理單位 */
strcat(programName,idxNamePrefix);
/* 如果初始化日志輸出不成功,程序退出 */
if( initLogFile(&pLogBuf,logPath,(char *)programName,procID) ){
printf("Can't init logBuf %s,error msg: %s \n",logPath,strerror(errno));
exit(1);
}
redoHandler((char *)programName);
/* 進入具體邏輯實現和處理流程 */
try{
while( (programStatu=getProgramStatu((char *)programName,tmpPath)) != 0 ){
for(k=0;k<1024;k++) memset(pFileList[k].fullPathName,0,sizeof(pFileList[k].fullPathName));
if((k = getFileList(pFileList,inputPath,filePattern)) <= 0 ){
if( k < 0 ){ /* 不能打開輸入文件路徑,程序退出 */
sprintf(errMsg,"Can't open dir %s for read!Msg: %s\n",inputPath,strerror(errno));
throw errMsg;
}
else if( k == 0 ){ /* 如果沒有文件處理,程序進入休眠狀態 */
printf("No file found,sleep %d sec...\n",sleepTime);
sleep(sleepTime);
continue ;
}
}
/* 否則程序依次處理輸入目錄下符合條件的文件 */
while ( memset(fullPathName,0,sizeof(fullPathName)),getFileFromList(fullPathName,pFileList)){
/* 需要在此處添加具體處理邏輯 */
/* 用于實現對fileName文件的處理 */
memset(fileName,0,sizeof(fileName));
memset(orgfileName,0,sizeof(orgfileName));
baseName(fileName,fullPathName);
strcpy(orgfileName,fileName);
fileName[strlen(fileName)-4]='\0';
printf("Process File %s ......\n",fullPathName);
/* 此處調用查重邏輯 */
checkDupFile(fullPathName,tmpPath,indexPath,errorPath,idxNamePrefix);
/* 開始移文件 */
beginTran((char *)programName,fileName);
if( runFlag == 2 || runFlag == 3 ) remove(fullPathName);
else if(mvfile(fullPathName,bakPath)){
throw (char *)"Can't backup file";
}
memset(tmpBuf,0,sizeof(tmpBuf));
sprintf(tmpBuf,"%s.chk",fileName);
if(mvfile(tmpPath,tmpBuf,outputPath,tmpBuf)){
throw (char *)"Can't mv chk file";
}
memset(tmpBuf,0,sizeof(tmpBuf));
sprintf(tmpBuf,"%s.dup",fileName);
if( mvfile(tmpPath,tmpBuf,errorPath,tmpBuf)){
throw (char *)"Can't mv dup file";
}
/* 移動索引文件 */
for(k=0;k<totalIndexFiles;k++){
memset(tmpBuf,0,sizeof(tmpBuf));
if (( strncmp( orgfileName, "p",1) == 0 ) || ( strncmp( orgfileName, "m",1) == 0 ))
sprintf(tmpBuf,"%s/%s%s.idx01",tmpPath,idxNamePrefix,pIndexName[k].callDate);
if (( strncmp( orgfileName, "q",1) == 0 ) || ( strncmp( orgfileName, "w",1) == 0 ))
sprintf(tmpBuf,"%s/%s%s.idx02",tmpPath,idxNamePrefix,pIndexName[k].callDate);
if( mvfile(tmpBuf,indexPath)){
throw (char *)"Can't mv index file";
}
}
commitTran((char *)programName);
/* 其他操作 */
}
}
}
catch (char * errMsg ){
/* 捕獲程序需要退出處理信號,程序退出 */
writeLog(&pLogBuf,"%s\n",errMsg);
closeLogFile(&pLogBuf);
exit(1);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -