From 8707aaa9f358bc23e4d2adf4644f7e52c6440af8 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 5 Sep 2006 12:50:56 +0000 Subject: [PATCH] Changed behavior for dict_scan: if the callback function returns 0 the scan operation visits all terms in range (before to after); if the function returns non-zero the scan operation is cancelled. --- dict/scan.c | 99 +++++++++++++++++++++++++++--------------------- dict/scantest.c | 99 ++++++++++++++++++++++++++++++++++-------------- include/idzebra/dict.h | 9 +++-- 3 files changed, 133 insertions(+), 74 deletions(-) diff --git a/dict/scan.c b/dict/scan.c index 53ea999..1305182 100644 --- a/dict/scan.c +++ b/dict/scan.c @@ -1,4 +1,4 @@ -/* $Id: scan.c,v 1.23 2006-08-29 13:38:38 adam Exp $ +/* $Id: scan.c,v 1.24 2006-09-05 12:50:56 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -28,10 +28,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "dict-p.h" -int dict_scan_trav(Dict dict, Dict_ptr ptr, int pos, Dict_char *str, - int start, int *count, void *client, - int (*userfunc)(char *, const char *, int, void *), - int dir) +static void scan_direction(Dict dict, Dict_ptr ptr, int pos, Dict_char *str, + int start, int *count, void *client, + int (*userfunc)(char *, const char *, int, void *), + int dir) { int lo, hi, j; void *p; @@ -63,9 +63,13 @@ int dict_scan_trav(Dict dict, Dict_ptr ptr, int pos, Dict_char *str, for (j = 0; info[j] != DICT_EOS; j++) str[pos+j] = info[j]; str[pos+j] = DICT_EOS; - (*userfunc)((char*) str, info+(j+1)*sizeof(Dict_char), - *count * dir, client); - --(*count); + if ((*userfunc)((char*) str, info+(j+1)*sizeof(Dict_char), + *count * dir, client)) + { + *count = 0; + } + else + --(*count); } else { @@ -87,12 +91,15 @@ int dict_scan_trav(Dict dict, Dict_ptr ptr, int pos, Dict_char *str, if ((*userfunc)((char*) str, info+sizeof(Dict_ptr)+sizeof(Dict_char), *count * dir, client)) - return 1; - --(*count); + { + *count = 0; + } + else + --(*count); } if (*count>0 && subptr) { - dict_scan_trav (dict, subptr, pos+1, str, -1, count, + scan_direction (dict, subptr, pos+1, str, -1, count, client, userfunc, dir); dict_bf_readp (dict->dbf, ptr, &p); indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short)); @@ -103,16 +110,18 @@ int dict_scan_trav(Dict dict, Dict_ptr ptr, int pos, Dict_char *str, if ((*userfunc)((char*) str, info+sizeof(Dict_ptr)+sizeof(Dict_char), *count * dir, client)) - return 1; - --(*count); + { + *count = 0; + } + else + --(*count); } } lo += dir; } - return 0; } -int dict_scan_r (Dict dict, Dict_ptr ptr, int pos, Dict_char *str, +void dict_scan_r(Dict dict, Dict_ptr ptr, int pos, Dict_char *str, int *before, int *after, void *client, int (*userfunc)(char *, const char *, int, void *)) { @@ -123,7 +132,7 @@ int dict_scan_r (Dict dict, Dict_ptr ptr, int pos, Dict_char *str, dict_bf_readp (dict->dbf, ptr, &p); if (!p) - return 0; + return; mid = lo = 0; hi = DICT_nodir(p)-1; indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short)); @@ -141,11 +150,15 @@ int dict_scan_r (Dict dict, Dict_ptr ptr, int pos, Dict_char *str, { if (*after) { - (*userfunc)((char *) str, info+ - (dict_strlen((Dict_char*) info)+1) - *sizeof(Dict_char), - *after, client); - --(*after); + if ((*userfunc)((char *) str, info+ + (dict_strlen((Dict_char*) info)+1) + *sizeof(Dict_char), + *after, client)) + { + *after = 0; + } + else + --(*after); } break; } @@ -171,23 +184,25 @@ int dict_scan_r (Dict dict, Dict_ptr ptr, int pos, Dict_char *str, { if (*after) { - (*userfunc)((char*) str, - info+sizeof(Dict_ptr)+ - sizeof(Dict_char), - *after, client); - --(*after); + if ((*userfunc)((char*) str, + info+sizeof(Dict_ptr)+ + sizeof(Dict_char), + *after, client)) + { + *after = 0; + } + else + --(*after); } } if (*after && subptr) - if (dict_scan_trav(dict, subptr, pos+1, str, -1, - after, client, userfunc, 1)) - return 1; + scan_direction(dict, subptr, pos+1, str, -1, + after, client, userfunc, 1); } else if (subptr) { - if (dict_scan_r(dict, subptr, pos+1, str, before, after, - client, userfunc)) - return 1; + dict_scan_r(dict, subptr, pos+1, str, before, after, + client, userfunc); } break; } @@ -200,18 +215,15 @@ int dict_scan_r (Dict dict, Dict_ptr ptr, int pos, Dict_char *str, if (lo>hi && cmp < 0) ++mid; if (*after) - if (dict_scan_trav(dict, ptr, pos, str, cmp ? mid : mid+1, after, - client, userfunc, 1)) - return 1; + scan_direction(dict, ptr, pos, str, cmp ? mid : mid+1, after, + client, userfunc, 1); if (*before && mid > 0) - if (dict_scan_trav(dict, ptr, pos, str, mid-1, before, - client, userfunc, -1)) - return 1; - return 0; + scan_direction(dict, ptr, pos, str, mid-1, before, + client, userfunc, -1); } -int dict_scan (Dict dict, char *str, int *before, int *after, void *client, - int (*f)(char *name, const char *info, int pos, void *client)) +int dict_scan(Dict dict, char *str, int *before, int *after, void *client, + int (*f)(char *name, const char *info, int pos, void *client)) { int i; @@ -223,8 +235,9 @@ int dict_scan (Dict dict, char *str, int *before, int *after, void *client, } if (!dict->head.root) return 0; - return dict_scan_r(dict, dict->head.root, 0, (Dict_char *) str, - before, after, client, f); + dict_scan_r(dict, dict->head.root, 0, (Dict_char *) str, + before, after, client, f); + return 0; } /* * Local variables: diff --git a/dict/scantest.c b/dict/scantest.c index 706cb01..b49023d 100644 --- a/dict/scantest.c +++ b/dict/scantest.c @@ -1,4 +1,4 @@ -/* $Id: scantest.c,v 1.8 2006-08-29 13:39:48 adam Exp $ +/* $Id: scantest.c,v 1.9 2006-09-05 12:50:56 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -31,6 +31,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA struct handle_info { int b; int a; + int start_cut; + int end_cut; char **ar; }; @@ -46,18 +48,30 @@ static int handler(char *name, const char *info, int pos, void *client) yaz_log(YLOG_DEBUG, "pos=%d idx=%d name=%s", pos, idx, name); if (idx < 0) return 0; + if (idx < hi->start_cut || idx >= hi->end_cut) + { + return 1; + } hi->ar[idx] = malloc(strlen(name)+1); strcpy(hi->ar[idx], name); + return 0; } -int do_scan(Dict dict, int before, int after, char *scan_term, char **cmp_strs, - int verbose) +int do_scan(Dict dict, int before, int after, const char *sterm, + char **cmp_strs, + int verbose, int start_cut, int end_cut) { struct handle_info hi; + char scan_term[1024]; + int i; int errors = 0; + + strcpy(scan_term, sterm); + hi.start_cut = start_cut; + hi.end_cut = end_cut; hi.a = after; hi.b = before; hi.ar = malloc(sizeof(char*) * (after+before+1)); @@ -66,25 +80,55 @@ int do_scan(Dict dict, int before, int after, char *scan_term, char **cmp_strs, yaz_log(YLOG_DEBUG, "dict_scan before=%d after=%d term=%s", before, after, scan_term); dict_scan (dict, scan_term, &before, &after, &hi, handler); - for (i = 0; i= start_cut && i < end_cut) + { + if (!hi.ar[i]) + { + printf ("--> FAIL i=%d hi.ar[i] == NULL\n", i); + errors++; + } + } + else + { + if (hi.ar[i]) + { + printf ("--> FAIL i=%d hi.ar[i] = %s\n", i, hi.ar[i]); + errors++; + } + } + } + else { - if (!cmp_strs[i]) - { - printf ("--> FAIL cmp_strs == NULL\n"); - errors++; - } - else if (!hi.ar[i]) - { - printf ("--> FAIL strs == NULL\n"); - errors++; - } - else if (strcmp(cmp_strs[i], hi.ar[i])) - { - printf ("--> FAIL expected %s\n", cmp_strs[i]); - errors++; - } + if (i >= start_cut && i < end_cut) + { + if (!hi.ar[i]) + { + printf ("--> FAIL i=%d strs == NULL\n", i); + errors++; + } + else if (!cmp_strs[i]) + { + printf ("--> FAIL i=%d cmp_strs == NULL\n", i); + errors++; + } + else if (strcmp(cmp_strs[i], hi.ar[i])) + { + printf ("--> FAIL i=%d expected %s\n", i, cmp_strs[i]); + errors++; + } + } + else + { + if (hi.ar[i]) + { + printf ("--> FAIL i=%d hi.ar[i] != NULL\n", i); + errors++; + } + } } if (verbose || errors) { @@ -108,7 +152,6 @@ int do_scan(Dict dict, int before, int after, char *scan_term, char **cmp_strs, static void tst(Dict dict, int start, int number) { int i; - char scan_term[1024]; /* insert again with original value again */ for (i = start; i < number; i += 100) @@ -118,7 +161,7 @@ static void tst(Dict dict, int start, int number) sprintf(w, "%d", i); YAZ_CHECK_EQ(dict_insert(dict, w, sizeof(v), &v), 2); } - /* insert again with differnt value */ + /* insert again with different value */ for (i = start; i < number; i += 100) { int v = i-1; @@ -141,8 +184,7 @@ static void tst(Dict dict, int start, int number) "4498", "4499", "45"}; - strcpy(scan_term, "4499"); - YAZ_CHECK_EQ(do_scan(dict, 2, 2, scan_term, cs, 0), 0); + YAZ_CHECK_EQ(do_scan(dict, 2, 2, "4499", cs, 0, 0, 3), 0); } { char *cs[] = { @@ -150,10 +192,11 @@ static void tst(Dict dict, int start, int number) "4499", "45", "450"}; - strcpy(scan_term, "45"); - YAZ_CHECK_EQ(do_scan(dict, 2, 2, scan_term, cs, 0), 0); + YAZ_CHECK_EQ(do_scan(dict, 2, 2, "45", cs, 0, 0, 3), 0); } - + + for (i = 0; i < 20; i++) + YAZ_CHECK_EQ(do_scan(dict, 20, 20, "45", 0, 0, 20-i, 20+i), 0); } int main(int argc, char **argv) @@ -217,7 +260,7 @@ int main(int argc, char **argv) } if (after > 0 || before > 0) - do_scan(dict, before, after, scan_term, 0, 1); + do_scan(dict, before, after, scan_term, 0, 1, 0, after+1); else tst(dict, start, number); diff --git a/include/idzebra/dict.h b/include/idzebra/dict.h index 1e819d2..968afbf 100644 --- a/include/idzebra/dict.h +++ b/include/idzebra/dict.h @@ -1,4 +1,4 @@ -/* $Id: dict.h,v 1.10 2006-08-29 14:25:40 adam Exp $ +/* $Id: dict.h,v 1.11 2006-09-05 12:50:56 adam Exp $ Copyright (C) 1995-2006 Index Data ApS @@ -153,9 +153,12 @@ int dict_lookup_grep(Dict dict, const char *p, int range, void *client, \param after number of terms to be visited following str \param client client data pointer to be passed to match function f \param f function be called for each matching term - \retval 0 Operation complete. Function f returned zero value always - \retval 1 Operation incomplete. Function f returned a non-zero value + \retval 0 Successful \retval -1 error + + If the callback function f returns 0 the scan operation visits + all terms in range (before to after); if the function returns non-zero + the scan operation is cancelled. */ YAZ_EXPORT int dict_scan(Dict dict, char *str, -- 1.7.10.4