/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 【機能概要】 : 共有メモリデータ展開プログラム 2つの定義ファイル(共有メモリ定義ファイル、テーブル定義ファイル) に従って、データファイル(tsv)とアクセスパターンファイル(xml)を 共有メモリ上に展開する。 【作成日】 : 2021.04.23 【呼出形式】 : GG_SHM1000 [ 共有メモリグループ ] # 共有メモリ定義ファイルで定義したグループ名称 [ 展開オプション ] # 共有メモリ展開オプション 【戻り値1】 : int # 0 : 正常終了、-1 : 異常終了 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ #include #include #include #ifndef _NONSTOP #include #endif #include #include #include "GG_SHMCOM.h" static char g_szLogFilePath [ MAX_PATH ] ; // ログファイル名 static char g_szXmlFilePath [ MAX_PATH ] ; // XMLファイルPath static char g_szTsvFilePath [ MAX_PATH ] ; // TSVファイルPath static int MaxRows ; static int MaxColumns ; static char *c_SHMemory = NULL ; static char *c_SHMBase = NULL ; static long l_SHMemory = 0 ; static long MaxColSize = MAX_COLSIZE; static ST_TblDef *t_TblDef ; static ST_ColumnDef *t_ColumnDef ; static iconv_t cd ; char ***pStructData ; char **pStructDataSort ; char ***xmlStruct ; //char pStructData [MAX_ROWS][MAX_COLUMNS][MAX_COLSIZE] ; //char xmlStruct [MAX_ROWS][MAX_COLUMNS][MAX_COLSIZE] ; int compare_str(const void* a, const void* b) ; int compare_int(const void* a, const void* b) ; char*** GG_SHM1000_malloc( int rows , int columns , int colsize ) ; char** GG_SHM1000_malloc_2( int rows , int colsize ) ; void qsort_reset ( char **b , int rows , int colsize ) ; #ifdef _NONSTOP char* GG_SHM1100_NONSTOP ( char *filename ) ; #endif int option_c2_proc(ST_ShmDef *s_ShmDef); void strchg(char *buf, const char *str1, const char *str2); void appendLog (int *logLen , char **logBuff , const char *append) ; CLSSharedMemory shmAcPtMng; CLSSharedMemory shmAcPtPtr_A[ GG_SHM1001_SHMIDNUM ]; CLSSharedMemory shmAcPtPtr_B[ GG_SHM1001_SHMIDNUM ]; int main( int argc, char *argv[] ) { char szLogFileTmpPath [ MAX_PATH ] ; // ログファイル一時名称 char szAccessDate [ 30 ] ; // YYYY/MM/DD HH:MM:SS.mmmmmm char c_GG_SHM_TBLDEF [ MAX_PATH ] ; // テーブル管理ファイル FILE *TblDeffp ; char *TblDefChar ; struct stat stat_buf ; char XmlInFile [ MAX_PATH ] ; char *TblDefLine ; char *TblDefLineWk ; char *TblDefPrm ; ST_ShmDef *s_ShmDef ; //使用面管理領域 ST_ShmDef *s_ShmDefBase ; //使用面管理先頭領域 char szCmEnvName [ MAX_PATH ] ; // 環境名 char tmpStr [ 2048 ] ; long usedMemSize = 0; // ログ出力場所の決定 getEnvString ( szLogFileTmpPath,"GG_LogFileName",GG_SHM1000_LOGPATH,sizeof(szLogFileTmpPath) ) ; getLocalTimeString ( g_szLogFilePath,sizeof(g_szLogFilePath),szLogFileTmpPath ) ; // データおよび環境ファイル格納場所の取得 getEnvString ( g_szXmlFilePath,"GG_XmlFilePath","",sizeof(g_szXmlFilePath) ) ; getEnvString ( g_szTsvFilePath,"GG_TsvFilePath","",sizeof(g_szTsvFilePath) ) ; // 環境名の決定 getEnvString ( szCmEnvName,"CM_ENV_NAME","galaxygoby",sizeof(szCmEnvName) ) ; // 開始メッセージ出力 getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 テーブルデータ展開 **** START ****" , szAccessDate ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 環境名=[%s]" , szAccessDate , szCmEnvName ) ; // データ作業領域確保 MaxRows = (int)getEnvLong("GG_SHM1000_MAX_ROWS",MAX_ROWS) + 1 ; MaxColumns = (int)getEnvLong("GG_SHM1000_MAX_COLUMNS",MAX_COLUMNS) + 1 ; MaxColSize = (int)getEnvLong("GG_SHM1000_MAX_COLSIZE",MAX_COLSIZE) + 1 ; if ( MaxColSize < strlen(PARM_FULLSCAN) + 1 ) { MaxColSize = strlen(PARM_FULLSCAN) + 1 ; } pStructData = GG_SHM1000_malloc( MaxRows , MaxColumns , MaxColSize ) ; if (pStructData == NULL) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 データ作業領域確保エラー ****" , szAccessDate ) ; exit (-1); } // XML作業領域確保 // 領域長(MAX_ROWS等)を変更する場合、GG_SHM1100のGG_SHM1100_MaxRow等を合わせて修正要 xmlStruct = GG_SHM1000_malloc ( MAX_ROWS + 1 , MAX_COLUMNS + 1 , MAX_COLSIZE + 1 ) ; if (xmlStruct == NULL) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 XML作業領域確保エラー ****" , szAccessDate ) ; exit (-1); } // 共有メモリ取得 /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 共有メモリポインタ取得 ( 管理部 ) _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ key_t keyShmMainMem = getEnvLong("GG_SHM1001_MEMORYID",GG_SHM1001_MEMORYID); char *c_ShmMngTmp = (char *)shmAcPtMng.OpenSheredMemory( keyShmMainMem ); if (c_ShmMngTmp == NULL) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 共有メモリ取得エラー ****" , szAccessDate ) ; exit (-1); } // ログレベルの設定 long LogLevel ; memcpy ( (void *)&LogLevel , (void *)c_ShmMngTmp , sizeof(LogLevel) ) ; // 先頭は、ログレベル(long型)の設定に使用 s_ShmDef = (ShmDefType *)( c_ShmMngTmp + sizeof(LogLevel) ) ; s_ShmDefBase = s_ShmDef ; // 起動パラメータは、メモリグループ名と展開オプション if ( argc < 3 ) { printf("Usage : GG_SHM1000 [メモリグループ] [オプション]\n") ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** Usage : GG_SHM1000 [メモリグループ] [オプション]****" , szAccessDate ) ; exit (-1); } // 共有メモリの使用面でない方に情報(データ、定義)を展開 for ( int i = 0 ; s_ShmDef->ShmName[0] != '\0' ; i++ , s_ShmDef ++ ) { if ( strcmp ( s_ShmDef->ShmName , argv[1] ) == 0 ) { if ( s_ShmDef->ShmFlg == 0 || s_ShmDef->ShmFlg == 2 ) { c_SHMemory = (char *)shmAcPtPtr_A[i].OpenSheredMemory( s_ShmDef->ShmID_A ); } else if ( s_ShmDef->ShmFlg == 1 ) { c_SHMemory = (char *)shmAcPtPtr_B[i].OpenSheredMemory( s_ShmDef->ShmID_B ); } else { c_SHMemory = NULL ; } if ( c_SHMemory == NULL ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 ,"**** ( %s ) **** GG_SHM1000 共有メモリ取得エラー [%s]****" , szAccessDate , argv[1] ) ; exit (-1); } break ; } } // 共有メモリ定義情報にないメモリグループ名が指定された場合エラー処理 if ( s_ShmDef->ShmName[0] == '\0' ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 パラメータエラー [%s] ****" , szAccessDate , argv[1] ) ; exit (-1); } // -c2オプション(面切替のみ)の場合、面を切替終了 if ( strcmp ( "-c2" , argv[2] ) == 0 ) { option_c2_proc( s_ShmDef ); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 面切替 メモリグループ:[%s] 面:[%d] ****" , szAccessDate , s_ShmDef->ShmName , s_ShmDef->ShmFlg ) ; // 終了メッセージ出力 getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 テーブルデータ展開 **** END ****" , szAccessDate ) ; exit (0); } // c_SHMBase に共有メモリポインタ格納 c_SHMBase = c_SHMemory ; // TableDefのopen getEnvString ( c_GG_SHM_TBLDEF , "GG_SHM_TBLDEF" , GG_SHM1000_TBLDEF , sizeof(c_GG_SHM_TBLDEF) ) ; if ( ( TblDeffp = fopen ( c_GG_SHM_TBLDEF , "r" ) ) == NULL) { // printf("file open error!! TblDefFile = [ %s ]\n" , GG_SHM1000_TBLDEF ); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 TBLDEFファイルの取得失敗 [ %s ]" , szAccessDate , GG_SHM1000_TBLDEF ) ; exit (-1); } // TableDefのサイズ取得 if ( stat ( c_GG_SHM_TBLDEF, &stat_buf ) != 0 ) { // printf("file stat error!! TblDefFile = [ %s ]\n" , c_GG_SHM_TBLDEF ); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 TBLDEFファイルのstat失敗 [ %s ]" , szAccessDate , c_GG_SHM_TBLDEF ) ; exit (-1); } // TableDefの読込 TblDefChar = (char *)malloc ( stat_buf.st_size + 1 ) ; fread ( TblDefChar , 1 , stat_buf.st_size , TblDeffp ) ; fclose ( TblDeffp ) ; TblDefChar [ stat_buf.st_size ] = '\0' ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 TableDef読込完了" , szAccessDate ) ; // TableDefのレコード件数取得 long TblDefNum , TblDefNum2 = 0 ; TblDefLineWk = strtok( TblDefChar , "\n" ); for ( TblDefNum = 0 ; TblDefLineWk != NULL ; TblDefNum ++ ) TblDefLineWk = strtok( NULL , "\n" ) ; // TableDefの構造体設定 TblDefLine = (char *) malloc ( TblDefNum * 1024 ) ; TblDefLineWk = TblDefChar ; char *TblDefLinePos = TblDefLine ; for ( int i = 0 ; i < TblDefNum ; i++ ) { if ( TblDefLineWk[0] != ';' ) { strcpy ( TblDefLinePos , TblDefLineWk ) ; if ( TblDefLinePos[strlen(TblDefLinePos)-1] == '\r' ) TblDefLinePos[strlen(TblDefLinePos)-1] = '\0' ; TblDefLinePos = TblDefLinePos + 1024 ; TblDefNum2 ++ ; } TblDefLineWk = TblDefLineWk + strlen(TblDefLineWk) + 1 ; } TblDefNum = TblDefNum2 ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 TableDef件数=[%d]" , szAccessDate , TblDefNum ) ; // TableDefの昇順並べ替え qsort( TblDefLine, TblDefNum, 1024 , compare_str ); // TableDefのデータ整備および初期値設定 t_TblDef = (struct TblDefType *) malloc ( TblDefNum * sizeof(*t_TblDef) ) ; ST_TblShmDef *t_TblShmDef = (struct TblShmDefType *) malloc ( TblDefNum * sizeof(ST_TblShmDef) ) ; TblDefLinePos = TblDefLine ; TblDefNum2 = 0 ; for ( int i = 0 ; i < TblDefNum ; i++ ) { TblDefPrm = strtok( TblDefLinePos , "," ) ; // テーブルID設定 strcpy ( t_TblDef[TblDefNum2].TblNo , TblDefPrm ) ; TblDefPrm = strtok( NULL , "," ) ; // テーブル識別子設定 strcpy ( t_TblDef[TblDefNum2].TblId , TblDefPrm ) ; strcpy ( t_TblShmDef[TblDefNum2].TblId , TblDefPrm ) ; TblDefPrm = strtok( NULL , "," ) ; if ( strcmp ( TblDefPrm , argv[1] ) != 0 ) { TblDefLinePos = TblDefLinePos + 1024 ; continue ; } // グループ識別子設定 strcpy ( t_TblShmDef[TblDefNum2].ShmName , TblDefPrm ) ; TblDefPrm = strtok( NULL , "," ) ; // strcpy ( t_TblDef[TblDefNum2].AcType , TblDefPrm ) ; TblDefPrm = strtok( NULL , "," ) ; // 共有情報ファイル名設定 strcpy ( tmpStr , TblDefPrm ) ; // 環境変数部分を置換 strchg ( tmpStr , "${CM_ENV_NAME}" , szCmEnvName ); strcpy ( t_TblDef[TblDefNum2].TextName , tmpStr ); TblDefPrm = strtok( NULL , "," ) ; // 共有メモリアクセスパターンファイル名設定 strcpy ( tmpStr , TblDefPrm ) ; // 環境変数部分を置換 strchg ( tmpStr , "${CM_ENV_NAME}" , szCmEnvName ); strcpy ( t_TblDef[TblDefNum2].XmlFileName , tmpStr ) ; TblDefPrm = strtok( NULL , "," ) ; strcpy ( t_TblDef[TblDefNum2].TblName , TblDefPrm ) ; t_TblDef[TblDefNum2].TblDataPos = 0 ; // テーブルデータ相対開始位置 t_TblDef[TblDefNum2].TblDataLen = 0 ; // テーブルデータ全体長 t_TblDef[TblDefNum2].TblColPos = 0 ; // 項目情報相対開始位置 t_TblDef[TblDefNum2].TblColNum = 0 ; // 項目情報件数 t_TblDef[TblDefNum2].TblPtnPos = 0 ; // アクセスパターン相対開始位置 t_TblDef[TblDefNum2].TblPtnNum = 0 ; // アクセスパターン件数 getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 4 , "**** ( %s ) **** TblNo=%s TblId=%s AcType=%s TextName=%s XmlFileName=%s TblName=%s" , szAccessDate , t_TblDef[i].TblNo , t_TblDef[i].TblId , t_TblDef[TblDefNum2].AcType , t_TblDef[TblDefNum2].TextName , t_TblDef[TblDefNum2].XmlFileName , t_TblDef[TblDefNum2].TblName ) ; TblDefLinePos = TblDefLinePos + 1024 ; TblDefNum2 ++ ; } TblDefNum = TblDefNum2 ; // printf("c_SHMemory=[%d] l_SHMemory=[%d]\n",(long)c_SHMemory,l_SHMemory) ; memcpy ( c_SHMemory , (char *)&TblDefNum , sizeof(TblDefNum) ) ; c_SHMemory = c_SHMemory + sizeof(TblDefNum); l_SHMemory = l_SHMemory + sizeof(TblDefNum) ; // printf("c_SHMemory=[%d] l_SHMemory=[%d]\n",(long)c_SHMemory,l_SHMemory) ; memcpy ( c_SHMemory , t_TblDef , TblDefNum * sizeof(*t_TblDef) ) ; c_SHMemory = c_SHMemory + ( TblDefNum * sizeof(*t_TblDef) ) ; l_SHMemory = l_SHMemory + ( TblDefNum * sizeof(*t_TblDef) ) ; // printf("c_SHMemory=[%d] l_SHMemory=[%d]\n",(long)c_SHMemory,l_SHMemory) ; // iconvのオープンおよび初期化 #ifndef _NONSTOP cd = iconv_open("Shift_JIS" , "UTF-8") ; if (cd == (iconv_t)-1) { // printf( "iconv_open(%s, %s) エラー\n", "Shift_JIS", "UTF-8"); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 iconv エラー [ %s ] to [ %s ]" , szAccessDate , "UTF-8" , "Shift_JIS" ) ; exit (-1); } #else cd = iconv_open("SJIS" , "FSS-UTF") ; if (cd == (iconv_t)-1) { // printf( "iconv_open(%s, %s) エラー\n", "SJIS" , "FSS-UTF"); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 iconv エラー [ %s ] to [ %s ]" , szAccessDate , "SJIS" , "FSS-UTF" ) ; exit (-1); } #endif // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // Tableデータの読込(1行目・データ項目) // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ // t_ColumnDef = (struct ST_ColumnDef **) malloc ( TblDefNum * sizeof(*t_ColumnDef) ) ; for ( int i = 0 ; i < TblDefNum ; i++ ) { FILE *TblDatafp ; char TextName [ MAX_PATH ] ; // TableDefのテキストファイル名に従い、テキストデータオープン if(strlen(g_szTsvFilePath) == 0){ sprintf ( TextName , "%s" , t_TblDef[i].TextName ) ; }else{ sprintf ( TextName , "%s/%s" , g_szTsvFilePath , t_TblDef[i].TextName ) ; } if ( ( TblDatafp = fopen( TextName , "r" ) ) == NULL) { // printf("file open error!! TblDefFile = [ %s ]\n" , TextName ); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 テキストデータの取得失敗 [ %s ]" , szAccessDate , TextName ) ; exit (-1); } // テキストデータのサイズ取得 if ( stat ( TextName, &stat_buf ) != 0 ) { // printf("file stat error!! TblDefFile = [ %s ]\n" , TextName ); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 テキストデータのstat失敗 [ %s ]" , szAccessDate , TextName ) ; exit (-1); } // テキストデータの読込 int BufSize = ( stat_buf.st_size + 1 ) * 2 ; char *TblDataChar = (char *)malloc ( BufSize ) ; char *ReadDataBuf = (char *)malloc ( BufSize ) ; char *TblDataCharBase = TblDataChar ; // 全件読み込み fread ( TblDataChar , 1 , stat_buf.st_size , TblDatafp ) ; fclose ( TblDatafp ) ; TblDataChar [ stat_buf.st_size - 1 ] = '\0' ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 [%s] ファイルサイズ=[%d]" , szAccessDate , TextName , stat_buf.st_size ) ; // テキストデータのレコード件数取得 int TblDataNum ; TblDefLineWk = strtok( TblDataChar , "\n" ); for ( TblDataNum = 0 ; TblDefLineWk != NULL ; TblDataNum ++ ) { TblDefLineWk = strtok( NULL , "\n" ) ; // if ( TblDefLineWk != NULL ) { // getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; // GG_MsgOut ( g_szLogFilePath , 1 // , "**** ( %s ) **** GG_SHM1000 TblDefLineWk=[%s]" // , szAccessDate , TblDefLineWk ) ; // } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 TblDataNum:(%d) TblDefLineWk:(%s)" , szAccessDate , TblDataNum, TblDefLineWk) ; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 [%s] 件数=[%d]" , szAccessDate , TextName , TblDataNum - 1 ) ; strcpy ( ReadDataBuf , TblDataChar ) ; TblDataChar = TblDataChar + strlen(TblDataChar) + 1 ; // テキストデータの項目数取得 int ColumnNum ; char* Column = strtok ( ReadDataBuf , "\t" ) ; for ( ColumnNum = 0 ; Column != NULL ; ColumnNum ++ ) { Column = strtok ( NULL , "\t" ) ; if ( Column != NULL && Column[0] != '\0' ) { if ( Column[strlen(Column)-1] == '\r' ) Column[strlen(Column)-1] = '\0' ; } } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 [%s] 項目数=[%d]" , szAccessDate , TextName , ColumnNum ) ; // テキストデータヘッダの項目情報設定および初期化 t_ColumnDef = (struct ColumnDefType *) malloc ( ColumnNum * sizeof(*t_ColumnDef) ) ; Column = ReadDataBuf ; for ( int j = 0 ; j < ColumnNum ; j++ ) { memset ( t_ColumnDef[j].ColumnName , 0x00 , sizeof(t_ColumnDef[j].ColumnName) ) ; if ( strlen(Column) >= (int)sizeof(t_ColumnDef[j].ColumnName) ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 ヘッダデータ項目長エラー [ %d < %s の長さ ]" , szAccessDate , sizeof(t_ColumnDef[j].ColumnName), Column) ; exit (-1); } strcpy ( t_ColumnDef[j].ColumnName , Column ) ; t_ColumnDef[j].ColumnSize = 0 ; Column = Column + strlen(Column) + 1 ; if ( Column[0] == '\0' ) Column++ ; } // ヘッダの項目情報設定の共有メモリ設定 char *cSHMColHeader = c_SHMemory ; memcpy ( c_SHMemory , t_ColumnDef , ColumnNum * sizeof(*t_ColumnDef) ) ; c_SHMemory = c_SHMemory + ( ColumnNum * sizeof(*t_ColumnDef) ) ; t_TblDef[i].TblColPos = l_SHMemory ; t_TblDef[i].TblColNum = ColumnNum ; // テキストデータ本文および項目長の設定 for ( int row = 0 ; row < TblDataNum-1 ; row ++ ) { strcpy ( ReadDataBuf , TblDataChar ) ; TblDataChar = TblDataChar + strlen(TblDataChar) + 1 ; int ReadDataPos = 0 ; int logBuffLen = LOG_LEN ; char *logBuff = (char *) malloc ( logBuffLen ) ; logBuff[0] = '\0' ; // ファイルから読込んだデータ項目をpStructData(一時領域)に格納 // データは\tで区切られているので、項目に区切って格納 for ( int col = 0 ; col < ColumnNum && Column != NULL ; col ++ ) { char *pos = strchr ( ReadDataBuf + ReadDataPos , '\t' ) ; if ( pos == NULL ) { pos = ReadDataBuf + strlen(ReadDataBuf) ; } int Collen = pos - ReadDataBuf - ReadDataPos ; // 環境変数で定義したMaxColSizeを超える項目があったときはエラー if ( Collen >= (int)MaxColSize ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 データ項目長エラー [ %d < %s の長さ(%d) ]" , szAccessDate , MaxColSize, ReadDataBuf + ReadDataPos , Collen ) ; exit (-1); } // データ格納、データがない場合は0x1f(文字長調整)を埋める if ( Collen > 0 ) { strncpy ( pStructData[row][col] , ReadDataBuf+ReadDataPos , Collen ) ; pStructData[row][col][Collen] ='\0' ; } else { pStructData[row][col][0] = SP_REP ; pStructData[row][col][1] = 0x00 ; } ReadDataPos += Collen + 1 ; // ログ領域に格納情報を設定(logBuff自動拡張有り) appendLog ( &logBuffLen , &logBuff , pStructData[row][col] ) ; appendLog ( &logBuffLen , &logBuff , "\t" ) ; // カラム長に同一列データの最大長を設定 if ( row == 0 ) { t_ColumnDef[col].ColumnSize = Collen ; } else { if ( t_ColumnDef[col].ColumnSize < Collen ) t_ColumnDef[col].ColumnSize = Collen ; } } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 10 , "**** ( %s ) **** GG_SHM1000 [%s] [%d]\t%s" , szAccessDate , TextName , row , logBuff ) ; free ( (char *) logBuff ) ; } free ( TblDataCharBase ) ; free ( ReadDataBuf ) ; // 項目名と最大項目長をログ出力 for ( int j = 0 ; j < ColumnNum ; j++ ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 4 , "**** ( %s ) **** GG_SHM1000 [%s] 項目名=%s 項目長=%d" , szAccessDate , TextName , t_ColumnDef[j].ColumnName , t_ColumnDef[j].ColumnSize ) ; } memcpy ( cSHMColHeader , t_ColumnDef , ColumnNum * sizeof(*t_ColumnDef) ) ; // テキストデータの共有メモリ設定 t_TblDef[i].TblDataPos = (long)c_SHMemory - (long)c_SHMBase ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 [%s] テーブルデータ開始位置=[%d]" , szAccessDate , TextName , t_TblDef[i].TblDataPos ) ; l_SHMemory = 0 ; // pStructData(一時領域)に格納したデータを共有メモリに展開 for ( int row = 0 ; row < TblDataNum-1 ; row ++ ) { int logBuffLen = LOG_LEN ; char *logBuff = (char *) malloc ( logBuffLen ) ; logBuff[0] = '\0' ; // 項目毎に最大長に合わせて、0x1fデータを埋めて同一項目長になるようにして設定 for ( int col = 0 ; col < ColumnNum ; col ++ ) { strcpy ( c_SHMemory , pStructData[row][col] ) ; if ( strlen ( pStructData[row][col] ) < (int)t_ColumnDef[col].ColumnSize ) { memset ( c_SHMemory + strlen ( pStructData[row][col] ) , SP_REP , (int)t_ColumnDef[col].ColumnSize - strlen ( pStructData[row][col] ) ) ; } c_SHMemory = c_SHMemory + t_ColumnDef[col].ColumnSize ; l_SHMemory = l_SHMemory + t_ColumnDef[col].ColumnSize ; // ログ領域に格納情報を設定(logBuff自動拡張有り) char cColSize [30] ; sprintf ( cColSize , "\t(%d)\t" , (int)t_ColumnDef[col].ColumnSize ) ; appendLog ( &logBuffLen , &logBuff , cColSize ) ; appendLog ( &logBuffLen , &logBuff , pStructData[row][col] ) ; } // ログ出力 getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 row[%d]:%s" , szAccessDate , row, logBuff ) ; free ( (char *) logBuff ) ; } free ( (char *)t_ColumnDef ) ; t_TblDef[i].TblDataLen = l_SHMemory ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 [%s] テーブルデータ長=[%d]" , szAccessDate , TextName , t_TblDef[i].TblDataLen ) ; // XMLデータの設定 if (strlen(g_szXmlFilePath) == 0) { sprintf ( XmlInFile , "%s" , t_TblDef[i].XmlFileName ) ; } else { sprintf ( XmlInFile , "%s/%s" , g_szXmlFilePath , t_TblDef[i].XmlFileName ) ; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 パターンファイル名称=[%s]" , szAccessDate , XmlInFile ) ; char *c_data ; #ifndef _NONSTOP c_data = GG_SHM1100 ( XmlInFile ) ; #else c_data = GG_SHM1100_NONSTOP ( XmlInFile ) ; #endif if ( c_data == (char *)NULL ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 xmlファイル解析エラー [ %s ]" , szAccessDate ,XmlInFile ) ; exit (-1); } // アクセスパターン一時格納領域(xmlStruct)に設定 int row = 0 ; int col = 0 ; for ( int j = 0 , k = 0 ; c_data[j] != '\0' ; j++ ) { if ( c_data[j] == '\t' ) { memcpy ( xmlStruct[row][col] , c_data + k , j - k ) ; xmlStruct[row][col][j-k] = '\0' ; col++ ; k = j + 1 ; strcpy ( xmlStruct[row][col] , STR_NULL ) ; } else if ( c_data[j] == '\n' ) { row++ ; k = j + 1 ; col = 0 ; strcpy ( xmlStruct[row][col] , STR_NULL ) ; } } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 4 , "**** ( %s ) **** GG_SHM1000 c_data = [\n%s]" , szAccessDate , c_data ) ; free ( (void *)c_data ) ; // XMLデータの共有メモリ設定 getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 4 , "**** ( %s ) **** GG_SHM1000 共有メモリ設定" , szAccessDate ) ; t_TblDef[i].TblPtnPos = (long)c_SHMemory - (long)c_SHMBase ; for ( row = 0 ; strcmp( xmlStruct[row][0], STR_NULL ) != 0 ; row ++ ) { char *wSHMemory = c_SHMemory + sizeof(row) ; int col = 0 ; for ( ; strcmp( xmlStruct[row][col], STR_NULL ) != 0 ; col ++ ) { if ( col == 2 ) { // col == 2 は、「検索条件格納領域」で、編集が必要 char whereWork [ MAX_PATTERNSZ ] ; int whereRet = GG_SHM1003 ( xmlStruct[row][col] , whereWork ) ; if ( whereRet != 0 ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 検索条件構文解析エラー Status=%d\n[ %s ] [ %s ] [ %s ]" , szAccessDate ,whereRet ,xmlStruct[row][0] ,xmlStruct[row][1] ,xmlStruct[row][2] ) ; exit (-1); } strcpy ( wSHMemory , whereWork ) ; wSHMemory = wSHMemory + strlen ( whereWork ) + 1 ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 4 , "**** ( %s ) **** GG_SHM1000 xmlStruct[%d][%d] = [%s]" , szAccessDate , row , col , whereWork ) ; // col=3,4,5の箇所に、インデックス開始位置 / レコード長 / レコード件数 // の初期値(0:12桁)を格納。インデックス検索の場合は、次ロジックで // それぞれの値が設定される。 strcpy ( wSHMemory , PARM_FULLSCAN ) ; wSHMemory += strlen(wSHMemory) + 1 ; strcpy ( wSHMemory , PARM_FULLSCAN ) ; wSHMemory += strlen(wSHMemory) + 1 ; strcpy ( wSHMemory , PARM_FULLSCAN ) ; wSHMemory += strlen(wSHMemory) + 1 ; } else { strcpy ( wSHMemory , xmlStruct[row][col] ) ; wSHMemory = wSHMemory + strlen ( xmlStruct[row][col] ) + 1 ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 4 , "**** ( %s ) **** GG_SHM1000 xmlStruct[%d][%d] = [%s]" , szAccessDate , row , col , xmlStruct[row][col] ) ; } } col += 3 ; // col=3,4,5の分を追加 memcpy ( c_SHMemory , (char *)&(col) , sizeof(col) ) ; c_SHMemory = wSHMemory ; } l_SHMemory = (long)c_SHMemory - (long)c_SHMBase ; t_TblDef[i].TblPtnNum = row ; usedMemSize = l_SHMemory; } // 共有メモリデータ・アクセス管理部の共有メモリ設定 memcpy ( c_SHMBase + sizeof(TblDefNum) , (char *)t_TblDef , TblDefNum * sizeof(*t_TblDef) ) ; /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ インデックス作成処理 アクセスパターン名称が「Index_」で始まり、検索条件接続詞が「or」でないものが対象 インデックス項目は、検索条件が「=」であり、文字列比較であるものが対象となる _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ char AcPt [GG_SHM0001_MaxPrmNum][GG_SHM0001_MaxCondLen] ; // アクセスパターン一時領域 char Left [GG_SHM0001_MaxCond][GG_SHM0001_MaxLeftLen] ; // インデックス項目格納 // テーブル情報毎にループ for ( int i = 0 ; i < TblDefNum ; i++ ) { char *wSHMemory = c_SHMBase + t_TblDef[i].TblPtnPos ; char *wIndexPos , *wIndexRec , *wIndexRow ; // アクセスパターン毎にループ for ( int j = 0 ; j < t_TblDef[i].TblPtnNum ; j++ ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 テーブルNo=[%d/%d] アクセスPtnNo=[%d/%d]" , szAccessDate , i , TblDefNum , j , t_TblDef[i].TblPtnNum ) ; int colnum ; memcpy ( (char *)&colnum , wSHMemory , sizeof(colnum) ) ; wSHMemory = wSHMemory + sizeof(colnum) ; // アクセスパターンを共有メモリ情報から一時領域(AcPt)に展開 // また、インデックス情報格納ポインタ(col=3,4,5)を一時領域に格納 for ( int col = 0 ; col < colnum ; col++ ) { strcpy ( AcPt[col] , wSHMemory ) ; AcPt[col+1][0] = '\0' ; if ( col == 3 ) wIndexPos = wSHMemory ; if ( col == 4 ) wIndexRec = wSHMemory ; if ( col == 5 ) wIndexRow = wSHMemory ; wSHMemory = wSHMemory + strlen(AcPt[col]) + 1 ; } if ( memcmp ( AcPt [1] , "Index_" , 6 ) != 0 ) continue ; // アクセスパターン名称が「Index_」から始まる場合、インデックス検索対象 long m = 0; int p = 0; Left[0][0] = '\0' ; for ( int n=0 ,k=0; m <= strlen(AcPt[2]) ; m++ ) { int q = k % 4 ; if ( AcPt[2][m] == ' ' || m == strlen(AcPt[2]) ) { if ( q==0 ) { memcpy ( Left[p] , AcPt[2]+n , m-n ) ; Left[p][m-n] = '\0' ; Left[p+1][0] = '\0' ; // @NUM対応 数字比較を行う場合は、インデックス項目対象外 char *Left_Num_Pos = strchr ( Left[p] , '@' ) ; if ( Left_Num_Pos == NULL ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 インデックス項目 [%s] : %s / %s" , szAccessDate , Left[p] , AcPt[0] , AcPt[1] ) ; } else { Left[p][0] = '\0' ; } } else if ( q==1 ) { if ( Left[p][0] != '\0' ) { if ( memcmp ( AcPt[2]+n , "=" , m-n ) == 0 ) { // インデックス項目確定 p++ ; } else { // インデックス項目から除外 getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 インデックス除外 [%s] : %s / %s (=比較でない)" , szAccessDate , Left[p] , AcPt[0] , AcPt[1] ) ; Left[p][0] = '\0' ; } } } else if ( q == 3 ) { // インデックスは作成しない if ( memcmp ( AcPt[2]+n , "or" , m-n ) == 0 ) break ; } n = m + 1 ; k++ ; } } if ( Left[0][0] == '\0' ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 4 , "**** ( %s ) **** GG_SHM1000 検索名[%s]は、Where句に文字列+「=」検索がないため、通常検索[%s]" , szAccessDate , AcPt[1] , AcPt[2] ) ; continue ; } if ( m <= strlen(AcPt[2]) ) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 4 , "**** ( %s ) **** GG_SHM1000 検索名[%s]は、「or」検索のため通常検索を行います[%s]" , szAccessDate , AcPt[1] , AcPt[2] ) ; continue ; } // 各検索項目(Left[n])の相対位置と長さをテーブルヘッダ情報から算出 // して、Leftpos[n],Leftlen[n]に格納 int Leftpos [GG_SHM0001_MaxCond] ; // インデックス項目のデータ格納相対位置 int Leftlen [GG_SHM0001_MaxCond] ; // インデックス項目のデータ長 long TblDataLen = 0 ; t_ColumnDef = (struct ColumnDefType *)(c_SHMBase + t_TblDef[i].TblColPos ) ; for ( int n = 0 ; Left[n][0] != '\0' ; n ++ ) { TblDataLen = 0 ; for ( int k = 0 ; k < t_TblDef[i].TblColNum ; k ++ ) { if ( strcmp ( Left[n] , t_ColumnDef[k].ColumnName ) == 0 ) { Leftpos[n] = TblDataLen ; Leftlen[n] = t_ColumnDef[k].ColumnSize ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 4 , "**** ( %s ) **** GG_SHM1000 %s:%s pos:len=%d:%d" , szAccessDate , AcPt[1] , Left[n] , Leftpos[n] , Leftlen[n] ) ; break ; } TblDataLen = TblDataLen + t_ColumnDef[k].ColumnSize ; } } // データ格納相対位置の大きさ(12バイト)をLeftlen[n]に格納 for ( int n = 0 ; ; n ++ ) { if ( Left[n][0] == '\0' ) { Leftlen[n] = strlen ( PARM_FULLSCAN ) ; break ; } } // データレコード長を TbleDataLen に算出・格納 TblDataLen = 0 ; for ( int n = 0 ; n < t_TblDef[i].TblColNum ; n ++ ) { TblDataLen = TblDataLen + t_ColumnDef[n].ColumnSize ; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 %s テーブルレコード長 = [%d]" , szAccessDate , AcPt[0] , TblDataLen ) ; // pStructData(テーブルデータ一時格納領域)に共有メモリデータを格納 long row = 0 , col = 0 , recLen = 0 ; char *wSHMemory2 = c_SHMBase + t_TblDef[i].TblDataPos ; for ( int n = 0 ; n < t_TblDef[i].TblDataLen ; ) { col = 0 ; int logBuffLen = LOG_LEN ; char *logBuff = (char *) malloc ( logBuffLen ) ; logBuff[0] = '\0' ; for ( int k = 0 ; Left[k][0] != '\0' ; k ++ ) { // pStructData(テーブルデータ一時格納領域)に格納 strncpy ( pStructData[row][col] , wSHMemory2 + n + Leftpos[k] , Leftlen[k] ) ; pStructData[row][col][Leftlen[k]] ='\0' ; // インデックスのレコード長算出 if ( row == 0 ) recLen += Leftlen[k] ; // ログ領域に格納情報を設定(logBuff自動拡張有り) appendLog ( &logBuffLen , &logBuff , pStructData[row][col] ) ; char *x1f = strchr ( logBuff , SP_REP ) ; if ( x1f != NULL ) *x1f = '\0' ; strcat ( logBuff , "\t" ) ; col ++ ; } // レコード相対位置の格納 sprintf ( pStructData[row][col] ,"%012d" , n ) ; pStructData[row][col+1][0] ='\0' ; // ログ出力 appendLog ( &logBuffLen , &logBuff , pStructData[row][col] ) ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 10 , "**** ( %s ) **** GG_SHM1000 SORT前 row[%d]:%s" , szAccessDate , row , logBuff ) ; // インデックスのレコード長にレコード相対位置の長さを追加 if ( row == 0 ) recLen += strlen(PARM_FULLSCAN) ; row ++ ; pStructData[row][0][0] ='\0' ; n = n + TblDataLen ; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 インデックスソート準備 %s : %s row:col:recLen=%d:%d:%d" , szAccessDate , AcPt[0] , AcPt[1] , row , col , recLen ) ; // ソート用メモリ領域確保 pStructDataSort = GG_SHM1000_malloc_2 ( row + 1 , recLen + 1 ) ; if (pStructDataSort == NULL) { getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000_malloc_2 作業領域確保エラー ****" , szAccessDate ) ; exit (-1); } // テーブルデータをpStructData(テーブルデータ一時格納領域)から // pStructDataSort(ソート用メモリ領域)に格納 for ( int n = 0 ; n < row ; n ++ ) { pStructDataSort[n][0] = '\0' ; int logBuffLen = LOG_LEN ; char *logBuff = (char *) malloc ( logBuffLen ) ; logBuff[0] = '\0' ; for ( int k = 0 ; k <= col ; k ++ ) { // テーブルデータをソート用メモリ領域に格納 strcat ( pStructDataSort[n] , pStructData[n][k] ) ; // ログ領域に格納情報を設定(logBuff自動拡張有り) appendLog ( &logBuffLen , &logBuff , pStructData[n][k] ) ; appendLog ( &logBuffLen , &logBuff , "\t" ) ; } // ログ領域の0x1fコード一括置換 char *p ; while ( ( p = strchr (logBuff , SP_REP) ) != NULL ) { *p = ' ' ; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 10 , "**** ( %s ) **** GG_SHM1000 WORK展開 row[%d]:%s" , szAccessDate , n, logBuff ) ; free ( (char *) logBuff ) ; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 インデックスSORT処理 %s : %s row:col:recLen=%d:%d:%d" , szAccessDate , AcPt[0] , AcPt[1] , row , col , recLen ) ; // インデックス領域をソート qsort ( (char *)(pStructDataSort+row+1) , row , recLen + 1 , compare_str ) ; // インデックス相対開始位置を共有メモリ上に設定 sprintf ( wIndexPos , "%012d" , l_SHMemory ) ; m = l_SHMemory ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 インデックスメモリ展開" , szAccessDate ) ; // インデックス情報を共有メモリに設定 for ( int n = 0 ; n < row ; n ++ ) { // インデックス情報を共有メモリに設定 strcpy ( c_SHMemory , pStructDataSort[n] ) ; c_SHMemory = c_SHMemory + strlen ( pStructDataSort[n] ) ; l_SHMemory = l_SHMemory + strlen ( pStructDataSort[n] ) ; // ログ出力処理 if ( LogLevel >= 9 ) { char *logBuff = (char *)malloc(recLen + 2) ; strcpy ( logBuff , pStructDataSort[n] ) ; // ログ領域の0x1fコード一括置換 char *p ; while ( ( p = strchr (logBuff , SP_REP) ) != NULL ) { *p = ' ' ; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 SORT後 row[%d]:%s" , szAccessDate , n, logBuff ) ; free ( logBuff ) ; } } sprintf ( wIndexRec , "%012d" , recLen ) ; // インデックスレコード長を共有メモリに設定 sprintf ( wIndexRow , "%012d" , row ) ; // インデックスレコード件数を共有メモリに設定 getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 9 , "**** ( %s ) **** GG_SHM1000 インデックス作成完了 %s : %s 位置:長さ;件数=%s:%s:%s" , szAccessDate , AcPt[0] , AcPt[1] , wIndexPos , wIndexRec , wIndexRow ) ; free ( (char **)pStructDataSort ) ; } } usedMemSize = l_SHMemory; // 共有メモリ使用率のログ出力 if ( usedMemSize != 0 ) { long dataSize = getEnvLong("GG_SHM1000_SHMID_ALLOCSIZE",-1); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; long useRate = -1; long threshold = getEnvLong("GG_SHM1000_SHMID_ALLOCSIZE_THRESHOLD",70); if ( dataSize != -1 ) { useRate = usedMemSize * 100 / dataSize; } if ( useRate > threshold ) { GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 メモリグループ=[%s] データサイズ=[%d] 共有メモリサイズ=[%d] 使用率=[%d%%] ※使用率が %d%%を超えています。ShmMng.defに定義している共有メモリサイズの変更をご検討ください。" , szAccessDate , s_ShmDef->ShmName , usedMemSize , dataSize , useRate , threshold ) ; } else { GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 メモリグループ=[%s] データサイズ=[%d] 共有メモリサイズ=[%d] 使用率=[%d%%]" , szAccessDate , s_ShmDef->ShmName , usedMemSize , dataSize , useRate ) ; } } // テーブル/共有メモリグループ管理(TableId / ShmName)を一時領域に展開 char *c_ShmMngPtr = (char *)( s_ShmDefBase + GG_SHM1001_SHMIDNUM + 1 ) ; ST_TblShmMng s_TblShmMng ; memcpy ( (void *)&s_TblShmMng , c_ShmMngPtr , sizeof(ST_TblShmMng) ) ; long l_TblShmNum = 0 ; ST_TblShmDef *s_TblShmDef = (struct TblShmDefType *)malloc( sizeof(ST_TblShmDef) * 4096 ) ; if ( s_TblShmMng.ShmFlg == 1 ) { l_TblShmNum = s_TblShmMng.TblNum_A ; memcpy ( (void *)s_TblShmDef , c_ShmMngPtr + sizeof(ST_TblShmMng) , l_TblShmNum * sizeof(ST_TblShmDef) ) ; } else if ( s_TblShmMng.ShmFlg == 2 ) { l_TblShmNum = s_TblShmMng.TblNum_B ; memcpy ( (void *)s_TblShmDef , c_ShmMngPtr + sizeof(ST_TblShmMng) + ( sizeof(ST_TblShmDef) * 4096 ) , l_TblShmNum * sizeof(ST_TblShmDef) ) ; } // 共有メモリに元々あるテーブル/共有メモリグループ管理(TableId / ShmName)を最新化 for ( int i = 0 ; i < l_TblShmNum ; i ++ ) { int j = 0 ; for ( j = 0 ; j < TblDefNum ; j ++ ) { if ( strcmp ( s_TblShmDef[i].TblId , t_TblShmDef[j].TblId ) == 0 ) { strcpy ( s_TblShmDef[i].ShmName , t_TblShmDef[j].ShmName ) ; break ; } } if ( j == TblDefNum && strcmp ( s_TblShmDef[i].ShmName , argv[1] ) == 0 ) { s_TblShmDef[i].TblId[0] = '\0' ; s_TblShmDef[i].ShmName[0] = '\0' ; } } // 共有メモリにないテーブル/共有メモリグループ管理(TableId / ShmName)を追加 int k = 0 ; for ( int j = 0 ; j < TblDefNum ; j ++ ) { int i = 0 ; for ( i = 0 ; i < l_TblShmNum ; i ++ ) { if ( strcmp ( s_TblShmDef[i].TblId , t_TblShmDef[j].TblId ) == 0 ) { break ; } } if ( i == l_TblShmNum ) { strcpy ( s_TblShmDef[i+k].TblId , t_TblShmDef[j].TblId ) ; strcpy ( s_TblShmDef[i+k].ShmName , t_TblShmDef[j].ShmName ) ; k ++ ; } } // テーブル/共有メモリグループ管理(TableId / ShmName)のソート l_TblShmNum += k ; for(int i=0;ii;j--){ if(strcmp(s_TblShmDef[j].TblId,s_TblShmDef[j-1].TblId)<0){ ST_TblShmDef w_TblShm ; strcpy ( w_TblShm.TblId , s_TblShmDef[j].TblId ) ; strcpy ( w_TblShm.ShmName , s_TblShmDef[j].ShmName ) ; strcpy ( s_TblShmDef[j].TblId , s_TblShmDef[j-1].TblId ) ; strcpy ( s_TblShmDef[j].ShmName , s_TblShmDef[j-1].ShmName ) ; strcpy ( s_TblShmDef[j-1].TblId , w_TblShm.TblId ) ; strcpy ( s_TblShmDef[j-1].ShmName , w_TblShm.ShmName ) ; } } } // 識別管理面情報(s_TblShmMng)の共有メモリ設定 for ( int i=0 ; i < l_TblShmNum ; i++ ) { if ( s_TblShmDef[i].TblId[0] != '\0' ) { if ( s_TblShmMng.ShmFlg == 1 ) { memcpy ( c_ShmMngPtr + sizeof(ST_TblShmMng) + ( sizeof(ST_TblShmDef) * 4096 ) , (void *)&s_TblShmDef[i] , ( l_TblShmNum - i ) * sizeof(ST_TblShmDef) ) ; s_TblShmMng.TblNum_B = l_TblShmNum - i ; s_TblShmMng.ShmFlg = 2 ; memcpy ( c_ShmMngPtr , (void *)&s_TblShmMng , sizeof(ST_TblShmMng) ) ; } else if ( s_TblShmMng.ShmFlg == 0 || s_TblShmMng.ShmFlg == 2 ) { memcpy ( c_ShmMngPtr + sizeof(ST_TblShmMng) , (void *)&s_TblShmDef[i] , ( l_TblShmNum - i ) * sizeof(ST_TblShmDef) ) ; s_TblShmMng.TblNum_A = l_TblShmNum - i ; s_TblShmMng.ShmFlg = 1 ; memcpy ( c_ShmMngPtr , (void *)&s_TblShmMng , sizeof(ST_TblShmMng) ) ; } break ; } } // A(1) / B(2) 面 の切替 // -c1オプション(展開のみ)の場合、面を切替を行わない if ( strcmp ( "-c1" , argv[2] ) != 0 ) { option_c2_proc( s_ShmDef ); } else { } // 終了メッセージ出力 getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 テーブルデータ展開 **** END ****" , szAccessDate ) ; } /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ char*型同士の比較関数 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ int compare_str(const void* a, const void* b) { // printf("a=[%s] b=[%s]\n",a,b) ; return strcmp( (char *)a, (char *)b ); } /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ int型同士の比較関数 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ int compare_int(const void* a, const void* b) { // printf("a=[%d] b=[%d]\n",a,b) ; if ( *(int *)a < *(int *)b ) return -1 ; if ( *(int *)a > *(int *)b ) return 1 ; return 0 ; } /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ アクセスパターンファイルの読み込み テキスト形式での読み込み(libxml2が使用できないときに利用) _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ #ifdef _NONSTOP char* GG_SHM1100_NONSTOP ( char *filename ) { char c_data[512000]; char linedata[1000]; struct stat stat_buf ; char szAccessDate [ 30 ] ; // YYYY/MM/DD HH:MM:SS.mmmmmm // memset(c_data, 0, sizeof(c_data)); // memset(linedata, 0, sizeof(linedata)); // strcpy(linedata, "002 CMC0106001 BUSINESS_KBN = 1 and DATE >= ? DATE \n"); // strcat(c_data, linedata); // memset(linedata, 0, sizeof(linedata)); // strcpy(linedata, "002 CMC0106002 BUSINESS_KBN = 1 and DATE <= ? DATE \n"); // strcat(c_data, linedata); //002 CMC0106001 BUSINESS_KBN = 1 and DATE >= ? DATE //002 CMC0106002 BUSINESS_KBN = 1 and DATE <= ? DATE //002 CMC0106003 BUSINESS_KBN = 1 and DATE >= ? and DATE <= ? DATE1 DATE2 //002 CMC0103001 DATE = ? DATE //001 CMC0106002 BUSINESS_KBN = 1 and DATE <= ? DATE //001 CMC0106003 BUSINESS_KBN = 1 and DATE >= ? and DATE <= ? DATE1 DATE2 //001 CMC0105001 BUSINESS_KBN = 1 and DATE >= ? and DATE <= ? DATE1 DATE2 //001 CMC0103001 DATE = ? DATE FILE *TblDatafp ; char TextName [ MAX_PATH ] ; // テキストデータの読込 sprintf ( TextName , "%s.txt" , filename) ; if ( ( TblDatafp = fopen( TextName , "r" ) ) == NULL) { printf("file open error!! TblDefFile = [ %s ]\n" , TextName ); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 テキストデータの取得失敗 [ %s ]" , szAccessDate , TextName ) ; return (char *)NULL; } // テキストデータのサイズ取得 if ( stat ( TextName, &stat_buf ) != 0 ) { // printf("file stat error!! TblDefFile = [ %s ]\n" , TextName ); getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 0 , "**** ( %s ) **** GG_SHM1000 テキストデータのstat失敗 [ %s ]" , szAccessDate , TextName ) ; return (char *)NULL; } // テキストデータの読込 int BufSize = ( stat_buf.st_size + 1 ) * 2 ; char *TblDataChar = (char *)malloc ( BufSize ) ; char *ReadDataBuf = (char *)malloc ( BufSize ) ; char *TblDataCharBase = TblDataChar ; fread ( TblDataChar , 1 , stat_buf.st_size , TblDatafp ) ; fclose ( TblDatafp ) ; TblDataChar [ stat_buf.st_size - 1 ] = '\0' ; getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 [%s] ファイルサイズ=[%d]" , szAccessDate , TextName , stat_buf.st_size ) ; memcpy(c_data, TblDataChar, stat_buf.st_size); free ( TblDataCharBase ) ; free ( ReadDataBuf ) ; return c_data ; } #endif /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 三次元配列データの作成(テーブルデータの一時保存用に使用) _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ char*** GG_SHM1000_malloc( int rows , int cols , int colsize ) { // char pStructData [MAX_ROWS][MAX_COLUMNS][MAX_COLSIZE] ; // long MaxRows = getEnvLong("GG_SHM1000_MAX_ROWS",MAX_ROWS); // long MaxColumns = getEnvLong("GG_SHM1000_MAX_COLUMNS",MAX_COLUMNS); // MaxColSize = getEnvLong("GG_SHM1000_MAX_COLSIZE",MAX_COLSIZE); char szAccessDate [ 30 ] ; // YYYY/MM/DD HH:MM:SS.mmmmmm getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 GG_SHM1000_malloc 1 [%ld][%ld][%ld]" , szAccessDate,rows,cols,colsize ) ; char ***a, **b, *c; int i = rows; int j = cols; int t = sizeof(char) * colsize; a = (char***)malloc((sizeof(*a) + sizeof(**a) * j + t * j) * i); if(a == NULL){ return a; } if(a != NULL){ b = (char**)(a + i); c = (char*)(b + i * j); for(int idx1 = 0; idx1 < i; idx1++){ a[idx1] = b; for(int idx2 = 0; idx2 < j; idx2++){ b[idx2] = c; c += t; } b += j; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 GG_SHM1000_malloc 2 pStructData=[%x]" , szAccessDate,a ) ; } return a; } /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 二次元配列データの作成(qsortを行う際に使用) _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ char** GG_SHM1000_malloc_2( int rows , int colsize ) { char szAccessDate [ 30 ] ; // YYYY/MM/DD HH:MM:SS.mmmmmm getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 GG_SHM1000_malloc_2 1 [%ld][%ld]" , szAccessDate,rows,colsize ) ; char **b, *c; int i = rows; int t = sizeof(char) * colsize; b = (char**)malloc((sizeof(*b) + t) * i); if(b == NULL){ return b; } if(b != NULL){ c = (char*)(b + i); for(int idx1 = 0; idx1 < i; idx1++){ b[idx1] = c; c += t; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 GG_SHM1000_malloc_2 2 pStructData=[%x]" , szAccessDate,b ) ; } return b; } /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ qsort の結果を戻す(未使用) _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ void qsort_reset ( char **b , int rows , int colsize ) { char szAccessDate [ 30 ] ; // YYYY/MM/DD HH:MM:SS.mmmmmm getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 GG_SHM1000_qsort_reset 1 [%ld][%ld]" , szAccessDate,rows,colsize ) ; char *c; int i = rows; int t = sizeof(char) * colsize; c = (char*)(b + i); for(int idx1 = 0; idx1 < i; idx1++){ b[idx1] = c; c += t; } getLocalTimeString ( szAccessDate,sizeof(szAccessDate),"%Y/%m/%d %H:%M:%S.%U" ) ; GG_MsgOut ( g_szLogFilePath , 1 , "**** ( %s ) **** GG_SHM1000 GG_SHM1000_qsort_reset 2 pStructData=[%x]" , szAccessDate,b ) ; } /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 面切替 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ int option_c2_proc(ST_ShmDef *s_ShmDef) { if ( s_ShmDef->ShmFlg == 0 || s_ShmDef->ShmFlg == 2 ) { s_ShmDef->ShmFlg = 1 ; } else if ( s_ShmDef->ShmFlg == 1 ) { s_ShmDef->ShmFlg = 2 ; } return 0 ; } /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 文字列一括置換(buf上の文字列str1をstr2に全て変換) _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ void strchg(char *buf, const char *str1, const char *str2){ char tmp [ 1024 + 1 ] ; char *p ; while ( ( p = strstr ( buf , str1 ) ) != NULL ) { // pは旧文字列の先頭 *p = '\0'; // 元の文字列を旧文字列の直前で区切って p += strlen ( str1 ) ; // ポインタを旧文字列の次の文字列へ strcpy ( tmp , p ); // 旧文字列から後を保存 strcat ( buf , str2 ); // 新文字列をその後につなぎ strcat ( buf , tmp ); // さらに残りをつなぐ } } /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ ログ領域への追記と領域自動拡張 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ void appendLog (int *logLen , char **logBuff , const char *append) { if ( *logLen < strlen(*logBuff) + strlen(append) + 1 ) { *logLen = ( strlen(*logBuff) + strlen(append) ) * 2 + 1 ; char *logBuff_sv = (char *) malloc ( *logLen ) ; strcpy ( logBuff_sv , *logBuff ) ; free ( (char *) *logBuff ) ; *logBuff = logBuff_sv ; } strcat ( *logBuff , append ) ; }