find.c
changeset 17 d95d9e7a2b81
parent 14 a961bb8806b9
child 21 01fe372188ac
equal deleted inserted replaced
16:b4e251400e36 17:d95d9e7a2b81
     3 #include <sys/types.h>
     3 #include <sys/types.h>
     4 #include <sys/mman.h>
     4 #include <sys/mman.h>
     5 #include <fcntl.h>
     5 #include <fcntl.h>
     6 #include "dictre.h"
     6 #include "dictre.h"
     7 
     7 
     8 static unsigned char *index;
     8 const static char indexext[] = ".index";
     9 static int indexfd;
     9 const static char dictext[] = ".dict";
    10 static int indexsize;
       
    11 static FILE *defs;
       
    12 const static char indexname[] = "akcentiga.index";
       
    13 const static char dictname[] = "akcentiga.dict";
       
    14 
    10 
    15 int get_filesize(const char *fname)
    11 int get_filesize(const char *fname)
    16 {
    12 {
    17     struct stat st;
    13     struct stat st;
    18     int res;
    14     int res;
    25     }
    21     }
    26 
    22 
    27     return st.st_size;
    23     return st.st_size;
    28 }
    24 }
    29 
    25 
    30 void init_dictionary()
    26 void init_dictionary(struct Dict *d, const char *base)
    31 {
    27 {
    32     indexsize = get_filesize(indexname);
    28     char *filename;
    33     indexfd = open(indexname, O_RDONLY);
    29 
    34     if (indexfd == -1)
    30     filename = (char *) malloc(strlen(base) + 10);
       
    31 
       
    32     /* Prepare .index filename and open it*/
       
    33     strcpy(filename, base);
       
    34     strcat(filename, indexext);
       
    35 
       
    36     d->indexsize = get_filesize(filename);
       
    37     d->indexfd = open(filename, O_RDONLY);
       
    38     if (d->indexfd == -1)
    35     {
    39     {
    36         fprintf(stderr, "Problem opening the file %s\n", indexname);
    40         fprintf(stderr, "Problem opening the file %s\n", filename);
    37         perror("Error:");
    41         perror("Error:");
    38         exit(-1);
    42         exit(-1);
    39     }
    43     }
    40     index = (unsigned char *) mmap(0, indexsize, PROT_READ, MAP_SHARED,
    44     d->index = (unsigned char *) mmap(0, d->indexsize, PROT_READ, MAP_SHARED,
    41             indexfd, 0);
    45             d->indexfd, 0);
    42 
    46 
    43     defs = fopen(dictname, "r");
    47     /* Prepare .dict filename and open it*/
    44     if (defs == 0)
    48     strcpy(filename, base);
       
    49     strcat(filename, dictext);
       
    50     d->defs = fopen(filename, "r");
       
    51     if (d->defs == 0)
    45     {
    52     {
    46         fprintf(stderr, "Problem opening the file %s\n", dictname);
    53         fprintf(stderr, "Problem opening the file %s\n", filename);
    47         perror("Error:");
    54         perror("Error:");
    48         exit(-1);
    55         exit(-1);
    49     }
    56     }
       
    57 
       
    58     free(filename);
    50 }
    59 }
    51 
    60 
    52 void end_dictionary()
    61 void end_dictionary(struct Dict *d)
    53 {
    62 {
    54     munmap(index, indexsize);
    63     munmap(d->index, d->indexsize);
    55     close(indexfd);
    64     close(d->indexfd);
    56     fclose(defs);
    65     fclose(d->defs);
    57 }
    66 }
    58 
    67 
    59 static void fill_def(int offset, int length, char * def)
    68 static void fill_def(struct Dict *d, int offset, int length, char * def)
    60 {
    69 {
    61     fseek(defs, offset, SEEK_SET);
    70     fseek(d->defs, offset, SEEK_SET);
    62     fread(def, 1, length, defs);
    71     fread(def, 1, length, d->defs);
    63 }
    72 }
    64 
    73 
    65 static int pointer_at_end(unsigned char *ptr)
    74 static int pointer_at_end(struct Dict *d, unsigned char *ptr)
    66 {
    75 {
    67     if (ptr >= (index + indexsize))
    76     if (ptr >= (d->index + d->indexsize))
    68         return 1;
    77         return 1;
    69     return 0;
    78     return 0;
    70 }
    79 }
    71 
    80 
    72 static char * skip_until_newline(char *from)
    81 static char * skip_until_newline(struct Dict *d, char *from)
    73 {
    82 {
    74     if (pointer_at_end(from))
    83     if (pointer_at_end(d, from))
    75         return 0;
    84         return 0;
    76     while(*from != '\n' && *from != 0)
    85     while(*from != '\n' && *from != 0)
    77     {
    86     {
    78         ++from;
    87         ++from;
    79         if(pointer_at_end(from))
    88         if(pointer_at_end(d, from))
    80             return 0;
    89             return 0;
    81     }
    90     }
    82     return from;
    91     return from;
    83 }
    92 }
    84 
    93 
   107 
   116 
   108     /* It should never reach this. */
   117     /* It should never reach this. */
   109     return -1;
   118     return -1;
   110 }
   119 }
   111 
   120 
   112 static char * bin_search(const char *word)
   121 static char * bin_search(struct Dict *d, const char *word)
   113 {
   122 {
   114     int step, pivot;
   123     int step, pivot;
   115 
   124 
   116     pivot = indexsize / 2;
   125     pivot = d->indexsize / 2;
   117     step = indexsize / 2;
   126     step = d->indexsize / 2;
   118 
   127 
   119     do
   128     do
   120     {
   129     {
   121         char *test;
   130         char *test;
   122         int comparision;
   131         int comparision;
   123         test = index + pivot;
   132         test = d->index + pivot;
   124         test = skip_until_newline(test);
   133         test = skip_until_newline(d, test);
   125         if (test == 0)
   134         if (test == 0)
   126             return 0;
   135             return 0;
   127         test += 1; /* skip exactly the new line */
   136         test += 1; /* skip exactly the new line */
   128 
   137 
   129         comparision = compare(word, test);
   138         comparision = compare(word, test);
   155     val = str2int_len(start, i);
   164     val = str2int_len(start, i);
   156     *pos += i + 1;
   165     *pos += i + 1;
   157     return val;
   166     return val;
   158 }
   167 }
   159 
   168 
   160 void find_def(const char *word, char * def)
   169 void find_def(struct Dict *d, const char *word, char * def)
   161 {
   170 {
   162     int offset, len;
   171     int offset, len;
   163     char *pos;
   172     char *pos;
   164 
   173 
   165     pos = bin_search(word); /* pos points to the offset already. */
   174     pos = bin_search(d, word); /* pos points to the offset already. */
   166     if (pos == 0)
   175     if (pos == 0)
   167     {
   176     {
   168         def[0] = 0;
   177         def[0] = 0;
   169         /*fprintf(stderr, "Cannot find %s\n", word);*/
   178         /*fprintf(stderr, "Cannot find %s\n", word);*/
   170         return;
   179         return;
   171     }
   180     }
   172     offset = my_get_int(&pos); /* increments pos */
   181     offset = my_get_int(&pos); /* increments pos */
   173     len = my_get_int(&pos); /* increments pos */
   182     len = my_get_int(&pos); /* increments pos */
   174     fill_def(offset, len, def);
   183     fill_def(d, offset, len, def);
   175 }
   184 }