Advertisement
Guest User

Untitled

a guest
Dec 6th, 2017
338
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.59 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/mman.h>
  5. #include <sys/stat.h>
  6. #include <sys/types.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9.  
  10. #define DATA_FILE "../sequence.dat"
  11. #define INDEX_FILE "sequence.vbsi"
  12. #define KEY_LEN 11
  13. #define DICT_SIZE 4194304
  14. #define KEY_MASK  4194303  /* 4**11 -1 */
  15. #define MAX_LIST_LEN 3000
  16. #define LIST_NO_RECORD 0xFFFFFFFF
  17. #define VERSION 0x01010100
  18.  
  19. typedef struct {     // Ячейка словаря
  20.   u_int32_t count;   // Количество вхождений ключа
  21.   u_int32_t point;   // Первый элемент в списке или позиция вхождения
  22. } dictCell;
  23. typedef struct {     // Заголовок индексного файла
  24.   int version;       // Версия
  25.   int dictSize;      // Размер словаря
  26.   int NlistSize;     // Размер секции Nlist
  27.   int keyLen;        // Длина ключа
  28. } indexHeader;
  29. void error(const char *);
  30. int Index(dictCell *dict,unsigned char *src,int srcLen,void *,int);
  31.  
  32. int main() {
  33.   struct stat statbuf;
  34.   indexHeader header;
  35.   int fdin,fdout,srcLen;
  36.   unsigned char *src;
  37.   dictCell *dict;
  38.   void *listData;
  39.   if ( (fdin = open(DATA_FILE, O_RDONLY)) < 0 )
  40.     error("Error opening data file");
  41.   if ( (fdout = open(INDEX_FILE, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0 )
  42.     error("Error opening index file for writing");
  43.   if ( fstat(fdin, &statbuf) < 0 )
  44.     error("fstat error");
  45.   srcLen=statbuf.st_size;
  46.   if ( (src = mmap(0, srcLen, PROT_READ, MAP_SHARED, fdin, 0)) == MAP_FAILED )
  47.     error("data file mmap error");
  48.   dict=(dictCell *)malloc(sizeof(dictCell)*DICT_SIZE);
  49.   if(dict==NULL) error("Memory allocation error (for dict)");
  50.   memset(dict,0,sizeof(dictCell)*DICT_SIZE);
  51.   int NlistCells=Index(dict,src,srcLen,NULL,0); // Первый проход, подсчет статистики
  52.   int i,listSize=0,keyCnt=0,nIndex=0;
  53.   for(i=0;i<DICT_SIZE;i++) {
  54.     if(dict[i].count > 0 && dict[i].count < MAX_LIST_LEN) {
  55.       dict[i].point=listSize;
  56.       listSize+=dict[i].count;
  57.       keyCnt++;
  58.     } else if(dict[i].count >= MAX_LIST_LEN) {
  59.       nIndex++;
  60.       dict[i].point=LIST_NO_RECORD;
  61.     }
  62.     dict[i].count=0;
  63.   }
  64.   printf("\nNlistCells=%d srcLen=%d listSize=%d keyCnt=%d notIndexedKeys=%d\n",
  65.          NlistCells,srcLen,listSize,keyCnt,nIndex);
  66.   int listDataSize=sizeof(u_int32_t)*listSize+sizeof(dictCell)*NlistCells;
  67.   listData=malloc(listDataSize);
  68.   if(listData==NULL) error("Memory allocation error (for list)");
  69.   Index(dict,src,srcLen,listData,NlistCells);  // Второй проход, индексация
  70.   printf("Index complete. Writing ...\n");
  71.   header.version=VERSION;
  72.   header.dictSize=DICT_SIZE;
  73.   header.keyLen=KEY_LEN;
  74.   header.NlistSize=NlistCells;
  75.   i=write(fdout,&header,sizeof(header));
  76.   i=write(fdout,dict,sizeof(dictCell)*DICT_SIZE);
  77.   i=write(fdout,listData,listDataSize);
  78.   printf("COMPLETE\n");
  79. }
  80. int Index(dictCell *dict,unsigned char *src,int srcLen,void *listData,int NlistCells)
  81. {
  82.   int Npos=-1;
  83.   int keyLen=0;
  84.   int NlistCnt=0;
  85.   dictCell *Nlist=NULL;
  86.   int *List=NULL;
  87.   if(listData!=NULL) {
  88.     Nlist=(dictCell *)listData;
  89.     List=(int *)(((char *)listData)+sizeof(dictCell)*NlistCells);
  90.     NlistCells=0;
  91.   }
  92.   u_int32_t key;
  93.   int i,flg=0;
  94. // Подсчет количества элементов в разбивке по ключам
  95.   for(i=0;i<srcLen;i++) {
  96.     unsigned char ch=src[i];
  97.     if(ch=='N') {  // Есть фиксируемая N-цепочка, считаем
  98.       if(NlistCnt) {
  99.         if(Nlist) Nlist[NlistCells-1].count++;
  100.         NlistCnt++;
  101.         continue;
  102.       }
  103.       if(Npos==0) {  // Предыдущий символ был N, а N-цепочка еще не начата
  104.         if(Nlist) {
  105.           Nlist[NlistCells].count=1;
  106.           Nlist[NlistCells].point=i-1;
  107.         }
  108.         NlistCells++;
  109.         NlistCnt++;
  110.       }
  111.       if(Npos>=0) {  // В ключе уже есть N. Не рассматриваем ключи с >1 N
  112.         keyLen=0; key=0; continue;
  113.       }
  114.       Npos=0; key=(key<<2) & KEY_MASK; // key*=размер_алфавита
  115.     } else {  // Встречен нормальный символ (может нужна проверка ?)
  116.       key=((key<<2) | ((ch >> 1)&3)) & KEY_MASK;
  117.       if(Npos>=0) Npos++;
  118.       if(Npos>=KEY_LEN) Npos=-1;    // N ушел за пределы ключа
  119.       NlistCnt=0;  // Цепочка N закончена, если она была
  120.     }
  121.     if(keyLen<KEY_LEN) {
  122.       keyLen++;
  123.       if(keyLen<KEY_LEN) continue;  // Формирование ключа не закончено
  124.     }
  125.     if(List && dict[key].point!=LIST_NO_RECORD) {
  126. //      if(!flg) {
  127. //        flg++;
  128. //        printf("SaveFirst (%d) to %d+%d\n",i-KEY_LEN+1,dict[key].point,dict[key].count);
  129. //      }
  130.       List[ dict[key].point + dict[key].count ]=i-KEY_LEN+1;
  131.     }
  132.     dict[key].count++;
  133.     if(Npos>=0) {  // В ключе есть N, надо писать другие ключи
  134.      u_int32_t Nmask=~(3 << Npos*2);
  135.      int j;
  136.      for(j=1;j<=3;j++) {
  137.        key|=j << Npos*2;
  138.        if(List && dict[key].point!=LIST_NO_RECORD) {
  139.          List[ dict[key].point + dict[key].count ]=i-KEY_LEN;
  140.        }
  141.        dict[key].count++;
  142.        key&=Nmask;
  143.      }
  144.      ;
  145.     }
  146.   }
  147. //  if(List) printf("List[0]=%d\n",List[0]);
  148.   if(Nlist) {
  149.     for(i=0;i<NlistCells;i++) {
  150.       Nlist[i].count=Nlist[i].point+Nlist[i].count-1;
  151.     }
  152.   }
  153.   return NlistCells;
  154. }
  155.  
  156. void error(const char *msg) {
  157.   printf("%s\n",msg);
  158.   _exit(1);
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement