MUSASHI C source: mssInput.h


構造体、共用体、列挙体
struct TTnode struct mssFPR struct mssFileInfo struct mssFldRec struct mssFldRecDbl struct mssFldRecKey struct mssFldRecMax struct mssRec struct mssSortDat


DEFINE,マクロ
MaxLineS MaxMemS MaxPntSize PWayS PipeSize ReadCnt


0001: /** 
0002:  * # CHAPTER # 
0003:  * ============================================================================ 
0004:  * MUSASHIで用いられるXMLtableデータの入力関連のヘッダーファイル 
0005:  * ============================================================================ 
0006:  */ 
0007:  
0008: #include <stdio.h> 
0009: #include <zlib.h> 
0010:  
0011: #include <mssHeader.h
0012: #include <mssConfig.h
0013: #include <mssOutput.h
0014: #include <mssOption.h
0015:  
0016:  
0017: #ifndef __MSSINPUT_H 
0018: #define __MSSINPUT_H 1 
0019:  
0020: /** 
0021:  * # DEFINE # 
0022:  * マージソートを行う際に、何個までのファイルを同時に併合させるか 
0023:  */ 
0024: #define PWayS 25 
0025:  
0026: /** 
0027:  * # DEFINE # 
0028:  * 分割ソートでのデータ読み込みバッファサイズの上限値 
0029:  * この値、もしくはMssMaxLineSortのいずれかが上限値に達したときのデータが 
0030:  * 分割ソートにおける一つのバケットとなる。 
0031:  */ 
0032: #define MaxMemS 2048000 
0033:  
0034: /** 
0035:  * # DEFINE # 
0036:  * 分割ソートでのデータ読み込み行数の上限値 
0037:  * この値、もしくはMssMaxMemSortのいずれかが上限値に達したときのデータが 
0038:  * 分割ソートにおける一つのバケットとなる。 
0039:  */ 
0040: #define MaxLineS 50000 
0041:  
0042: /** 
0043:  * # DEFINE # 
0044:  * パイプのバッファサイズ 
0045:  */ 
0046: #define PipeSize 4096 
0047:  
0048: /** 
0049:  * # DEFINE # 
0050:  * リングバッファの一つのキューのブロック数 
0051:  */ 
0052: #define ReadCnt 4 
0053:  
0054: /** 
0055:  * # DEFINE # 
0056:  * FRM構造体におけるポインタバッファのメモリ量上限値 
0057:  */ 
0058: #define MaxPntSize 2048000 
0059:  
0060: /** 
0061:  * # STRUCT # 
0062:  * トーナメントツリーのデータ構造 
0063:  * 
0064:  *                 (1) 
0065:  *          +-------+--------+ 
0066:  *          |                | 
0067:  *         (2)              (3) 
0068:  *    +-----+------+     +---+--+ 
0069:  *    |            |     |      | 
0070:  *   (4)          (5)   (6)    (7) 
0071:  *  +--+--+     +--+--+ 
0072:  *  |     |     |     | 
0073:  * (8)   (9)  (10)  (11) 
0074:  * 各ノード毎にTTnode構造体が張りつけられる 
0075:  * ノード番号(4)についてみると、 
0076:  * node->parent  は (2) 
0077:  * node->brother は (5)となる。 
0078:  * node->key はTTkey構造体へのポインタで実際の文字列を示すと考えればよい。 
0079:  * node->key->strが実際の文字列へのポインタを示し 
0080:  * node->key->bktはそのstr文字列がPwayマージソートで分割されたバケット番号 
0081:  *                                                          (ファイル番号) 
0082:  */ 
0083: struct TTnode { 
0084:   int num;           /*ノード番号*/ 
0085:   struct TTkey { 
0086:     char   *str;     /*キーの文字列*/ 
0087:     int     bkt;     /*分割ソートにおけるバケット番号*/ 
0088:   } *key; 
0089:   struct TTnode *parent;  /*親ノード*/ 
0090:   struct TTnode *brother; /*兄弟ノード*/ 
0091: }; 
0092:  
0093: /** 
0094:  * # STRUCT # 
0095:  * ソート用のデータ構造 
0096:  * ソートのアルゴリズムは、実装において非常に複雑になっている。 
0097:  * 複雑さの原因は、数値や逆順ソートと通常の文字ソートを同一プログラムで 
0098:  * 扱っているところになる。 
0099:  * 数値逆順ソートでは全ての処理において、キーの比較を項目単位で行っているため 
0100:  * 読み込みおよびTNtreeでは項目を区切って処理している。 
0101:  * 一方で、通常の文字ソートの場合は、最初にデータを読み込む際に、項目をキー順 
0102:  * に並べ換える。そうすることによって、後の処理では項目を区切ることなく処理 
0103:  * できる。比較は、一行単位で先頭から文字比較をすればよい。 
0104:  * このアルゴリズムの違いによって、通常の文字ソートはかなり高速になる。 
0105:  * 500万件のベンチマークにおいて、約1.3倍の高速化が実現できている。 
0106:  * 両者のソートを数値逆順ソートにあわせることもできるが、そうすると、 
0107:  * プログラムが非常にシンプルになる代わりに、処理が遅くなる。 
0108:  * 通常の利用においては、単純な文字ソートの方が利用率が圧倒的に多いと予測される 
0109:  * ので、プログラムのシンプルさより、高速性を選んだ。 
0110:  */ 
0111: struct mssSortDat { 
0112:   struct TTnode  *tt;               /*トーナメントツリー(プライオリティキュー)*/ 
0113:   struct mssFPR  *iFile[PWayS];     /*入力ワークファイルポインタ*/ 
0114:   struct mssRec  *rec[PWayS];       /*入力ワークファイル読み込みバッファ*/ 
0115:   struct mssFldRec *fr[PWayS];        /*数値や逆順ソートでの読み込みバッファ*/ 
0116:   char            prefix[MssFileNameMaxLen]; /*ワークファイル名のprefix*/ 
0117:   int             iStart;           /*開始入力ファイル番号*/ 
0118:   int             iEnd;             /*終了入力ファイル番号*/ 
0119:   int             bktCnt;           /*バケットの数(iEnd-iStart+1)*/ 
0120:   struct mssFields *flds;           /*ソート項目*/ 
0121:   int             fldCnt;           /*データの全項目数*/ 
0122:   int             recCnt;           /*データのレコード数*/ 
0123:   int             conv[MssFieldMaxCnt];/*要素:ソート項目順番 値:infileの項目番号*/ 
0124: }; 
0125:  
0126: /** 
0127:  * # STRUCT # 
0128:  * 入力バッファの構造体(リングバッファ) 
0129:  * 
0130:  * バッファの全体像                  1つのキューの内容(読み込み単位) 
0131:  * fp->que -----+---------------+        
0132:  *              |MssRecordMaxLen|    / +------------+ 
0133:  *              +---------------+   /  |PipeSize    |0 
0134:  *             0|fp->queSize    |  /   +------------+ 
0135:  *              |               | /    |            |1 
0136:  *              +---------------+/     +------------+ 
0137:  *             1|               |      |     :      | 
0138:  *              |               |      |     :      | 
0139:  *              +---------------+\     |     :      | 
0140:  *              |       :       | \    |     :      | 
0141:  *              |       :       |  \   +------------+ 
0142:  *              |       :       |   \  |            |ReadCnt 
0143:  *              +---------------+    \ +------------+ 
0144:  *              |               | 
0145:  *    fp->queCnt|               | 
0146:  *              +---------------+ 
0147:  */ 
0148: struct mssFPR { 
0149:   char *fName;  /*ファイル名へのポインタ(NULL:標準入力)*/ 
0150:   char *curPnt; /*現在の読み込みポインタ*/ 
0151:   char *buf;    /*リングバッファデータ本体*/ 
0152:   int   queCnt; /*queueの数 2の階乗でなければならない*/ 
0153:   int   queSize;/*queのサイズ=queCnt*PipeSize(毎回計算で求めるのが遅いので)*/ 
0154:   int   enq;    /*次に読みこむバッファ番号*/ 
0155:   int   deq;    /*有効なバッファの開始番号*/ 
0156:   int   full;   /*バッファfullフラグ*/ 
0157:   int   last;   /*eofを含む読み込みを行ったフラグ*/ 
0158:   int   recCnt; /*これまでに読み込んだレコードのカウント*/ 
0159:   int   chrCnt; /*これまでに読み込んだ文字のカウント*/ 
0160:  
0161:   int   zflg;   /*圧縮ファイル(1)か、通常ファイル(0)か?*/ 
0162:   gzFile zfd;   /*圧縮ファイル*/ 
0163:   FILE *fp;     /*通常ファイル*/ 
0164:  
0165:   int   sort;   /*通常ファイル(0)かソートファイル(1)か? reopenFPRsortでセット*/ 
0166:   struct mssSortDat *sd; /*ソートファイルオブジェクト*/ 
0167:   char *readPnt;         /*データの読み込みポイント*/ 
0168: }; 
0169:  
0170: /** 
0171:  * # STRUCT # 
0172:  * 一行読み込み構造体 
0173:  * 項目による分割はおこなわない。 
0174:  */ 
0175: struct mssRec { 
0176:   char *pnt;    /*行の先頭へのポインタ*/ 
0177:   int   chrCnt; /*読みこんだ文字数*/ 
0178:   int   eof;    /*ファイルを読み切った時にセットされる*/ 
0179: }; 
0180:  
0181: /** 
0182:  * # STRUCT # 
0183:  * 項目によるトークン分割をともなった一行単位読み込み構造体 
0184:  */ 
0185: struct mssFldRec { 
0186:   char **pnt;   /*各項目へのポインタ*/ 
0187:   int fldCnt;   /*項目数(初期化initFldRec時にセットされる)*/ 
0188:   int   chrCnt; /*読みこんだ文字数*/ 
0189:   int   eof; 
0190: }; 
0191:  
0192: /** 
0193:  * # STRUCT # 
0194:  * 項目によるトークン分割をともなった二行単位読み込み構造体 
0195:  * キーブレーク処理を行うときに利用する。 
0196:  */ 
0197: struct mssFldRecDbl { 
0198:   char **pnt[2]; /*各行各項目へのポインタ*/ 
0199:   int new;       /*0 or 1: pnt[new]で現在行の項目をさす*/ 
0200:   int old;       /*0 or 1: pnt[old]で前行の項目をさす*/ 
0201:   int firstRead; /*最初の一行のキーブレーク時にのみ例外処理するためのフラグ*/ 
0202:   int eof;       /*ファイルを読み切った時にセットされる*/ 
0203:   int newChrCnt; /*読みこんだ文字数(new)*/ 
0204:   int oldChrCnt; /*読みこんだ文字数(old)*/ 
0205:   int fldCnt;    /*項目数(初期化initFRD時にセットされる)*/ 
0206: }; 
0207:  
0208: /** 
0209:  * # STRUCT # 
0210:  * 項目によるトークン分割をともなったn行単位読み込み構造体 
0211:  * nの値はFPRのバッファの大きさ、もしくはMaxPntSizeで決まる。 
0212:  */ 
0213: struct mssFldRecMax { 
0214:   char **pnt;      /*各行各項目へのポインタ 
0215:                     (*(pnt+fldCnt*行番号)+項目番号)で行番号の項目番号をさす*/ 
0216:   int    fldCnt;   /*項目数(初期化initFldRec時にセットされる)*/ 
0217:   int    chrCnt;   /*読みこんだ文字数*/ 
0218:   int    eof;      /*ファイルを読み切った時にセットされる*/ 
0219:   int    recCnt;   /*読み込んだ行数*/ 
0220:   int    recMax;   /*MaxPntSizeから計算される、読み込み行数の上限値*/ 
0221: }; 
0222:  
0223: /** 
0224:  * # STRUCT # 
0225:  * 項目によるトークン分割をともなったキー単位読み込み構造体 
0226:  */ 
0227: struct mssFldRecKey { 
0228:   char **pnt;       /*一行単位の項目ポインタ*/ 
0229:   int    fldCnt;    /*項目数(初期化initFRK時にセットされる)*/ 
0230:   int    chrCnt;    /*読みこんだ文字数*/ 
0231:   int    eof;       /*ファイルを読み切った時にセットされる*/ 
0232:   int    keyRecCnt; /*現在のキーに含まれる行数*/ 
0233:   int    keyNo;     /*現在の通しキー番号*/ 
0234:  
0235:   char **frPnt;     /*項目行を格納するポインタ*/ 
0236:   int firstRead;    /*最初の一行のキーブレーク時にのみ例外処理するためのフラグ*/ 
0237:   int    alcRecCnt; /*pntに領域確保された行数*/ 
0238:   int    recPnt;    /*pntに読み込む位置(行番号)*/ 
0239:   MssOptKEY *optKey;   /*キー*/ 
0240:   int     byFile;   /*一時ファイルに出力されたかどうかのフラグ*/ 
0241:   char   fName[MssFileNameMaxLen]; /*一時ファイル名*/ 
0242:   struct mssFPW *fpw;  /*内部で利用するワークファイル用*/ 
0243:   struct mssFPR *fpr;/*内部で利用するワークファイル用*/ 
0244:   struct mssFldRec *fr;/*ワークファイルから行単位で読み込むため*/ 
0245:   int    curRecNo;  /*現在処理中の行番号*/ 
0246: }; 
0247:  
0248: /** 
0249:  * # STRUCT # 
0250:  * ファイルステータスの構造体 
0251:  */ 
0252: struct mssFileInfo { 
0253:   int   maxCnt;    /* 0:データ部を完全に読み込む n:n行まで*/ 
0254:   char *fName;     /*ファイル名*/ 
0255:   int   totalSize; /*-tの時はtotalSize==bodySize*/ 
0256:   int   readEnd;   /*最終行まで読み込んだかどうか*/ 
0257:   int   bodySize;  /*データ本体*/ 
0258:   int   fldCnt;    /*項目数*/ 
0259:   int   recCnt;    /*レコード数*/ 
0260: }; 
0261:  
0262: /** 
0263:  * # PROTOTYPE #  
0264:  */ 
0265: struct mssFileInfo *  mssGetFileInfo(char *fName, int recMax); 
0266: struct mssRec * mssInitRec(void); 
0267: void         mssFreeRec(struct mssRec *rec); 
0268: int          mssReadRec(struct mssFPR *fp, struct mssRec *rec); 
0269: struct mssFldRec * mssInitFldRec(int fldCnt); 
0270: void            mssFreeFldRec(struct mssFldRec* fr); 
0271: int             mssReadFldRec(struct mssFPR *fp, struct mssFldRec *fr); 
0272: int  mssReadRandFldRec(struct mssFPR *fp, struct mssFldRec *fr, int recNo, int datTop, int recLen); 
0273: struct mssFldRecDbl * mssInitFRD(int fldCnt); 
0274: void               mssFreeFRD(struct mssFldRecDbl *frd); 
0275: int                mssReadFRD(struct mssFPR *fp, struct mssFldRecDbl *frd); 
0276: int                mssKeyBreak(struct mssFldRecDbl *frd, MssOptKEY *optKey); 
0277: struct mssFldRecMax * mssInitFRM(int fldCnt); 
0278: void  mssFreeFRM(struct mssFldRecMax *frm); 
0279: int  mssReadFRM(struct mssFPR *fp, struct mssFldRecMax *frm); 
0280: struct mssFldRecKey * mssInitFRK(int fldCnt,MssOptKEY *optKey,char *path); 
0281: void               mssFreeFRK(struct mssFldRecKey *frk); 
0282: int                mssReadFRK(struct mssFPR *fp, struct mssFldRecKey *frk); 
0283: int mssReadFldRecFRK(struct mssFldRecKey *frk); 
0284: void mssSeekTopFRK(struct mssFldRecKey *frk); 
0285: int  mssGetFldCntOnData(struct mssFPR *fp); 
0286: void  mssSeekTopFPR(struct mssFPR *fp); 
0287: struct mssFPR * mssOpenFPR(char *fileName, int bufCnt); 
0288: struct mssFPR * mssReopenFPRsort(struct mssFPR *inFile, int queCnt, struct mssFields *flds, int fldCnt, char *tmpPath); 
0289: void mssCloseFPR(struct mssFPR *fp); 
0290: struct mssFPR * mssOpenFPU(char *fileName, int queCnt); 
0291: void         mssCloseFPU(struct mssFPR *fp); 
0292:  
0293: #endif /* _INPUT_H */