X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=data1%2Fd1_absyn.c;h=216f60a410de2ce34427ab47bed9151256877692;hb=078a786204b5edef350982c385342f889d37e5ad;hp=3e26fc5e2a199a41782b4a7eb5489ac47f31d9e2;hpb=8b2a5cf09bb9c5cd5c0f780f63c40612366b8daa;p=idzebra-moved-to-github.git diff --git a/data1/d1_absyn.c b/data1/d1_absyn.c index 3e26fc5..216f60a 100644 --- a/data1/d1_absyn.c +++ b/data1/d1_absyn.c @@ -1,5 +1,5 @@ -/* $Id: d1_absyn.c,v 1.7 2003-02-25 21:50:27 adam Exp $ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 +/* $Id: d1_absyn.c,v 1.14 2004-09-30 18:31:14 adam Exp $ + Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 Index Data Aps This file is part of the Zebra server. @@ -27,11 +27,102 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include -#include +#include #include +#include #define D1_MAX_NESTING 128 +struct data1_hash_table { + NMEM nmem; + int size; + struct data1_hash_entry **ar; +}; + +struct data1_hash_entry { + void *clientData; + char *str; + struct data1_hash_entry *next; +}; + +unsigned data1_hash_calc(struct data1_hash_table *ht, const char *str) +{ + unsigned v = 0; + assert(str); + while (*str) + { + if (*str >= 'a' && *str <= 'z') + v = v*65509 + *str -'a'+10; + else if (*str >= 'A' && *str <= 'Z') + v = v*65509 + *str -'A'+10; + else if (*str >= '0' && *str <= '9') + v = v*65509 + *str -'0'; + str++; + } + return v % ht->size; +} + +struct data1_hash_table *data1_hash_open(int size, NMEM nmem) +{ + int i; + struct data1_hash_table *ht = nmem_malloc(nmem, sizeof(*ht)); + ht->nmem = nmem; + ht->size = size; + if (ht->size <= 0) + ht->size = 29; + ht->ar = nmem_malloc(nmem, sizeof(*ht->ar) * ht->size); + for (i = 0; isize; i++) + ht->ar[i] = 0; + return ht; +} + +void data1_hash_insert(struct data1_hash_table *ht, const char *str, + void *clientData, int copy) +{ + char *dstr = copy ? nmem_strdup(ht->nmem, str) : (char*) str; + if (strchr(str, '?') || strchr(str, '.')) + { + int i; + for (i = 0; isize; i++) + { + struct data1_hash_entry **he = &ht->ar[i]; + for (; *he && strcmp(str, (*he)->str); he = &(*he)->next) + ; + if (!*he) + { + *he = nmem_malloc(ht->nmem, sizeof(**he)); + (*he)->str = dstr; + (*he)->next = 0; + } + (*he)->clientData = clientData; + } + } + else + { + struct data1_hash_entry **he = &ht->ar[data1_hash_calc(ht, str)]; + for (; *he && strcmp(str, (*he)->str); he = &(*he)->next) + ; + if (!*he) + { + *he = nmem_malloc(ht->nmem, sizeof(**he)); + (*he)->str = dstr; + (*he)->next = 0; + } + (*he)->clientData = clientData; + } +} + +void *data1_hash_lookup(struct data1_hash_table *ht, const char *str) +{ + struct data1_hash_entry **he = &ht->ar[data1_hash_calc(ht, str)]; + + for (; *he && yaz_matchstr(str, (*he)->str); he = &(*he)->next) + ; + if (*he) + return (*he)->clientData; + return 0; +} + struct data1_systag { char *name; char *value; @@ -52,13 +143,25 @@ struct data1_attset_cache_info data1_attset_cache next; }; +data1_element *data1_mk_element(data1_handle dh) +{ + data1_element *e = nmem_malloc(data1_nmem_get(dh), sizeof(*e)); + e->name = 0; + e->tag = 0; + e->termlists = 0; + e->next = e->children = 0; + e->sub_name = 0; + e->hash = 0; + return e; +} + data1_absyn *data1_absyn_search (data1_handle dh, const char *name) { data1_absyn_cache p = *data1_absyn_cache_get (dh); while (p) { - if (!strcmp (name, p->name)) + if (!yaz_matchstr (name, p->name)) return p->absyn; p = p->next; } @@ -76,12 +179,15 @@ void data1_absyn_destroy (data1_handle dh) while (p) { data1_absyn *abs = p->absyn; - data1_xpelement *xpe = abs->xp_elements; - while (xpe) { - logf (LOG_DEBUG,"Destroy xp element %s",xpe->xpath_expr); - if (xpe->dfa) { dfa_delete (&xpe->dfa); } - xpe = xpe->next; - } + if (abs) + { + data1_xpelement *xpe = abs->xp_elements; + while (xpe) { + logf (LOG_DEBUG,"Destroy xp element %s",xpe->xpath_expr); + if (xpe->dfa) { dfa_delete (&xpe->dfa); } + xpe = xpe->next; + } + } p = p->next; } } @@ -130,7 +236,7 @@ data1_attset *data1_attset_search_name (data1_handle dh, const char *name) while (p) { - if (!strcmp (name, p->name)) + if (!yaz_matchstr (name, p->name)) return p->attset; p = p->next; } @@ -202,6 +308,11 @@ data1_esetname *data1_getesetbyname(data1_handle dh, data1_absyn *a, return 0; } +/* we have multiple versions of data1_getelementbyname */ +#define DATA1_GETELEMENTBYTAGNAME_VERSION 1 + +#if DATA1_GETELEMENTBYTAGNAME_VERSION==0 +/* straight linear search */ data1_element *data1_getelementbytagname (data1_handle dh, data1_absyn *abs, data1_element *parent, const char *tagname) @@ -227,6 +338,44 @@ data1_element *data1_getelementbytagname (data1_handle dh, data1_absyn *abs, } return 0; } +#endif + +#if DATA1_GETELEMENTBYTAGNAME_VERSION==1 +/* using hash search */ +data1_element *data1_getelementbytagname (data1_handle dh, data1_absyn *abs, + data1_element *parent, + const char *tagname) +{ + data1_element *r; + struct data1_hash_table *ht; + + /* It's now possible to have a data1 tree with no abstract syntax */ + if ( !abs ) + return 0; + + if (!parent) + r = abs->main_elements; + else + r = parent->children; + + if (!r) + return 0; + + ht = r->hash; + if (!ht) + { + ht = r->hash = data1_hash_open(29, data1_nmem_get(dh)); + for (; r; r = r->next) + { + data1_name *n; + + for (n = r->tag->names; n; n = n->next) + data1_hash_insert(ht, n->name, r, 0); + } + } + return data1_hash_lookup(ht, tagname); +} +#endif data1_element *data1_getelementbyname (data1_handle dh, data1_absyn *absyn, const char *name) @@ -359,28 +508,57 @@ const char * mk_xpath_regexp (data1_handle dh, char *expr) pop, 2002-12-13 */ static int parse_termlists (data1_handle dh, data1_termlist ***tpp, - char *p, const char *file, int lineno, + char *cp, const char *file, int lineno, const char *element_name, data1_absyn *res, int xpelement) { data1_termlist **tp = *tpp; - do + while(1) { char attname[512], structure[512]; char *source; - int r; - - if (!(r = sscanf(p, "%511[^:,]:%511[^,]", attname, - structure))) + int r, i; + int level = 0; + structure[0] = '\0'; + for (i = 0; cp[i] && inext = 0; if (!xpelement) { @@ -413,7 +591,7 @@ static int parse_termlists (data1_handle dh, data1_termlist ***tpp, nmem_strdup (data1_nmem_get (dh), structure); tp = &(*tp)->next; } - while ((p = strchr(p, ',')) && *(++p)); + *tpp = tp; return 0; } @@ -469,6 +647,16 @@ int read_absyn_line(FILE *f, int *lineno, char *line, int len, return argc; } +data1_marctab *data1_absyn_getmarctab(data1_handle dh, data1_absyn *absyn) +{ + return absyn->marc; +} + +YAZ_EXPORT data1_element *data1_absyn_getelements(data1_handle dh, + data1_absyn *absyn) +{ + return absyn->main_elements; +} data1_absyn *data1_read_absyn (data1_handle dh, const char *file, int file_must_exist) @@ -571,12 +759,7 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file, return 0; } level = i; - new_element = *ppl[level-1] = (data1_element *) - nmem_malloc(data1_nmem_get(dh), sizeof(*new_element)); - new_element->next = new_element->children = 0; - new_element->tag = 0; - new_element->termlists = 0; - new_element->sub_name = 0; + new_element = *ppl[level-1] = data1_mk_element(dh); tp = &new_element->termlists; ppl[level-1] = &new_element->next; @@ -701,10 +884,11 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file, cur_xpelement->dfa = dfa; #ifdef ENHANCED_XELM - cur_xpelement->xpath_len = parse_xpath_str(xpath_expr, - cur_xpelement->xpath, - data1_nmem_get(dh)); - + cur_xpelement->xpath_len = + zebra_parse_xpath_str(xpath_expr, + cur_xpelement->xpath, XPATH_STEP_COUNT, + data1_nmem_get(dh)); + /* dump_xp_steps(cur_xpelement->xpath,cur_xpelement->xpath_len); */ @@ -987,6 +1171,6 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file, fix_element_ref (dh, res, cur_elements->elements); } *systagsp = 0; - yaz_log (LOG_DEBUG, "%s: data1_read_absyn end", file); + yaz_log(LOG_DEBUG, "%s: data1_read_absyn end", file); return res; }