The rec_get function returns NULL if record doesn't exist - will
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 11 Dec 1995 09:12:44 +0000 (09:12 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 11 Dec 1995 09:12:44 +0000 (09:12 +0000)
happen in the server if the result set records have been deleted since
the creation of the set (i.e. the search).
The server saves a result temporarily if it is 'volatile', i.e. the
set is register dependent.

index/Makefile
index/extract.c
index/recindex.c
index/recindxp.h
index/zrpn.c
index/zserver.c

index 89286f6..8a45db2 100644 (file)
@@ -1,16 +1,16 @@
 # Copyright (C) 1995, Index Data I/S 
 # All rights reserved.
 # Sebastian Hammer, Adam Dickmeiss
-# $Id: Makefile,v 1.29 1995-12-07 17:38:45 adam Exp $
+# $Id: Makefile,v 1.30 1995-12-11 09:12:44 adam Exp $
 
 SHELL=/bin/sh
 RANLIB=ranlib
 
-YAZLIB=../../yaz/lib/libyaz.a
-#YAZLIB=-lyaz
-YAZINC=-I../../yaz/include
-OSILIB=../../xtimosi/src/libmosi.a ../../yaz/lib/librfc.a
-#OSILIB=../../xtimosi/src/libmosi.a -lrfc
+#YAZLIB=../../yaz/lib/libyaz.a
+YAZLIB=-lyaz
+#YAZINC=-I../../yaz/include
+#OSILIB=../../xtimosi/src/libmosi.a ../../yaz/lib/librfc.a
+OSILIB=../../xtimosi/src/libmosi.a -lrfc
 #NETLIB=-lnsl -lsocket
 
 INCLUDE=-I../include $(YAZINC)
index 8b189ca..5c1f738 100644 (file)
@@ -4,7 +4,14 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: extract.c,v $
- * Revision 1.42  1995-12-07 17:38:46  adam
+ * Revision 1.43  1995-12-11 09:12:46  adam
+ * The rec_get function returns NULL if record doesn't exist - will
+ * happen in the server if the result set records have been deleted since
+ * the creation of the set (i.e. the search).
+ * The server saves a result temporarily if it is 'volatile', i.e. the
+ * set is register dependent.
+ *
+ * Revision 1.42  1995/12/07  17:38:46  adam
  * Work locking mechanisms for concurrent updates/commit.
  *
  * Revision 1.41  1995/12/06  16:06:42  adam
@@ -177,6 +184,7 @@ void key_open (int mem)
 {
     if (mem < 50000)
         mem = 50000;
+    logf (LOG_LOG, "key_open %d", mem);
     key_buf = xmalloc (mem);
     ptr_top = mem/sizeof(char*);
     ptr_i = 0;
@@ -303,6 +311,7 @@ void key_flush (void)
 int key_close (void)
 {
     key_flush ();
+    logf (LOG_LOG, "buf free");
     xfree (key_buf);
     rec_close (&records);
     dict_close (matchDict);
@@ -785,7 +794,7 @@ static int recordExtract (SYSNO *sysno, const char *fname,
         struct recKeys delkeys;
 
         rec = rec_get (records, *sysno);
-
+        assert (rec);
         delkeys.buf_used = rec->size[recInfo_delKeys];
        delkeys.buf = rec->info[recInfo_delKeys];
         flushRecordKeys (*sysno, 0, &delkeys, rec->info[recInfo_databaseName]);
index 09cc708..44de12b 100644 (file)
@@ -4,7 +4,14 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: recindex.c,v $
- * Revision 1.12  1995-12-07 17:38:47  adam
+ * Revision 1.13  1995-12-11 09:12:49  adam
+ * The rec_get function returns NULL if record doesn't exist - will
+ * happen in the server if the result set records have been deleted since
+ * the creation of the set (i.e. the search).
+ * The server saves a result temporarily if it is 'volatile', i.e. the
+ * set is register dependent.
+ *
+ * Revision 1.12  1995/12/07  17:38:47  adam
  * Work locking mechanisms for concurrent updates/commit.
  *
  * Revision 1.11  1995/12/06  13:58:26  adam
@@ -118,8 +125,8 @@ static void rec_release_blocks (Records p, int sysno)
 
     if (read_indx (p, sysno, &entry, sizeof(entry), 1) != 1)
         return ;
-    p->head.total_bytes -= entry.u.used.size;
-    freeblock = entry.u.used.next;
+    p->head.total_bytes -= entry.size;
+    freeblock = entry.next;
     assert (freeblock > 0);
     dst_type = freeblock & 7;
     assert (dst_type < REC_BLOCK_TYPES);
@@ -150,7 +157,8 @@ static void rec_delete_single (Records p, Record rec)
 
     rec_release_blocks (p, rec->sysno);
 
-    entry.u.free.next = p->head.index_free;
+    entry.next = p->head.index_free;
+    entry.size = 0;
     p->head.index_free = rec->sysno;
     write_indx (p, rec->sysno, &entry, sizeof(entry));
 }
@@ -206,8 +214,8 @@ static void rec_write_single (Records p, Record rec)
             block_free = p->head.block_last[dst_type]++;
         if (block_prev == -1)
         {
-            entry.u.used.next = block_free*8 + dst_type;
-            entry.u.used.size = size;
+            entry.next = block_free*8 + dst_type;
+            entry.size = size;
             p->head.total_bytes += size;
             write_indx (p, rec->sysno, &entry, sizeof(entry));
         }
@@ -424,16 +432,20 @@ Record rec_get (Records p, int sysno)
     if ((recp = rec_cache_lookup (p, sysno, recordFlagNop)))
         return rec_cp (*recp);
 
-    read_indx (p, sysno, &entry, sizeof(entry), 0);
+    if (!read_indx (p, sysno, &entry, sizeof(entry), 1))
+        return NULL;       /* record is not there! */
+
+    if (!entry.size)
+        return NULL;       /* record is deleted */
 
-    dst_type = entry.u.used.next & 7;
+    dst_type = entry.next & 7;
     assert (dst_type < REC_BLOCK_TYPES);
-    freeblock = entry.u.used.next / 8;
+    freeblock = entry.next / 8;
 
     assert (freeblock > 0);
     
     rec = xmalloc (sizeof(*rec));
-    rec_tmp_expand (p, entry.u.used.size, dst_type);
+    rec_tmp_expand (p, entry.size, dst_type);
 
     cptr = p->tmp_buf;
     bf_read (p->data_BFile[dst_type], freeblock, 0, 0, cptr);
@@ -485,7 +497,7 @@ Record rec_new (Records p)
 
         read_indx (p, p->head.index_free, &entry, sizeof(entry), 0);
         sysno = p->head.index_free;
-        p->head.index_free = entry.u.free.next;
+        p->head.index_free = entry.next;
     }
     (p->head.no_records)++;
     rec->sysno = sysno;
index a0d9d4c..f821315 100644 (file)
@@ -4,7 +4,14 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: recindxp.h,v $
- * Revision 1.1  1995-12-06 12:41:25  adam
+ * Revision 1.2  1995-12-11 09:12:51  adam
+ * The rec_get function returns NULL if record doesn't exist - will
+ * happen in the server if the result set records have been deleted since
+ * the creation of the set (i.e. the search).
+ * The server saves a result temporarily if it is 'volatile', i.e. the
+ * set is register dependent.
+ *
+ * Revision 1.1  1995/12/06  12:41:25  adam
  * New command 'stat' for the index program.
  * Filenames can be read from stdin by specifying '-'.
  * Bug fix/enhancement of the transformation from terms to regular
@@ -62,6 +69,10 @@ struct record_cache_entry {
 };
 
 struct record_index_entry {
+#if 1
+    int next;         /* first block of record info / next free entry */
+    int size;         /* size of record or 0 if free entry */
+#else
     union {
         struct {
             int next;
@@ -71,5 +82,6 @@ struct record_index_entry {
             int next;
         } free;
     } u;
+#endif
 };
 
index a8ce682..a51d937 100644 (file)
@@ -4,7 +4,14 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: zrpn.c,v $
- * Revision 1.37  1995-12-06 15:05:28  adam
+ * Revision 1.38  1995-12-11 09:12:55  adam
+ * The rec_get function returns NULL if record doesn't exist - will
+ * happen in the server if the result set records have been deleted since
+ * the creation of the set (i.e. the search).
+ * The server saves a result temporarily if it is 'volatile', i.e. the
+ * set is register dependent.
+ *
+ * Revision 1.37  1995/12/06  15:05:28  adam
  * More verbose in count_set.
  *
  * Revision 1.36  1995/12/06  12:41:27  adam
@@ -1116,12 +1123,15 @@ static RSET rpn_search_structure (ZServerInfo *zi, Z_RPNStructure *zs,
     if (zs->which == Z_RPNStructure_complex)
     {
         rset_bool_parms bool_parms;
+        int soft = 0;
 
         bool_parms.rset_l = rpn_search_structure (zi, zs->u.complex->s1,
                                                   attributeSet,
                                                   num_bases, basenames);
         if (bool_parms.rset_l == NULL)
             return NULL;
+        if (rset_is_ranked(bool_parms.rset_l))
+            soft = 1;
         bool_parms.rset_r = rpn_search_structure (zi, zs->u.complex->s2,
                                                   attributeSet,
                                                   num_bases, basenames);
@@ -1130,19 +1140,21 @@ static RSET rpn_search_structure (ZServerInfo *zi, Z_RPNStructure *zs,
             rset_delete (bool_parms.rset_l);
             return NULL;
         }
+        if (rset_is_ranked(bool_parms.rset_r))
+            soft = 1;
         bool_parms.key_size = sizeof(struct it_key);
         bool_parms.cmp = key_compare;
 
         switch (zs->u.complex->operator->which)
         {
         case Z_Operator_and:
-            r = rset_create (rset_kind_and, &bool_parms);
+            r = rset_create (soft ? rset_kind_sand:rset_kind_and, &bool_parms);
             break;
         case Z_Operator_or:
-            r = rset_create (rset_kind_or, &bool_parms);
+            r = rset_create (soft ? rset_kind_sor:rset_kind_or, &bool_parms);
             break;
         case Z_Operator_and_not:
-            r = rset_create (rset_kind_not, &bool_parms);
+            r = rset_create (soft ? rset_kind_snot:rset_kind_not, &bool_parms);
             break;
         default:
             assert (0);
@@ -1173,6 +1185,38 @@ static RSET rpn_search_structure (ZServerInfo *zi, Z_RPNStructure *zs,
     return r;
 }
 
+void count_set_save (RSET *r, int *count)
+{
+    int psysno = 0;
+    int kno = 0;
+    struct it_key key;
+    RSFD rfd, wfd;
+    RSET w;
+    rset_temp_parms parms;
+
+    logf (LOG_DEBUG, "count_set_save");
+    *count = 0;
+    parms.key_size = sizeof(struct it_key);
+    w = rset_create (rset_kind_temp, &parms);
+    wfd = rset_open (w, RSETF_WRITE|RSETF_SORT_SYSNO);
+    rfd = rset_open (*r, RSETF_READ|RSETF_SORT_SYSNO);
+    while (rset_read (*r, rfd, &key))
+    {
+        if (key.sysno != psysno)
+        {
+            rset_write (w, wfd, &key);
+            psysno = key.sysno;
+            (*count)++;
+        }
+        kno++;
+    }
+    rset_close (*r, rfd);
+    rset_delete (*r);
+    rset_close (w, wfd);
+    *r = w;
+    logf (LOG_DEBUG, "%d keys, %d distinct sysnos", kno, *count);
+}
+
 static void count_set (RSET r, int *count)
 {
     int psysno = 0;
@@ -1180,7 +1224,7 @@ static void count_set (RSET r, int *count)
     struct it_key key;
     RSFD rfd;
 
-    logf (LOG_DEBUG, "rpn_save_set");
+    logf (LOG_DEBUG, "count_set");
     *count = 0;
     rfd = rset_open (r, RSETF_READ|RSETF_SORT_SYSNO);
     while (rset_read (r, rfd, &key))
@@ -1215,7 +1259,10 @@ int rpn_search (ZServerInfo *zi,
                                  num_bases, basenames);
     if (!rset)
         return zi->errCode;
-    count_set (rset, hits);
+    if (rset_is_volatile(rset))
+        count_set_save(&rset,hits);
+    else
+        count_set (rset, hits);
     resultSetAdd (zi, setname, 1, rset);
     if (zi->errCode)
         logf (LOG_DEBUG, "search error: %d", zi->errCode);
index 9013c55..f9f5823 100644 (file)
@@ -4,7 +4,14 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: zserver.c,v $
- * Revision 1.31  1995-12-08 16:22:56  adam
+ * Revision 1.32  1995-12-11 09:12:58  adam
+ * The rec_get function returns NULL if record doesn't exist - will
+ * happen in the server if the result set records have been deleted since
+ * the creation of the set (i.e. the search).
+ * The server saves a result temporarily if it is 'volatile', i.e. the
+ * set is register dependent.
+ *
+ * Revision 1.31  1995/12/08  16:22:56  adam
  * Work on update while servers are running. Three lock files introduced.
  * The servers reload their registers when necessary, but they don't
  * reestablish result sets yet.
@@ -168,8 +175,20 @@ static int register_lock (ZServerInfo *zi)
     return 0;
 }
 
-static int register_unlock (ZServerInfo *zi)
+static void register_unlock (ZServerInfo *zi)
 {
+    static int waitSec = -1;
+
+    if (waitSec == -1)
+    {
+        char *s = res_get (common_resource, "debugRequestWait");
+        if (s)
+            waitSec = atoi (s);
+        else
+            waitSec = 0;
+    }
+    if (waitSec > 0)
+        sleep (waitSec);
     if (zi->registerState != -1)
         zebraServerUnlock (zi->registerState);
 }
@@ -270,6 +289,14 @@ static int record_fetch (ZServerInfo *zi, int sysno, int score, ODR stream,
     char subType[128];
 
     rec = rec_get (zi->records, sysno);
+    if (!rec)
+    {
+        char *msg = "Record is deleted\n";
+        *output_format = VAL_SUTRS;
+        *rec_bufp = msg;
+        *rec_lenp = strlen (msg);
+        return 0;
+    }
     file_type = rec->info[recInfo_fileType];
     fname = rec->info[recInfo_filename];
 
@@ -292,7 +319,7 @@ static int record_fetch (ZServerInfo *zi, int sysno, int score, ODR stream,
     {
         if ((retrieveCtrl.fd = open (fname, O_RDONLY)) == -1)
         {
-            char *msg = "Record doesn't exist";
+            char *msg = "Record doesn't exist\n";
             logf (LOG_WARN|LOG_ERRNO, "Retrieve: Open record file %s", fname);
             *output_format = VAL_SUTRS;
             *rec_bufp = msg;