Work on bug #550: Avoid exit. In particular the mfile/cfile/bfile has
[idzebra-moved-to-github.git] / index / zebraapi.c
index a1673f7..0ff27a1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: zebraapi.c,v 1.224 2006-08-14 10:40:15 adam Exp $
+/* $Id: zebraapi.c,v 1.231 2006-11-14 08:12:08 adam Exp $
    Copyright (C) 1995-2006
    Index Data ApS
 
@@ -140,6 +140,7 @@ ZebraHandle zebra_open(ZebraService zs, Res res)
 
     zh->shadow_enable = 1;
     zh->m_staticrank = 0;
+    zh->m_segment_indexing = 0;
 
     default_encoding = res_get_def(zh->session_res, "encoding", "ISO-8859-1");
 
@@ -767,6 +768,15 @@ static void zebra_select_register (ZebraHandle zh, const char *new_reg)
        if (res_get_int(zh->res, "staticrank", &zh->m_staticrank) == ZEBRA_OK)
            yaz_log(YLOG_LOG, "static rank set and is %d", zh->m_staticrank);
     }
+    if (zh->res)
+    {
+       if (res_get_int(zh->res, "segment", &zh->m_segment_indexing) == 
+            ZEBRA_OK)
+        {
+           yaz_log(YLOG_DEBUG, "segment indexing set and is %d",
+                    zh->m_segment_indexing);
+        }
+    }
 }
 
 void map_basenames_func (void *vp, const char *name, const char *value)
@@ -1167,10 +1177,10 @@ ZEBRA_RES zebra_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
            return ZEBRA_FAIL;
        }
     }
-    res = rpn_scan (zh, stream, zapt, attributeset,
-                   zh->num_basenames, zh->basenames, position,
-                   num_entries, entries, is_partial, limit_rset, 0);
-    zebra_end_read (zh);
+    res = rpn_scan(zh, stream, zapt, attributeset,
+                   zh->num_basenames, zh->basenames, position,
+                   num_entries, entries, is_partial, limit_rset);
+    zebra_end_read(zh);
     return res;
 }
 
@@ -1475,12 +1485,20 @@ ZEBRA_RES zebra_drop_database(ZebraHandle zh, const char *db)
     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);
+       if (zebraExplain_curDatabase (zh->reg->zei, db))
+        {
+            zebra_setError(zh, YAZ_BIB1_DATABASE_DOES_NOT_EXIST, db);
+            ret = ZEBRA_FAIL;
+        }
+        else
+        {
+            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);
+            zebra_remove_file_match(zh);
+        }
     }
     else
     {
@@ -1546,6 +1564,16 @@ int zebra_string_norm (ZebraHandle zh, unsigned reg_id,
     return wrbuf_len(wrbuf);
 }
 
+/** \brief set register state (state*.LCK)
+    \param zh Zebra handle
+    \param val state
+    \param seqno sequence number
+    
+    val is one of:
+    d=writing to shadow(dirty)
+    o=no writing, 
+    c=commit
+*/
 static void zebra_set_state (ZebraHandle zh, int val, int seqno)
 {
     char state_fname[256];
@@ -1655,7 +1683,6 @@ ZEBRA_RES zebra_begin_trans(ZebraHandle zh, int rw)
     assert (zh->res);
     if (rw)
     {
-        int pass;
         int seqno = 0;
         char val = '?';
         const char *rval = 0;
@@ -1691,51 +1718,40 @@ ZEBRA_RES zebra_begin_trans(ZebraHandle zh, int rw)
         if (zh->shadow_enable)
             rval = res_get (zh->res, "shadow");
         
-        for (pass = 0; pass < 2; pass++)
+        if (rval)
         {
-            if (rval)
-            {
-                zebra_lock_r (zh->lock_normal);
-                zebra_lock_w (zh->lock_shadow);
-            }
-            else
+            zebra_lock_r(zh->lock_normal);
+            zebra_lock_w(zh->lock_shadow);
+        }
+        else
+        {
+            zebra_lock_w(zh->lock_normal);
+            zebra_lock_w(zh->lock_shadow);
+        }
+        zebra_get_state (zh, &val, &seqno);
+        if (val != 'o')
+        {
+            /* either we didn't finish commit or shadow is dirty */
+            zebra_unlock (zh->lock_shadow);
+            zebra_unlock (zh->lock_normal);
+            if (zebra_commit (zh))
             {
-                zebra_lock_w (zh->lock_normal);
-                zebra_lock_w (zh->lock_shadow);
+                zh->trans_no--;
+                zh->trans_w_no = 0;
+                return ZEBRA_FAIL;
             }
-            
-            zebra_get_state (zh, &val, &seqno);
-            if (val == 'c')
+            if (rval)
             {
-                yaz_log (YLOG_WARN, "previous transaction didn't finish commit");
-                zebra_unlock (zh->lock_shadow);
-                zebra_unlock (zh->lock_normal);
-                zebra_commit (zh);
-                continue;
+                zebra_lock_r(zh->lock_normal);
+                zebra_lock_w(zh->lock_shadow);
             }
-            else if (val == 'd')
+            else
             {
-                if (rval)
-                {
-                    BFiles bfs = bfs_create (res_get (zh->res, "shadow"),
-                                             zh->path_reg);
-                    yaz_log (YLOG_WARN, "previous transaction didn't reach commit");
-                    bf_commitClean (bfs, rval);
-                    bfs_destroy (bfs);
-               }
-                else
-                {
-                    yaz_log (YLOG_WARN, "your previous transaction didn't finish");
-                }
+                zebra_lock_w(zh->lock_normal);
+                zebra_lock_w(zh->lock_shadow);
             }
-            break;
-        }
-        if (pass == 2)
-        {
-            yaz_log (YLOG_FATAL, "zebra_begin_trans couldn't finish commit");
-            abort();
-            return ZEBRA_FAIL;
         }
+
         zebra_set_state (zh, 'd', seqno);
         
         zh->reg = zebra_register_open(zh->service, zh->reg_name,
@@ -1970,6 +1986,8 @@ static ZEBRA_RES zebra_commit_ex(ZebraHandle zh, int clean_only)
     char val;
     const char *rval;
     BFiles bfs;
+    ZEBRA_RES res = ZEBRA_OK;
+
     ASSERTZH;
 
     zebra_select_default_database(zh);
@@ -1978,60 +1996,73 @@ static ZEBRA_RES zebra_commit_ex(ZebraHandle zh, int clean_only)
         zh->errCode = YAZ_BIB1_DATABASE_UNAVAILABLE;
         return ZEBRA_FAIL;
     }
-    rval = res_get (zh->res, "shadow");    
+    rval = res_get(zh->res, "shadow");    
     if (!rval)
     {
         yaz_log (YLOG_WARN, "Cannot perform commit - No shadow area defined");
         return ZEBRA_OK;
     }
 
-    zebra_lock_w (zh->lock_normal);
-    zebra_lock_r (zh->lock_shadow);
+    zebra_lock_w(zh->lock_normal);
+    zebra_lock_r(zh->lock_shadow);
 
-    bfs = bfs_create (res_get (zh->res, "register"), zh->path_reg);
+    bfs = bfs_create(res_get (zh->res, "register"), zh->path_reg);
     if (!bfs)
     {
        zebra_unlock(zh->lock_shadow);
        zebra_unlock(zh->lock_normal);
         return ZEBRA_FAIL;
     }
-    zebra_get_state (zh, &val, &seqno);
+    zebra_get_state(zh, &val, &seqno);
+
+    if (val == 'd')
+    {
+        yaz_log(YLOG_WARN, "previous transaction didn't reach commit");
+        clean_only = 1;
+    }
 
     if (rval && *rval)
         bf_cache (bfs, rval);
     if (bf_commitExists (bfs))
     {
         if (clean_only)
-            zebra_set_state (zh, 'd', seqno);
+            zebra_set_state(zh, 'd', seqno);
         else
         {
-            zebra_set_state (zh, 'c', seqno);
+            zebra_set_state(zh, 'c', seqno);
             
-            yaz_log (YLOG_DEBUG, "commit start");
-            bf_commitExec (bfs);
-#ifndef WIN32
-            sync ();
-#endif
+            yaz_log(YLOG_DEBUG, "commit start");
+            if (bf_commitExec (bfs))
+                res = ZEBRA_FAIL;
+        }
+        if (res == ZEBRA_OK)
+        {
+            seqno++;
+            zebra_set_state(zh, 'o', seqno);
+            
+            zebra_unlock(zh->lock_shadow);
+            zebra_unlock(zh->lock_normal);
+            
+            zebra_lock_w(zh->lock_shadow);
+            bf_commitClean(bfs, rval);
+            zebra_unlock(zh->lock_shadow);
+        }
+        else
+        {
+            zebra_unlock(zh->lock_shadow);
+            zebra_unlock(zh->lock_normal);
+            yaz_log(YLOG_WARN, "zebra_commit: failed");
         }
-        seqno++;
-        zebra_set_state (zh, 'o', seqno);
-
-       zebra_unlock (zh->lock_shadow);
-       zebra_unlock (zh->lock_normal);
-
-       zebra_lock_w(zh->lock_shadow);
-        bf_commitClean (bfs, rval);
-       zebra_unlock (zh->lock_shadow);
     }
     else
     {
        zebra_unlock(zh->lock_shadow);
        zebra_unlock(zh->lock_normal);
-        yaz_log (log_level, "nothing to commit");
+        yaz_log(log_level, "nothing to commit");
     }
-    bfs_destroy (bfs);
+    bfs_destroy(bfs);
 
-    return ZEBRA_OK;
+    return res;
 }
 
 ZEBRA_RES zebra_clean(ZebraHandle zh)