From 1d09966e51904c44ed82eaa920ffc9fbcc087541 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 9 Feb 2006 08:31:02 +0000 Subject: [PATCH] Fixed bug #447: Zebra aborts with "isamb: Inconsistent register". This fixes zebra_drop_database. We put a prefix in front of each dictionary entry in the matchDict and are then able to delete the whole subtree when database is dropped. --- index/extract.c | 33 ++++++++++++++++------ index/orddict.c | 83 +++++++++++++++++++++++++++++++++++++++--------------- index/orddict.h | 17 +++++------ index/zebraapi.c | 19 +++++++++---- index/zinfo.c | 9 +++++- index/zinfo.h | 3 +- test/api/t14.c | 11 ++------ 7 files changed, 121 insertions(+), 54 deletions(-) diff --git a/index/extract.c b/index/extract.c index fbd37ac..3a6f8c2 100644 --- a/index/extract.c +++ b/index/extract.c @@ -1,4 +1,4 @@ -/* $Id: extract.c,v 1.201 2006-02-08 13:45:44 adam Exp $ +/* $Id: extract.c,v 1.202 2006-02-09 08:31:02 adam Exp $ Copyright (C) 1995-2005 Index Data ApS @@ -32,6 +32,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include "index.h" +#include "orddict.h" #include #include @@ -492,7 +493,9 @@ static int file_extract_record(ZebraHandle zh, } if (matchStr) { - char *rinfo = dict_lookup (zh->reg->matchDict, matchStr); + int db_ord = zebraExplain_get_database_ord(zh->reg->zei); + char *rinfo = dict_lookup_ord(zh->reg->matchDict, db_ord, + matchStr); if (rinfo) { assert(*rinfo == sizeof(*sysno)); @@ -535,7 +538,9 @@ static int file_extract_record(ZebraHandle zh, if (matchStr) { - dict_insert (zh->reg->matchDict, matchStr, sizeof(*sysno), sysno); + int db_ord = zebraExplain_get_database_ord(zh->reg->zei); + dict_insert_ord(zh->reg->matchDict, db_ord, matchStr, + sizeof(*sysno), sysno); } #if NATTR extract_flushSortKeys (zh, *sysno, 1, zh->reg->sortKeys); @@ -597,7 +602,10 @@ static int file_extract_record(ZebraHandle zh, zh->m_record_type, fname, recordOffset); zh->records_deleted++; if (matchStr) - dict_delete (zh->reg->matchDict, matchStr); + { + int db_ord = zebraExplain_get_database_ord(zh->reg->zei); + dict_delete_ord(zh->reg->matchDict, db_ord, matchStr); + } rec_del (zh->reg->records, &rec); } rec_rm (&rec); @@ -966,8 +974,11 @@ ZEBRA_RES buffer_extract_record(ZebraHandle zh, } } } - if (matchStr) { - char *rinfo = dict_lookup (zh->reg->matchDict, matchStr); + if (matchStr) + { + int db_ord = zebraExplain_get_database_ord(zh->reg->zei); + char *rinfo = dict_lookup_ord(zh->reg->matchDict, db_ord, + matchStr); if (rinfo) { assert(*rinfo == sizeof(*sysno)); @@ -1005,8 +1016,9 @@ ZEBRA_RES buffer_extract_record(ZebraHandle zh, if (matchStr) { - dict_insert (zh->reg->matchDict, matchStr, - sizeof(*sysno), sysno); + int db_ord = zebraExplain_get_database_ord(zh->reg->zei); + dict_insert_ord(zh->reg->matchDict, db_ord, matchStr, + sizeof(*sysno), sysno); } #if NATTR extract_flushSortKeys (zh, *sysno, 1, zh->reg->sortKeys); @@ -1082,7 +1094,10 @@ ZEBRA_RES buffer_extract_record(ZebraHandle zh, pr_fname, (long) recordOffset); zh->records_deleted++; if (matchStr) - dict_delete (zh->reg->matchDict, matchStr); + { + int db_ord = zebraExplain_get_database_ord(zh->reg->zei); + dict_delete_ord(zh->reg->matchDict, db_ord, matchStr); + } rec_del (zh->reg->records, &rec); } rec_rm (&rec); diff --git a/index/orddict.c b/index/orddict.c index ed4a05f..e93d04f 100644 --- a/index/orddict.c +++ b/index/orddict.c @@ -1,35 +1,74 @@ +/* $Id: orddict.c,v 1.2 2006-02-09 08:31:02 adam Exp $ + Copyright (C) 1995-2005 + Index Data ApS -#include +This file is part of the Zebra server. -#include "orddict.h" +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 +Software Foundation; either version 2, or (at your option) any later +version. -struct zebra_ord_dict { - char *str; - size_t str_sz; - Dict dict; -}; +Zebra is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. -Zebra_ord_dict zebra_ord_dict_open(Dict dict) +You should have received a copy of the GNU General Public License +along with Zebra; see the file LICENSE.zebra. If not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. +*/ + +#include +#include +#include "index.h" + +WRBUF zebra_mk_ord_str(int ord, const char *str) +{ + char pref[20]; + WRBUF w = wrbuf_alloc(); + int len; + + assert(ord >= 0); + + len = key_SU_encode(ord, pref); + + wrbuf_write(w, pref, len); + wrbuf_puts(w, str); + return w; +} + +char *dict_lookup_ord(Dict d, int ord, const char *str) { - Zebra_ord_dict zod = xmalloc(sizeof(*zod)); - zod->str_sz = 50; - zod->str = xmalloc(zod->str_sz); - zod->dict = dict; - return zod; + WRBUF w = zebra_mk_ord_str(ord, str); + char *rinfo = dict_lookup(d, wrbuf_buf(w)); + wrbuf_free(w, 1); + return rinfo; } -void zebra_ord_dict_close(Zebra_ord_dict zod) +int dict_insert_ord(Dict d, int ord, const char *p, + int userlen, void *userinfo) { - if (!zod) - return; - dict_close(zod->dict); - xfree(zod->str); - xfree(zod); + WRBUF w = zebra_mk_ord_str(ord, p); + int r = dict_insert(d, wrbuf_buf(w), userlen, userinfo); + wrbuf_free(w, 1); + return r; } -char *zebra_ord_dict_lookup (Zebra_ord_dict zod, int ord, - const char *p) +int dict_delete_ord(Dict d, int ord, const char *p) { - return dict_lookup(zod->dict, p); + WRBUF w = zebra_mk_ord_str(ord, p); + int r = dict_delete(d, wrbuf_buf(w)); + wrbuf_free(w, 1); + return r; } +int dict_delete_subtree_ord(Dict d, int ord, void *client, + int (*f)(const char *info, void *client)) +{ + WRBUF w = zebra_mk_ord_str(ord, ""); + int r = dict_delete_subtree(d, wrbuf_buf(w), client, f); + wrbuf_free(w, 1); + return r; +} diff --git a/index/orddict.h b/index/orddict.h index 930a8d3..db9a455 100644 --- a/index/orddict.h +++ b/index/orddict.h @@ -1,4 +1,4 @@ -/* $Id: orddict.h,v 1.1 2006-01-19 13:31:08 adam Exp $ +/* $Id: orddict.h,v 1.2 2006-02-09 08:31:02 adam Exp $ Copyright (C) 1995-2005 Index Data ApS @@ -25,16 +25,17 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include +#include YAZ_BEGIN_CDECL - -typedef struct zebra_ord_dict *Zebra_ord_dict; - -Zebra_ord_dict zebra_ord_dict_open(Dict s); -void zebra_ord_dict_close(Zebra_ord_dict zod); -char *zebra_ord_dict_lookup (Zebra_ord_dict zod, int ord, - const char *p); +WRBUF zebra_mk_ord_str(int ord, const char *str); +char *dict_lookup_ord(Dict d, int ord, const char *str); +int dict_insert_ord(Dict dict, int ord, const char *p, + int userlen, void *userinfo); +int dict_delete_ord(Dict dict, int ord, const char *p); +int dict_delete_subtree_ord(Dict d, int ord, void *client, + int (*f)(const char *info, void *client)); YAZ_END_CDECL #endif diff --git a/index/zebraapi.c b/index/zebraapi.c index 1d6e6ec..8207926 100644 --- a/index/zebraapi.c +++ b/index/zebraapi.c @@ -1,4 +1,4 @@ -/* $Id: zebraapi.c,v 1.200 2006-01-19 13:30:02 adam Exp $ +/* $Id: zebraapi.c,v 1.201 2006-02-09 08:31:02 adam Exp $ Copyright (C) 1995-2005 Index Data ApS @@ -36,6 +36,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include "index.h" +#include "orddict.h" #include #include @@ -435,6 +436,7 @@ struct zebra_register *zebra_register_open(ZebraService zs, const char *name, yaz_log (YLOG_WARN, "Cannot obtain EXPLAIN information"); return 0; } + reg->active = 2; yaz_log (YLOG_DEBUG, "zebra_register_open ok p=%p", reg); return reg; @@ -1299,6 +1301,7 @@ ZEBRA_RES zebra_admin_exchange_record(ZebraHandle zh, SYSNO sysno = 0; char *rinfo = 0; char recid_z[256]; + int db_ord; ASSERTZH; assert(action>0 && action <=4); assert(rec_buf); @@ -1318,7 +1321,8 @@ ZEBRA_RES zebra_admin_exchange_record(ZebraHandle zh, if (zebra_begin_trans(zh, 1) == ZEBRA_FAIL) return ZEBRA_FAIL; - rinfo = dict_lookup (zh->reg->matchDict, recid_z); + db_ord = zebraExplain_get_database_ord(zh->reg->zei); + rinfo = dict_lookup_ord(zh->reg->matchDict, db_ord, recid_z); if (rinfo) { if (action == 1) /* fail if insert */ @@ -1359,11 +1363,12 @@ ZEBRA_RES zebra_admin_exchange_record(ZebraHandle zh, } if (action == 1) { - dict_insert (zh->reg->matchDict, recid_z, sizeof(sysno), &sysno); + dict_insert_ord(zh->reg->matchDict, db_ord, recid_z, + sizeof(sysno), &sysno); } else if (action == 3) { - dict_delete (zh->reg->matchDict, recid_z); + dict_delete_ord(zh->reg->matchDict, db_ord, recid_z); } zebra_end_trans(zh); return res; @@ -1410,8 +1415,11 @@ ZEBRA_RES zebra_drop_database(ZebraHandle zh, const char *db) return ZEBRA_FAIL; if (zh->reg->isamb) { + int db_ord; zebraExplain_curDatabase (zh->reg->zei, db); - + db_ord = zebraExplain_get_database_ord(zh->reg->zei); + dict_delete_subtree_ord(zh->reg->matchDict, db_ord, + 0 /* handle */, 0 /* func */); zebraExplain_trav_ord(zh->reg->zei, zh, delete_SU_handle); zebraExplain_removeDatabase(zh->reg->zei, zh); } @@ -1684,6 +1692,7 @@ ZEBRA_RES zebra_begin_trans(ZebraHandle zh, int rw) yaz_log(YLOG_FATAL, "%s", zh->errString); return ZEBRA_FAIL; } + zebraExplain_curDatabase(zh->reg->zei, zh->basenames[0]); } else { diff --git a/index/zinfo.c b/index/zinfo.c index 69a3bad..740f7f0 100644 --- a/index/zinfo.c +++ b/index/zinfo.c @@ -1,4 +1,4 @@ -/* $Id: zinfo.c,v 1.53 2005-12-13 13:47:35 adam Exp $ +/* $Id: zinfo.c,v 1.54 2006-02-09 08:31:02 adam Exp $ Copyright (C) 1995-2005 Index Data ApS @@ -1609,6 +1609,13 @@ static void att_loadset(void *p, const char *n, const char *name) yaz_log(YLOG_WARN, "Directive attset failed for %s", name); } +int zebraExplain_get_database_ord(ZebraExplainInfo zei) +{ + if (!zei->curDatabaseInfo) + return -1; + return zei->curDatabaseInfo->ordinalDatabase; +} + void zebraExplain_loadAttsets (data1_handle dh, Res res) { res_trav(res, "attset", dh, att_loadset); diff --git a/index/zinfo.h b/index/zinfo.h index a1db67c..fe20b92 100644 --- a/index/zinfo.h +++ b/index/zinfo.h @@ -1,4 +1,4 @@ -/* $Id: zinfo.h,v 1.27 2005-08-26 10:13:31 adam Exp $ +/* $Id: zinfo.h,v 1.28 2006-02-09 08:31:02 adam Exp $ Copyright (C) 1995-2005 Index Data ApS @@ -74,6 +74,7 @@ int zebraExplain_lookup_ord (ZebraExplainInfo zei, int ord, int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle, int (*f)(void *handle, int ord)); +int zebraExplain_get_database_ord(ZebraExplainInfo zei); int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *updateHandle); typedef struct { diff --git a/test/api/t14.c b/test/api/t14.c index dd7618e..a98b175 100644 --- a/test/api/t14.c +++ b/test/api/t14.c @@ -1,4 +1,4 @@ -/* $Id: t14.c,v 1.1 2005-12-15 13:28:46 adam Exp $ +/* $Id: t14.c,v 1.2 2006-02-09 08:31:02 adam Exp $ Copyright (C) 2004-2005 Index Data ApS @@ -31,15 +31,12 @@ static void create_search_drop(ZebraHandle zh) res = zebra_create_database (zh, "Default"); TL_ASSERT(res == ZEBRA_OK); -#if 0 - /* probably bug #447 .. but we don't know */ + /* bug #447 */ res = zebra_admin_exchange_record ( zh, rec, strlen(rec), opaque_id, strlen(opaque_id), 1); /* insert */ - - TL_ASSERT(res == ZEBRA_FAIL); -#endif + TL_ASSERT(res == ZEBRA_OK); res = zebra_admin_exchange_record ( zh, rec, strlen(rec), @@ -67,10 +64,8 @@ int main(int argc, char **argv) zebra_init(zh); create_search_drop(zh); -#if 0 /* bug #447 */ create_search_drop(zh); -#endif return close_down(zh, zs, 0); } -- 1.7.10.4