Added a timing test, minor modifications in 02
[idzebra-moved-to-github.git] / dict / lookup.c
1 /* $Id: lookup.c,v 1.11 2002-08-02 19:26:55 adam Exp $
2    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
3    Index Data Aps
4
5 This file is part of the Zebra server.
6
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra.  If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.
21 */
22
23
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <assert.h>
29
30 #include <dict.h>
31
32 static char *dict_look (Dict dict, const Dict_char *str, Dict_ptr ptr)
33 {
34     int mid, lo, hi;
35     int cmp;
36     void *p;
37     short *indxp;
38     char *info;
39
40     dict_bf_readp (dict->dbf, ptr, &p);
41     mid = lo = 0;
42     hi = DICT_nodir(p)-1;
43     indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));    
44     while (lo <= hi)
45     {
46         mid = (lo+hi)/2;
47         if (indxp[-mid] > 0)
48         {
49             /* string (Dict_char *) DICT_EOS terminated */
50             /* unsigned char        length of information */
51             /* char *               information */
52             info = (char*)p + indxp[-mid];
53             cmp = dict_strcmp((Dict_char*) info, str);
54             if (!cmp)
55                 return info+(dict_strlen ((Dict_char*) info)+1)
56                     *sizeof(Dict_char);
57         }
58         else
59         {
60             Dict_char dc;
61             Dict_ptr subptr;
62
63             /* Dict_ptr             subptr */
64             /* Dict_char            sub char */
65             /* unsigned char        length of information */
66             /* char *               information */
67             info = (char*)p - indxp[-mid];
68             memcpy (&dc, info+sizeof(Dict_ptr), sizeof(Dict_char));
69             cmp = dc- *str;
70             if (!cmp)
71             {
72                 memcpy (&subptr, info, sizeof(Dict_ptr));
73                 if (*++str == DICT_EOS)
74                 {
75                     if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
76                         return info+sizeof(Dict_ptr)+sizeof(Dict_char);
77                     return NULL;
78                 }
79                 else
80                 {
81                     if (subptr == 0)
82                         return NULL;
83                     ptr = subptr;
84                     dict_bf_readp (dict->dbf, ptr, &p);
85                     mid = lo = 0;
86                     hi = DICT_nodir(p)-1;
87                     indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
88                     continue;
89                 }
90             }
91         }
92         if (cmp < 0)
93             lo = mid+1;
94         else
95             hi = mid-1;
96     }
97     return NULL;
98 }
99
100 char *dict_lookup (Dict dict, const char *p)
101 {
102     if (!dict->head.root)
103         return NULL;
104     return dict_look (dict, (const Dict_char *) p, dict->head.root);
105 }