Fixed bug #447: Zebra aborts with "isamb: Inconsistent register".
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 9 Feb 2006 08:31:02 +0000 (08:31 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 9 Feb 2006 08:31:02 +0000 (08:31 +0000)
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
index/orddict.c
index/orddict.h
index/zebraapi.c
index/zinfo.c
index/zinfo.h
test/api/t14.c

index fbd37ac..3a6f8c2 100644 (file)
@@ -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 <fcntl.h>
 
 #include "index.h"
+#include "orddict.h"
 #include <direntz.h>
 #include <charmap.h>
 
@@ -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);
index ed4a05f..e93d04f 100644 (file)
@@ -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 <yaz/xmalloc.h>
+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 <assert.h>
+#include <yaz/wrbuf.h>
+#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;
+}
index 930a8d3..db9a455 100644 (file)
@@ -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 <yaz/yconfig.h>
 #include <idzebra/dict.h>
+#include <yaz/wrbuf.h>
 
 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
index 1d6e6ec..8207926 100644 (file)
@@ -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 <yaz/pquery.h>
 #include <yaz/sortspec.h>
 #include "index.h"
+#include "orddict.h"
 #include <charmap.h>
 #include <idzebra/api.h>
 
@@ -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
     {
index 69a3bad..740f7f0 100644 (file)
@@ -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);
index a1db67c..fe20b92 100644 (file)
@@ -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 {
index dd7618e..a98b175 100644 (file)
@@ -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);
 }