X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=blobdiff_plain;f=index%2Frpnscan.c;h=598ca7faa27843e44feb0bf679c57e79e4559686;hp=b4e9fa8e0afddcd182368d1b8a432c268deb3d1e;hb=e2e073b5c947e996304ed7d577497af5e9a879ee;hpb=1aac6e217a6ff917fdacabec636aa00cbf2f3226 diff --git a/index/rpnscan.c b/index/rpnscan.c index b4e9fa8..598ca7f 100644 --- a/index/rpnscan.c +++ b/index/rpnscan.c @@ -1,8 +1,5 @@ -/* $Id: rpnscan.c,v 1.18 2007-11-01 14:10:03 adam Exp $ - Copyright (C) 1995-2007 - Index Data ApS - -This file is part of the Zebra server. +/* This file is part of the Zebra server. + Copyright (C) Index Data Zebra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -20,6 +17,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#if HAVE_CONFIG_H +#include +#endif #include #include #ifdef WIN32 @@ -41,26 +41,38 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define RPN_MAX_ORDS 32 -int log_scan = YLOG_LOG; - /* convert APT SCAN term to internal cmap */ static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt, char *termz, zebra_map_t zm) { - char termz0[IT_MAX_WORD]; + char term_utf8[IT_MAX_WORD]; - if (zapt_term_to_utf8(zh, zapt, termz0) == ZEBRA_FAIL) + if (zapt_term_to_utf8(zh, zapt, term_utf8) == ZEBRA_FAIL) return ZEBRA_FAIL; /* error */ + else if (zebra_maps_is_icu(zm)) + { + const char *res_buf; + size_t res_len; + zebra_map_tokenize_start(zm, term_utf8, strlen(term_utf8)); + + if (zebra_map_tokenize_next(zm, &res_buf, &res_len, 0, 0)) + { + memcpy(termz, res_buf, res_len); + termz[res_len] = '\0'; + } + else + termz[0] = '\0'; + } else { const char **map; - const char *cp = (const char *) termz0; + const char *cp = (const char *) term_utf8; const char *cp_end = cp + strlen(cp); const char *src; int i = 0; const char *space_map = NULL; int len; - + while ((len = (cp_end - cp)) > 0) { map = zebra_maps_input(zm, &cp, len, 0); @@ -81,33 +93,8 @@ static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt, return ZEBRA_OK; } -static void count_set(ZebraHandle zh, RSET rset, zint *count, zint approx_limit) -{ - zint psysno = 0; - struct it_key key; - RSFD rfd; - - yaz_log(YLOG_DEBUG, "count_set"); - - rset->hits_limit = approx_limit; - - *count = 0; - rfd = rset_open(rset, RSETF_READ); - while (rset_read(rfd, &key,0 /* never mind terms */)) - { - if (key.mem[0] != psysno) - { - psysno = key.mem[0]; - if (rfd->counted_items >= rset->hits_limit) - break; - } - } - rset_close(rfd); - *count = rset->hits_count; -} - -static void get_first_snippet_from_rset(ZebraHandle zh, - RSET rset, zebra_snippets *snippets, +static void get_first_snippet_from_rset(ZebraHandle zh, + RSET rset, zebra_snippets *snippets, zint *sysno) { struct it_key key; @@ -162,11 +149,6 @@ static int scan_handle2(char *name, const char *info, int pos, void *client) len_prefix = strlen(scan_info->prefix); if (memcmp(name, scan_info->prefix, len_prefix)) return 1; - - /* skip special terms such as first-in-field specials */ - if (name[len_prefix] < CHR_BASE_CHAR) - return 1; - wrbuf_rewind(scan_info->term); wrbuf_puts(scan_info->term, name+len_prefix); @@ -180,7 +162,7 @@ static int scan_save_set(ZebraHandle zh, ODR stream, NMEM nmem, struct rset_key_control *kc, Z_AttributesPlusTerm *zapt, RSET limit_set, - const char *term, + const char *term, const char *index_type, struct scan2_info_entry *ar, int ord_no, ZebraScanEntry *glist, int pos) @@ -191,38 +173,41 @@ static int scan_save_set(ZebraHandle zh, ODR stream, NMEM nmem, AttrType global_hits_limit_attr; int l; attr_init_APT(&global_hits_limit_attr, zapt, 12); - + l = attr_find(&global_hits_limit_attr, NULL); if (l != -1) approx_limit = l; - + for (i = 0; i < ord_no; i++) { if (ar[i].isam_p && strcmp(wrbuf_cstr(ar[i].term), term) == 0) { - struct ord_list *ol = ord_list_create(nmem); - RSET rset_t; + if (strcmp(term, FIRST_IN_FIELD_STR)) + { + struct ord_list *ol = ord_list_create(nmem); + RSET rset_t; - ol = ord_list_append(nmem, ol, ar[i].ord); + ol = ord_list_append(nmem, ol, ar[i].ord); - assert(ol); - rset_t = rset_trunc( + assert(ol); + rset_t = rset_trunc( zh, &ar[i].isam_p, 1, wrbuf_buf(ar[i].term), wrbuf_len(ar[i].term), - NULL, 1, zapt->term->which, nmem, - kc, kc->scope, ol, index_type, + NULL, 1, zapt->term->which, nmem, + kc, kc->scope, ol, index_type, 0 /* hits_limit_value */, 0 /* term_ref_id_str */); - if (!rset) - rset = rset_t; - else - { - RSET rsets[2]; - - rsets[0] = rset; - rsets[1] = rset_t; - rset = rset_create_or(nmem, kc, kc->scope, 0 /* termid */, - 2, rsets); + if (!rset) + rset = rset_t; + else + { + RSET rsets[2]; + + rsets[0] = rset; + rsets[1] = rset_t; + rset = rset_create_or(nmem, kc, kc->scope, 0 /* termid */, + 2, rsets); + } } ar[i].isam_p = 0; } @@ -236,40 +221,54 @@ static int scan_save_set(ZebraHandle zh, ODR stream, NMEM nmem, RSET rsets[2]; rsets[0] = rset; rsets[1] = rset_dup(limit_set); - + rset = rset_create_and(nmem, kc, kc->scope, 2, rsets); } /* count it */ - count_set(zh, rset, &count, approx_limit); + zebra_count_set(zh, rset, &count, approx_limit); if (pos != -1) { zint sysno; - int code = -1; - zebra_snippets *rec_snippets = zebra_snippets_create(); zebra_snippets *hit_snippets = zebra_snippets_create(); glist[pos].term = 0; glist[pos].display_term = 0; - + get_first_snippet_from_rset(zh, rset, hit_snippets, &sysno); if (sysno) - code = zebra_get_rec_snippets(zh, sysno, rec_snippets); - - if (code == 0) { - const struct zebra_snippet_word *w = - zebra_snippets_lookup(rec_snippets, hit_snippets); - if (w) + zebra_snippets *rec_snippets = zebra_snippets_create(); + int code = zebra_get_rec_snippets(zh, sysno, rec_snippets); + if (code == 0) { - glist[pos].display_term = odr_strdup(stream, w->term); + const struct zebra_snippet_word *w = + zebra_snippets_lookup(rec_snippets, hit_snippets); + if (w) + { + glist[pos].display_term = odr_strdup(stream, w->term); + } + else + { + yaz_log(YLOG_WARN, "zebra_snippets_lookup failed for pos=%d", pos); + } } + zebra_snippets_destroy(rec_snippets); + } + if (zebra_term_untrans_iconv(zh, stream->mem, index_type, + &glist[pos].term, term)) + { + /* failed.. use display_term instead (which could be 0) */ + glist[pos].term = glist[pos].display_term; } + if (!glist[pos].term) - zebra_term_untrans_iconv(zh, stream->mem, index_type, - &glist[pos].term, term); + { + yaz_log(YLOG_WARN, "Could not generate scan term for pos=%d", + pos); + glist[pos].term = "None"; + } glist[pos].occurrences = count; - zebra_snippets_destroy(rec_snippets); zebra_snippets_destroy(hit_snippets); } rset_delete(rset); @@ -280,11 +279,11 @@ static int scan_save_set(ZebraHandle zh, ODR stream, NMEM nmem, } return 0; } - -static ZEBRA_RES rpn_scan_ver2(ZebraHandle zh, ODR stream, NMEM nmem, + +static ZEBRA_RES rpn_scan_norm(ZebraHandle zh, ODR stream, NMEM nmem, struct rset_key_control *kc, Z_AttributesPlusTerm *zapt, - int *position, int *num_entries, + int *position, int *num_entries, ZebraScanEntry **list, int *is_partial, RSET limit_set, const char *index_type, @@ -292,7 +291,7 @@ static ZEBRA_RES rpn_scan_ver2(ZebraHandle zh, ODR stream, NMEM nmem, { struct scan2_info_entry *ar = nmem_malloc(nmem, sizeof(*ar) * ord_no); struct rpn_char_map_info rcmi; - zebra_map_t zm = zebra_map_get(zh->reg->zebra_maps, index_type); + zebra_map_t zm = zebra_map_get_or_add(zh->reg->zebra_maps, index_type); int i, dif; int after_pos; int pos = 0; @@ -301,13 +300,6 @@ static ZEBRA_RES rpn_scan_ver2(ZebraHandle zh, ODR stream, NMEM nmem, odr_malloc(stream, *num_entries * sizeof(*glist)); *is_partial = 0; - if (*position > *num_entries+1) - { - *is_partial = 1; - *position = 1; - *num_entries = 0; - return ZEBRA_OK; - } rpn_char_map_prepare(zh->reg, zm, &rcmi); for (i = 0; i < ord_no; i++) @@ -317,12 +309,12 @@ static ZEBRA_RES rpn_scan_ver2(ZebraHandle zh, ODR stream, NMEM nmem, { char termz[IT_MAX_WORD+20]; int prefix_len = 0; - + prefix_len = key_SU_encode(ords[i], termz); termz[prefix_len] = 0; strcpy(ar[i].prefix, termz); - - if (trans_scan_term(zh, zapt, termz+prefix_len, zm) == + + if (trans_scan_term(zh, zapt, termz+prefix_len, zm) == ZEBRA_FAIL) { for (i = 0; i < ord_no; i++) @@ -360,7 +352,7 @@ static ZEBRA_RES rpn_scan_ver2(ZebraHandle zh, ODR stream, NMEM nmem, /* get maximum after scan */ for (i = 0; i < ord_no; i++) { - if (ar[i].isam_p + if (ar[i].isam_p && (hi == 0 || strcmp(wrbuf_cstr(ar[i].term), hi) > 0)) hi = wrbuf_cstr(ar[i].term); } @@ -377,9 +369,13 @@ static ZEBRA_RES rpn_scan_ver2(ZebraHandle zh, ODR stream, NMEM nmem, { /* did not get all terms; adjust the real position and reduce number of entries */ - yaz_log(YLOG_LOG, "before terms dif=%d", dif); - glist = glist + dif; - *num_entries -= dif; + if (dif < *num_entries) + { + glist = glist + dif; + *num_entries -= dif; + } + else + *num_entries = 0; *position -= dif; *is_partial = 1; } @@ -387,12 +383,12 @@ static ZEBRA_RES rpn_scan_ver2(ZebraHandle zh, ODR stream, NMEM nmem, { char termz[IT_MAX_WORD+20]; int prefix_len = 0; - + prefix_len = key_SU_encode(ords[i], termz); termz[prefix_len] = 0; strcpy(ar[i].prefix, termz); - - if (trans_scan_term(zh, zapt, termz+prefix_len, zm) == + + if (trans_scan_term(zh, zapt, termz+prefix_len, zm) == ZEBRA_FAIL) return ZEBRA_FAIL; wrbuf_rewind(ar[i].term); @@ -428,7 +424,7 @@ static ZEBRA_RES rpn_scan_ver2(ZebraHandle zh, ODR stream, NMEM nmem, /* get minimum after scan */ for (i = 0; i < ord_no; i++) { - if (ar[i].isam_p + if (ar[i].isam_p && (lo == 0 || strcmp(wrbuf_cstr(ar[i].term), lo) < 0)) lo = wrbuf_cstr(ar[i].term); } @@ -440,7 +436,7 @@ static ZEBRA_RES rpn_scan_ver2(ZebraHandle zh, ODR stream, NMEM nmem, pos++; } - if (pos != *num_entries) + if (pos < *num_entries) { if (pos >= 0) *num_entries = pos; @@ -473,7 +469,7 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, const Odr_oid *attributeset, int num_bases, char **basenames, int *position, int *num_entries, ZebraScanEntry **list, - int *is_partial, RSET limit_set) + int *is_partial, const char *set_name) { int base_no; int ords[RPN_MAX_ORDS], ord_no = 0; @@ -486,6 +482,7 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, NMEM nmem; ZEBRA_RES res; struct rset_key_control *kc = 0; + RSET limit_set = 0; *list = 0; *is_partial = 0; @@ -493,43 +490,44 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, if (!attributeset) attributeset = yaz_oid_attset_bib_1; - if (!limit_set) /* no limit set given already */ + if (!set_name) { /* see if there is a @attr 8=set */ AttrType termset; int termset_value_numeric; - const char *termset_value_string; + const char *termset_value_string = 0; attr_init_APT(&termset, zapt, 8); termset_value_numeric = attr_find_ex(&termset, NULL, &termset_value_string); if (termset_value_numeric != -1) { - char resname[32]; - const char *termset_name = 0; - if (termset_value_numeric != -2) { + char resname[32]; sprintf(resname, "%d", termset_value_numeric); - termset_name = resname; + set_name = odr_strdup(stream, resname); } else - termset_name = termset_value_string; - - limit_set = resultSetRef(zh, termset_name); + set_name = odr_strdup(stream, termset_value_string); + } + } - if (!limit_set) - { - zebra_setError(zh, - YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST, - termset_name); - return ZEBRA_FAIL; - } + if (set_name) + { + limit_set = resultSetRef(zh, set_name); + + if (!limit_set) + { + zebra_setError(zh, + YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST, + set_name); + return ZEBRA_FAIL; } } - + yaz_log(YLOG_DEBUG, "position = %d, num = %d", *position, *num_entries); - + if (zebra_maps_attr(zh->reg->zebra_maps, zapt, &index_type, &search_type, rank_type, &complete_flag, &sort_flag)) { @@ -542,7 +540,6 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, zebra_setError(zh, YAZ_BIB1_TOO_MANY_DATABASES_SPECIFIED, 0); return ZEBRA_FAIL; } - for (base_no = 0; base_no < num_bases; base_no++) { int ord; @@ -554,7 +551,7 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, *num_entries = 0; return ZEBRA_FAIL; } - if (zebra_apt_get_ord(zh, zapt, index_type, 0, attributeset, &ord) + if (zebra_apt_get_ord(zh, zapt, index_type, 0, attributeset, &ord) != ZEBRA_OK) continue; ords[ord_no++] = ord; @@ -572,9 +569,9 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, nmem = nmem_create(); kc = zebra_key_control_create(zh); - res = rpn_scan_ver2(zh, stream, nmem, kc, zapt, position, num_entries, - list, - is_partial, limit_set, index_type, ord_no, ords); + res = rpn_scan_norm(zh, stream, nmem, kc, zapt, position, num_entries, + list, is_partial, limit_set, + index_type, ord_no, ords); nmem_destroy(nmem); (*kc->dec)(kc); return res; @@ -583,6 +580,7 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab