Towards GPL
[idzebra-moved-to-github.git] / isam / memory.c
index afb7887..800d74e 100644 (file)
@@ -1,38 +1,26 @@
-/*
- * Copyright (C) 1994, Index Data I/S 
- * All rights reserved.
- * Sebastian Hammer, Adam Dickmeiss
- *
- * $Log: memory.c,v $
- * Revision 1.9  1995-12-06 15:48:46  quinn
- * Fixed update-problem.
- *
- * Revision 1.8  1995/12/06  14:48:27  quinn
- * Fixed some strange bugs.
- *
- * Revision 1.7  1995/12/06  09:59:46  quinn
- * Fixed memory-consumption bug in memory.c
- * Added more blocksizes to the default ISAM configuration.
- *
- * Revision 1.6  1995/09/04  12:33:47  adam
- * Various cleanup. YAZ util used instead.
- *
- * Revision 1.5  1994/09/28  16:58:33  quinn
- * Small mod.
- *
- * Revision 1.4  1994/09/27  20:03:52  quinn
- * Seems relatively bug-free.
- *
- * Revision 1.3  1994/09/26  17:11:30  quinn
- * Trivial
- *
- * Revision 1.2  1994/09/26  17:06:35  quinn
- * Back again...
- *
- * Revision 1.1  1994/09/26  16:07:56  quinn
- * Most of the functionality in place.
- *
- */
+/* $Id: memory.c,v 1.18 2002-08-02 19:26:56 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.
+*/
+
+
 
 /*
  * This module accesses and rearranges the records of the tables.
 
 #include <assert.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
-#include <alexutil.h>
+#include <zebrautl.h>
 #include <isam.h>
 
 int is_mbuf_size[3] = { 0, 1024, 4096 };
@@ -58,7 +48,8 @@ is_mblock *xmalloc_mblock()
 
     if (!mblock_freelist)
     {
-       mblock_freelist = xmalloc(sizeof(is_mblock) * MALLOC_CHUNK);
+       mblock_freelist = (is_mblock *)
+           xmalloc(sizeof(is_mblock) * MALLOC_CHUNK);
        for (i = 0; i < MALLOC_CHUNK - 1; i++)
            mblock_freelist[i].next = &mblock_freelist[i+1];
        mblock_freelist[i].next = 0;
@@ -82,7 +73,7 @@ is_mbuf *xmalloc_mbuf(int type)
     }
     else
     {
-       tmp = xmalloc(sizeof(is_mbuf) + is_mbuf_size[type]);
+       tmp = (is_mbuf*) xmalloc(sizeof(is_mbuf) + is_mbuf_size[type]);
        tmp->type = type;
     }
     tmp->refcount = type ? 1 : 0;
@@ -148,6 +139,7 @@ void is_m_establish_tab(ISAM is, is_mtable *tab, ISAM_P pos)
        tab->data->data = 0;
        tab->cur_mblock = tab->data;
        tab->cur_mblock->cur_mbuf = 0;
+       tab->last_mbuf = 0;
     }
     else /* new block */
     {
@@ -160,6 +152,7 @@ void is_m_establish_tab(ISAM is, is_mtable *tab, ISAM_P pos)
        tab->cur_mblock = tab->data;
        tab->cur_mblock->cur_mbuf = tab->data->data;
        tab->cur_mblock->cur_mbuf->cur_record = 0;
+       tab->last_mbuf = 0;
     }
     tab->is = is;
 }
@@ -222,7 +215,7 @@ void is_m_replace_record(is_mtable *tab, const void *rec)
  */
 void is_m_delete_record(is_mtable *tab)
 {
-    is_mbuf *mbuf, *new;
+    is_mbuf *mbuf, *inew;
 
     mbuf = tab->cur_mblock->cur_mbuf;
     if (mbuf->cur_record >= mbuf->num)  /* top of mbuf */
@@ -230,18 +223,28 @@ void is_m_delete_record(is_mtable *tab)
        mbuf->num--;
        mbuf->cur_record--;
     }
-    else /* middle of a block */
+    else if (mbuf->cur_record == 1) /* beginning of mbuf */
+    {
+       mbuf->num--;
+       mbuf->offset +=is_keysize(tab->is);
+       mbuf->cur_record = 0;
+    }
+    else /* middle of mbuf */
     {
-       new = xmalloc_mbuf(IS_MBUF_TYPE_SMALL);
-       new->next = mbuf->next;
-       mbuf->next = new;
-       new->data = mbuf->data;
+       /* insert block after current one */
+       inew = xmalloc_mbuf(IS_MBUF_TYPE_SMALL);
+       inew->next = mbuf->next;
+       mbuf->next = inew;
+
+       /* virtually transfer everything after current record to new one. */
+       inew->data = mbuf->data;
        mbuf->refcount++;
-       new->offset = mbuf->offset + mbuf->cur_record * is_keysize(tab->is);
-       new->num = mbuf->num - mbuf->cur_record;
+       inew->offset = mbuf->offset + mbuf->cur_record * is_keysize(tab->is);
+       inew->num = mbuf->num - mbuf->cur_record;
+       
+       /* old buf now only contains stuff before current record */
        mbuf->num = mbuf->cur_record -1;
-       mbuf = mbuf->next;
-       mbuf->cur_record = 0;
+       tab->cur_mblock->cur_mbuf = inew;
     }
     tab->num_records--;
     tab->cur_mblock->num_records--;
@@ -285,7 +288,9 @@ int is_m_write_record(is_mtable *tab, const void *rec)
        mbuf = tab->cur_mblock->cur_mbuf = mbuf->next;
        mbuf->cur_record = 0;
     }
+    /*
     logf (LOG_DEBUG, "is_m_write_rec(rec == %d)", mbuf->cur_record);
+    */
     memcpy(mbuf->data + mbuf->offset + mbuf->cur_record * is_keysize(tab->is),
        rec, is_keysize(tab->is));
     mbuf->num++;
@@ -299,7 +304,10 @@ int is_m_write_record(is_mtable *tab, const void *rec)
 void is_m_unread_record(is_mtable *tab)
 {
     assert(tab->cur_mblock->cur_mbuf->cur_record);
-    tab->cur_mblock->cur_mbuf->cur_record--;
+    if (tab->last_mbuf)
+       tab->cur_mblock->cur_mbuf = tab->last_mbuf;
+    else
+       tab->cur_mblock->cur_mbuf->cur_record--;
 }
 
 /*
@@ -367,14 +375,20 @@ int is_m_read_record(is_mtable *tab, void *buf, int keep)
                    if (read_current_full(tab, tab->cur_mblock) < 0)
                        return -1;
                tab->cur_mblock->cur_mbuf = mbuf = tab->cur_mblock->data;
+               tab->last_mbuf = 0;
            }
            else
                return 0;   /* EOTable */
        }
        else
+       {
+           tab->last_mbuf = mbuf;
            tab->cur_mblock->cur_mbuf = mbuf = mbuf->next;
+       }
        mbuf->cur_record = 0;
     }
+    else
+       tab->last_mbuf = 0;
     memcpy(buf, mbuf->data + mbuf->offset + mbuf->cur_record *
        is_keysize(tab->is), is_keysize(tab->is));
     mbuf->cur_record++;
@@ -396,7 +410,7 @@ int is_m_seek_record(is_mtable *tab, const void *rec)
        if ((rs = (*tab->is->cmp)(peek, rec)) > 0)
        {
            is_m_unread_record(tab);
-           return 1;
+           return rs;
        }
        else if (rs == 0)
            return 0;