1 /* $Id: zebramap.c,v 1.60 2007-10-30 19:17:15 adam Exp $
2 Copyright (C) 1995-2007
5 This file is part of the Zebra server.
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
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
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
29 #include <yaz/yaz-util.h>
33 #define ZEBRA_MAP_TYPE_SORT 1
34 #define ZEBRA_MAP_TYPE_INDEX 2
35 #define ZEBRA_MAP_TYPE_STATICRANK 3
37 #define ZEBRA_REPLACE_ANY 300
55 const char *maptab_name;
56 zebra_maps_t zebra_maps;
57 struct zebra_map *next;
65 const char *temp_map_ptr[2];
66 struct zebra_map **lookup_array;
70 zebra_map_t *last_map;
73 void zebra_maps_close(zebra_maps_t zms)
75 struct zebra_map *zm = zms->map_list;
79 chrmaptab_destroy(zm->maptab);
82 wrbuf_destroy(zms->wrbuf_1);
83 nmem_destroy(zms->nmem);
87 zebra_map_t zebra_add_map(zebra_maps_t zms, const char *index_type,
90 zebra_map_t zm = (zebra_map_t) nmem_malloc(zms->nmem, sizeof(*zm));
93 zm->reg_id = index_type[0];
99 zm->alwaysmatches = 0;
100 zm->first_in_field = 0;
104 zms->last_map = &zm->next;
111 ZEBRA_RES zebra_maps_read_file(zebra_maps_t zms, const char *fname)
121 if (!(f = yaz_fopen(zms->tabpath, fname, "r", zms->tabroot)))
123 yaz_log(YLOG_ERRNO|YLOG_FATAL, "%s", fname);
126 while ((argc = readconf_line(f, &lineno, line, 512, argv, 10)))
130 yaz_log(YLOG_WARN, "%s:%d: Missing arguments for '%s'",
131 fname, lineno, argv[0]);
137 yaz_log(YLOG_WARN, "%s:%d: Too many arguments for '%s'",
138 fname, lineno, argv[0]);
142 if (!yaz_matchstr(argv[0], "index"))
144 zm = zebra_add_map(zms, argv[1], ZEBRA_MAP_TYPE_INDEX);
147 else if (!yaz_matchstr(argv[0], "sort"))
149 zm = zebra_add_map(zms, argv[1], ZEBRA_MAP_TYPE_SORT);
150 zm->u.sort.entry_size = 80;
152 else if (!yaz_matchstr(argv[0], "staticrank"))
154 zm = zebra_add_map(zms, argv[1], ZEBRA_MAP_TYPE_STATICRANK);
155 zm->completeness = 1;
159 yaz_log(YLOG_WARN, "%s:%d: Missing sort/index before '%s'",
160 fname, lineno, argv[0]);
163 else if (!yaz_matchstr(argv[0], "charmap") && argc == 2)
165 if (zm->type != ZEBRA_MAP_TYPE_STATICRANK)
166 zm->maptab_name = nmem_strdup(zms->nmem, argv[1]);
169 yaz_log(YLOG_WARN|YLOG_FATAL, "%s:%d: charmap for "
170 "staticrank is invalid", fname, lineno);
171 yaz_log(YLOG_LOG, "Type is %d", zm->type);
175 else if (!yaz_matchstr(argv[0], "completeness") && argc == 2)
177 zm->completeness = atoi(argv[1]);
179 else if (!yaz_matchstr(argv[0], "position") && argc == 2)
181 zm->positioned = atoi(argv[1]);
183 else if (!yaz_matchstr(argv[0], "alwaysmatches") && argc == 2)
185 if (zm->type != ZEBRA_MAP_TYPE_STATICRANK)
186 zm->alwaysmatches = atoi(argv[1]);
189 yaz_log(YLOG_WARN|YLOG_FATAL, "%s:%d: alwaysmatches for "
190 "staticrank is invalid", fname, lineno);
194 else if (!yaz_matchstr(argv[0], "firstinfield") && argc == 2)
196 zm->first_in_field = atoi(argv[1]);
198 else if (!yaz_matchstr(argv[0], "entrysize") && argc == 2)
200 if (zm->type == ZEBRA_MAP_TYPE_SORT)
201 zm->u.sort.entry_size = atoi(argv[1]);
205 yaz_log(YLOG_WARN, "%s:%d: Unrecognized directive '%s'",
206 fname, lineno, argv[0]);
212 for (zm = zms->map_list; zm; zm = zm->next)
213 zms->lookup_array[zm->reg_id] = zm;
220 zebra_maps_t zebra_maps_open(Res res, const char *base_path,
221 const char *profile_path)
223 zebra_maps_t zms = (zebra_maps_t) xmalloc(sizeof(*zms));
226 zms->nmem = nmem_create();
228 zms->tabpath = profile_path ? nmem_strdup(zms->nmem, profile_path) : 0;
231 zms->tabroot = nmem_strdup(zms->nmem, base_path);
233 zms->last_map = &zms->map_list;
235 zms->temp_map_str[0] = '\0';
236 zms->temp_map_str[1] = '\0';
238 zms->temp_map_ptr[0] = zms->temp_map_str;
239 zms->temp_map_ptr[1] = NULL;
241 zms->lookup_array = (zebra_map_t *)
242 nmem_malloc(zms->nmem, sizeof(*zms->lookup_array)*256);
243 zms->wrbuf_1 = wrbuf_alloc();
245 for (i = 0; i<256; i++)
246 zms->lookup_array[i] = 0;
250 zebra_map_t zebra_map_get(zebra_maps_t zms, unsigned reg_id)
252 assert(reg_id >= 0 && reg_id <= 255);
253 return zms->lookup_array[reg_id];
256 zebra_map_t zebra_map_get_or_add(zebra_maps_t zms, unsigned reg_id)
258 struct zebra_map *zm = zebra_map_get(zms, reg_id);
265 zm = zebra_add_map(zms, name, ZEBRA_MAP_TYPE_INDEX);
267 /* no reason to warn if no maps are installed at ALL
268 Note that zebra_add_maps increments no_maps ..
270 if (zms->no_maps > 1)
271 yaz_log(YLOG_WARN, "Unknown register type: %c", reg_id);
275 zm->maptab_name = nmem_strdup(zms->nmem, "@");
276 zm->completeness = 0;
278 zm->next = zms->map_list;
279 zms->map_list = zm->next;
281 zms->lookup_array[zm->reg_id & 255] = zm;
286 chrmaptab zebra_charmap_get(zebra_map_t zm)
290 if (!zm->maptab_name || !yaz_matchstr(zm->maptab_name, "@"))
292 if (!(zm->maptab = chrmaptab_create(zm->zebra_maps->tabpath,
294 zm->zebra_maps->tabroot)))
295 yaz_log(YLOG_WARN, "Failed to read character table %s",
298 yaz_log(YLOG_DEBUG, "Read character table %s", zm->maptab_name);
303 const char **zebra_maps_input(zebra_map_t zm,
304 const char **from, int len, int first)
306 chrmaptab maptab = zebra_charmap_get(zm);
308 return chr_map_input(maptab, from, len, first);
310 zm->zebra_maps->temp_map_str[0] = **from;
313 return zm->zebra_maps->temp_map_ptr;
316 const char **zebra_maps_search(zebra_map_t zm,
317 const char **from, int len, int *q_map_match)
322 maptab = zebra_charmap_get(zm);
326 map = chr_map_q_input(maptab, from, len, 0);
332 map = chr_map_input(maptab, from, len, 0);
336 zm->zebra_maps->temp_map_str[0] = **from;
339 return zm->zebra_maps->temp_map_ptr;
342 const char *zebra_maps_output(zebra_map_t zm,
345 chrmaptab maptab = zebra_charmap_get(zm);
348 return chr_map_output(maptab, from, 1);
352 /* ------------------------------------ */
354 int zebra_maps_is_complete(zebra_map_t zm)
357 return zm->completeness;
361 int zebra_maps_is_positioned(zebra_map_t zm)
364 return zm->positioned;
368 int zebra_maps_is_index(zebra_map_t zm)
371 return zm->type == ZEBRA_MAP_TYPE_INDEX;
375 int zebra_maps_is_staticrank(zebra_map_t zm)
378 return zm->type == ZEBRA_MAP_TYPE_STATICRANK;
382 int zebra_maps_is_sort(zebra_map_t zm)
385 return zm->type == ZEBRA_MAP_TYPE_SORT;
389 int zebra_maps_is_alwaysmatches(zebra_map_t zm)
392 return zm->alwaysmatches;
396 int zebra_maps_is_first_in_field(zebra_map_t zm)
399 return zm->first_in_field;
403 int zebra_maps_sort(zebra_maps_t zms, Z_SortAttributes *sortAttributes,
409 attr_init_AttrList(&use, sortAttributes->list, 1);
410 attr_init_AttrList(&structure, sortAttributes->list, 4);
413 structure_value = attr_find(&structure, 0);
414 if (structure_value == 109)
416 return attr_find(&use, NULL);
419 int zebra_maps_attr(zebra_maps_t zms, Z_AttributesPlusTerm *zapt,
420 const char **index_type, char **search_type, char *rank_type,
421 int *complete_flag, int *sort_flag)
423 AttrType completeness;
426 AttrType sort_relation;
429 int completeness_value;
431 const char *structure_str = 0;
433 int sort_relation_value;
437 attr_init_APT(&structure, zapt, 4);
438 attr_init_APT(&completeness, zapt, 6);
439 attr_init_APT(&relation, zapt, 2);
440 attr_init_APT(&sort_relation, zapt, 7);
441 attr_init_APT(&weight, zapt, 9);
442 attr_init_APT(&use, zapt, 1);
444 completeness_value = attr_find(&completeness, NULL);
445 structure_value = attr_find_ex(&structure, NULL, &structure_str);
446 relation_value = attr_find(&relation, NULL);
447 sort_relation_value = attr_find(&sort_relation, NULL);
448 weight_value = attr_find(&weight, NULL);
449 use_value = attr_find(&use, NULL);
451 if (completeness_value == 2 || completeness_value == 3)
457 *sort_flag =(sort_relation_value > 0) ? 1 : 0;
458 *search_type = "phrase";
459 strcpy(rank_type, "void");
460 if (relation_value == 102)
462 if (weight_value == -1)
464 sprintf(rank_type, "rank,w=%d,u=%d", weight_value, use_value);
470 switch (structure_value)
472 case 6: /* word list */
473 *search_type = "and-list";
475 case 105: /* free-form-text */
476 *search_type = "or-list";
478 case 106: /* document-text */
479 *search_type = "or-list";
484 case 108: /* string */
485 *search_type = "phrase";
487 case 107: /* local-number */
488 *search_type = "local";
491 case 109: /* numeric string */
493 *search_type = "numeric";
497 *search_type = "phrase";
501 *search_type = "phrase";
505 *search_type = "phrase";
509 *search_type = "phrase";
512 if (structure_str && *structure_str)
513 *index_type = structure_str;
523 WRBUF zebra_replace(zebra_map_t zm, const char *ex_list,
524 const char *input_str, int input_len)
526 wrbuf_rewind(zm->zebra_maps->wrbuf_1);
527 wrbuf_write(zm->zebra_maps->wrbuf_1, input_str, input_len);
528 return zm->zebra_maps->wrbuf_1;
534 * indent-tabs-mode: nil
536 * vim: shiftwidth=4 tabstop=8 expandtab