Revise resource API to take default/override resources.
[idzebra-moved-to-github.git] / index / kinput.c
index 9b7b8b2..a590587 100644 (file)
@@ -1,15 +1,26 @@
-/*
- * Copyright (C) 1994-2002, Index Data
- * All rights reserved.
- * Sebastian Hammer, Adam Dickmeiss, Heikki Levanto
- *
- * $Id: kinput.c,v 1.51 2002-07-12 18:12:22 heikki Exp $
- *
- * Bugs
- *  - Allocates a lot of memory for the merge process, but never releases it.
- *    Doesn't matter, as the program terminates soon after.  
- */
+/* $Id: kinput.c,v 1.56 2003-06-23 15:35:25 adam Exp $
+   Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
+   Index Data Aps
+
+This file is part of the Zebra server.
+
+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.
+
+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.
+
+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 <fcntl.h>
 #ifdef WIN32
@@ -263,7 +274,7 @@ struct heap_info *key_heap_init (int nkeys,
 void key_heap_destroy (struct heap_info *hi, int nkeys)
 {
     int i;
-    yaz_log (LOG_LOG, "key_heap_destroy");
+    yaz_log (LOG_DEBUG, "key_heap_destroy");
     for (i = 0; i<=nkeys; i++)
         xfree (hi->info.buf[i]);
     
@@ -347,26 +358,119 @@ static int heap_read_one (struct heap_info *hi, char *name, char *key)
     return 1;
 }
 
+#define PR_KEY 0
+
+#if PR_KEY
+static void pkey(const char *b, int mode)
+{
+    struct it_key *key = (struct it_key *) b;
+    printf ("%c %d:%d\n", mode + 48, key->sysno, key->seqno);
+}
+#endif
+
 struct heap_cread_info {
     char prev_name[INP_NAME_MAX];
     char cur_name[INP_NAME_MAX];
     char *key;
+    char *key_1, *key_2;
+    int mode_1, mode_2;
+    int sz_1, sz_2;
     struct heap_info *hi;
-    int mode;
+    int first_in_list;
     int more;
+    int ret;
 };
+
+static int heap_cread_item (void *vp, char **dst, int *insertMode);
+
+int heap_cread_item2 (void *vp, char **dst, int *insertMode)
+{
+    struct heap_cread_info *p = (struct heap_cread_info *) vp;
+    int level = 0;
+
+    if (p->ret == 0)    /* lookahead was 0?. Return that in read next round */
+    {
+        p->ret = -1;
+        return 0;
+    }
+    else if (p->ret == -1) /* Must read new item ? */
+    {
+        char *dst_1 = p->key_1;
+        p->ret = heap_cread_item(vp, &dst_1, &p->mode_1);
+        p->sz_1 = dst_1 - p->key_1;
+    }
+    else
+    {        /* lookahead in 2 . Now in 1. */
+        p->sz_1 = p->sz_2;
+        p->mode_1 = p->mode_2;
+        memcpy (p->key_1, p->key_2, p->sz_2);
+    }
+    if (p->mode_1)
+        level = 1;     /* insert */
+    else
+        level = -1;    /* delete */
+    while(1)
+    {
+        char *dst_2 = p->key_2;
+        p->ret = heap_cread_item(vp, &dst_2, &p->mode_2);
+        if (!p->ret)
+        {
+            if (level)
+                break;
+            p->ret = -1;
+            return 0;
+        }
+        p->sz_2 = dst_2 - p->key_2;
+        if (p->sz_1 == p->sz_2 && memcmp(p->key_1, p->key_2, p->sz_1) == 0)
+        {
+            if (p->mode_2) /* adjust level according to deletes/inserts */
+                level++;
+            else
+                level--;
+        }
+        else
+        {
+            if (level)
+                break;
+            /* all the same. new round .. */
+            p->sz_1 = p->sz_2;
+            p->mode_1 = p->mode_2;
+            memcpy (p->key_1, p->key_2, p->sz_1);
+            if (p->mode_1)
+                level = 1;     /* insert */
+            else
+                level = -1;    /* delete */
+        }
+    }
+    /* outcome is insert (1) or delete (0) depending on final level */
+    if (level > 0)
+        *insertMode = 1;
+    else
+        *insertMode = 0;
+    memcpy (*dst, p->key_1, p->sz_1);
+#if PR_KEY
+    printf ("top: ");
+    pkey(*dst, *insertMode); fflush(stdout);
+#endif
+    (*dst) += p->sz_1;
+    return 1;
+}
       
 int heap_cread_item (void *vp, char **dst, int *insertMode)
 {
     struct heap_cread_info *p = (struct heap_cread_info *) vp;
     struct heap_info *hi = p->hi;
 
-    if (p->mode == 1)
+    if (p->first_in_list)
     {
         *insertMode = p->key[0];
         memcpy (*dst, p->key+1, sizeof(struct it_key));
+#if PR_KEY
+        printf ("sub1: ");
+        pkey(*dst, *insertMode);
+#endif
         (*dst) += sizeof(struct it_key);
-        p->mode = 2;
+        p->first_in_list = 0;
         return 1;
     }
     strcpy (p->prev_name, p->cur_name);
@@ -374,11 +478,15 @@ int heap_cread_item (void *vp, char **dst, int *insertMode)
         return 0;
     if (*p->cur_name && strcmp (p->cur_name, p->prev_name))
     {
-        p->mode = 1;
+        p->first_in_list = 1;
         return 0;
     }
     *insertMode = p->key[0];
     memcpy (*dst, p->key+1, sizeof(struct it_key));
+#if PR_KEY
+    printf ("sub2: ");
+    pkey(*dst, *insertMode);
+#endif
     (*dst) += sizeof(struct it_key);
     return 1;
 }
@@ -386,15 +494,18 @@ int heap_cread_item (void *vp, char **dst, int *insertMode)
 int heap_inpc (struct heap_info *hi)
 {
     struct heap_cread_info hci;
-    ISAMC_I isamc_i = (ISAMC_I) xmalloc (sizeof(*isamc_i));
+    ISAMC_I *isamc_i = (ISAMC_I *) xmalloc (sizeof(*isamc_i));
 
     hci.key = (char *) xmalloc (KEY_SIZE);
-    hci.mode = 1;
+    hci.key_1 = (char *) xmalloc (KEY_SIZE);
+    hci.key_2 = (char *) xmalloc (KEY_SIZE);
+    hci.ret = -1;
+    hci.first_in_list = 1;
     hci.hi = hi;
     hci.more = heap_read_one (hi, hci.cur_name, hci.key);
 
     isamc_i->clientData = &hci;
-    isamc_i->read_item = heap_cread_item;
+    isamc_i->read_item = heap_cread_item2;
 
     while (hci.more)
     {
@@ -432,9 +543,12 @@ int heap_inpc (struct heap_info *hi)
     }
     xfree (isamc_i);
     xfree (hci.key);
+    xfree (hci.key_1);
+    xfree (hci.key_2);
     return 0;
 } 
 
+#if 0
 /* for debugging only */
 static void print_dict_item (ZebraMaps zm, const char *s)
 {
@@ -455,19 +569,23 @@ static void print_dict_item (ZebraMaps zm, const char *s)
     *to = '\0';
     yaz_log (LOG_LOG, "%s", keybuf);
 }
+#endif
 
 int heap_inpb (struct heap_info *hi)
 {
     struct heap_cread_info hci;
-    ISAMC_I isamc_i = (ISAMC_I) xmalloc (sizeof(*isamc_i));
+    ISAMC_I *isamc_i = (ISAMC_I *) xmalloc (sizeof(*isamc_i));
 
     hci.key = (char *) xmalloc (KEY_SIZE);
-    hci.mode = 1;
+    hci.key_1 = (char *) xmalloc (KEY_SIZE);
+    hci.key_2 = (char *) xmalloc (KEY_SIZE);
+    hci.ret = -1;
+    hci.first_in_list = 1;
     hci.hi = hi;
     hci.more = heap_read_one (hi, hci.cur_name, hci.key);
 
     isamc_i->clientData = &hci;
-    isamc_i->read_item = heap_cread_item;
+    isamc_i->read_item = heap_cread_item2;
 
     while (hci.more)
     {
@@ -509,6 +627,8 @@ int heap_inpb (struct heap_info *hi)
     }
     xfree (isamc_i);
     xfree (hci.key);
+    xfree (hci.key_1);
+    xfree (hci.key_2);
     return 0;
 } 
 
@@ -518,7 +638,10 @@ int heap_inpd (struct heap_info *hi)
     ISAMD_I isamd_i = (ISAMD_I) xmalloc (sizeof(*isamd_i));
 
     hci.key = (char *) xmalloc (KEY_SIZE);
-    hci.mode = 1;
+    hci.key_1 = (char *) xmalloc (KEY_SIZE);
+    hci.key_2 = (char *) xmalloc (KEY_SIZE);
+    hci.ret = -1;
+    hci.first_in_list = 1;
     hci.hi = hi;
     hci.more = heap_read_one (hi, hci.cur_name, hci.key);
 
@@ -584,6 +707,9 @@ int heap_inpd (struct heap_info *hi)
         }
     }
     xfree (isamd_i);
+    xfree (hci.key);
+    xfree (hci.key_1);
+    xfree (hci.key_2);
     return 0;
 } 
 
@@ -664,7 +790,10 @@ int heap_inps (struct heap_info *hi)
     ISAMS_I isams_i = (ISAMS_I) xmalloc (sizeof(*isams_i));
 
     hci.key = (char *) xmalloc (KEY_SIZE);
-    hci.mode = 1;
+    hci.key_1 = (char *) xmalloc (KEY_SIZE);
+    hci.key_2 = (char *) xmalloc (KEY_SIZE);
+    hci.first_in_list = 1;
+    hci.ret = -1;
     hci.hi = hi;
     hci.more = heap_read_one (hi, hci.cur_name, hci.key);