Work on bug #550: Avoid exit. In particular the mfile/cfile/bfile has
[idzebra-moved-to-github.git] / isamb / isamb.c
index 327993c..8e464ba 100644 (file)
@@ -1,6 +1,6 @@
-/* $Id: isamb.c,v 1.68 2005-01-15 18:53:46 adam Exp $
-   Copyright (C) 1995-2005
-   Index Data Aps
+/* $Id: isamb.c,v 1.85 2006-11-14 08:12:08 adam Exp $
+   Copyright (C) 1995-2006
+   Index Data ApS
 
 This file is part of the Zebra server.
 
@@ -15,11 +15,12 @@ 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.
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
 */
 
+#include <stdlib.h>
 #include <string.h>
 #include <yaz/log.h>
 #include <yaz/xmalloc.h>
@@ -71,7 +72,7 @@ struct ISAMB_head {
 #define ISAMB_PTR_CODEC 1
 
 struct ISAMB_cache_entry {
-    ISAMB_P pos;
+    ISAM_P pos;
     unsigned char *buf;
     int dirty;
     int hits;
@@ -101,7 +102,7 @@ struct ISAMB_s {
 };
 
 struct ISAMB_block {
-    ISAMB_P pos;
+    ISAM_P pos;
     int cat;
     int size;
     int leaf;
@@ -118,7 +119,7 @@ struct ISAMB_block {
 
 struct ISAMB_PP_s {
     ISAMB isamb;
-    ISAMB_P pos;
+    ISAM_P pos;
     int level;
     int maxlevel; /* total depth */
     zint total_size;
@@ -140,10 +141,10 @@ static void encode_ptr(char **dst, zint pos)
 
     while (pos > 127)
     {
-         *bp++ = 128 | (pos & 127);
+         *bp++ = (unsigned char) (128 | (pos & 127));
          pos = pos >> 7;
     }
-    *bp++ = pos;
+    *bp++ = (unsigned char) pos;
     *dst = (char *) bp;
 }
 #else
@@ -156,14 +157,13 @@ static void encode_ptr(char **dst, zint pos)
 
 #define decode_item_len decode_ptr
 #if ISAMB_PTR_CODEC
-static void decode_ptr(const char **src1, zint *pos)
+static void decode_ptr(const char **src, zint *pos)
 {
-    const unsigned char **src = (const unsigned char **) src1;
     zint d = 0;
     unsigned char c;
     unsigned r = 0;
 
-    while (((c = *(*src)++) & 128))
+    while (((c = *(const unsigned char *)((*src)++)) & 128))
     {
         d += ((zint) (c & 127) << r);
        r += 7;
@@ -180,31 +180,38 @@ static void decode_ptr(const char **src, zint *pos)
 #endif
 
 ISAMB isamb_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method,
-                  int cache)
+                int cache)
 {
     ISAMB isamb = xmalloc(sizeof(*isamb));
     int i, b_size = ISAMB_MIN_SIZE;
 
     isamb->bfs = bfs;
     isamb->method = (ISAMC_M *) xmalloc(sizeof(*method));
-    memcpy (isamb->method, method, sizeof(*method));
+    memcpy(isamb->method, method, sizeof(*method));
     isamb->no_cat = CAT_NO;
     isamb->log_io = 0;
     isamb->log_freelist = 0;
     isamb->cache = cache;
     isamb->skipped_numbers = 0;
     isamb->returned_numbers = 0;
-    for (i = 0;i<ISAMB_MAX_LEVEL;i++)
-      isamb->skipped_nodes[i]= isamb->accessed_nodes[i]=0;
+    for (i = 0; i<ISAMB_MAX_LEVEL; i++)
+       isamb->skipped_nodes[i] = isamb->accessed_nodes[i] = 0;
 
     assert(cache == 0);
     isamb->file = xmalloc(sizeof(*isamb->file) * isamb->no_cat);
+
+    for (i = 0; i < isamb->no_cat; i++)
+    {
+        isamb->file[i].bf = 0;
+        isamb->file[i].head_dirty = 0;
+        isamb->file[i].cache_entries = 0;
+    }
+
     for (i = 0; i < isamb->no_cat; i++)
     {
         char fname[DST_BUF_SIZE];
        char hbuf[DST_BUF_SIZE];
-        isamb->file[i].cache_entries = 0;
-        isamb->file[i].head_dirty = 0;
+
         sprintf(fname, "%s%c", name, i+'A');
         if (cache)
             isamb->file[i].bf = bf_open(bfs, fname, ISAMB_CACHE_ENTRY_SIZE,
@@ -212,6 +219,12 @@ ISAMB isamb_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method,
         else
             isamb->file[i].bf = bf_open(bfs, fname, b_size, writeflag);
 
+        if (!isamb->file[i].bf)
+        {
+            isamb_close(isamb);
+            return 0;
+        }
+
         /* fill-in default values (for empty isamb) */
        isamb->file[i].head.first_block = ISAMB_CACHE_ENTRY_SIZE/b_size+1;
        isamb->file[i].head.last_block = isamb->file[i].head.first_block;
@@ -265,9 +278,9 @@ ISAMB isamb_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method,
            decode_ptr(&src, &isamb->file[i].head.first_block);
            decode_ptr(&src, &isamb->file[i].head.last_block);
            decode_ptr(&src, &zint_tmp);
-           isamb->file[i].head.block_size = zint_tmp;
+           isamb->file[i].head.block_size = (int) zint_tmp;
            decode_ptr(&src, &zint_tmp);
-           isamb->file[i].head.block_max = zint_tmp;
+           isamb->file[i].head.block_max = (int) zint_tmp;
            decode_ptr(&src, &isamb->file[i].head.free_list);
        }
         assert (isamb->file[i].head.block_size >= isamb->file[i].head.block_offset);
@@ -298,7 +311,7 @@ static void flush_blocks (ISAMB b, int cat)
     }
 }
 
-static int get_block (ISAMB b, ISAMC_P pos, char *userbuf, int wr)
+static int cache_block (ISAMB b, ISAM_P pos, unsigned char *userbuf, int wr)
 {
     int cat = (int) (pos&CAT_MASK);
     int off = (int) (((pos/CAT_MAX) & 
@@ -343,7 +356,7 @@ static int get_block (ISAMB b, ISAMC_P pos, char *userbuf, int wr)
         *ce_last = 0;  /* remove the last entry from list */
         if (ce_this->dirty)
         {
-            yaz_log(b->log_io, "bf_write: get_block");
+            yaz_log(b->log_io, "bf_write: cache_block");
             bf_write(b->file[cat].bf, ce_this->pos, 0, 0, ce_this->buf);
         }
         xfree(ce_this->buf);
@@ -354,7 +367,7 @@ static int get_block (ISAMB b, ISAMC_P pos, char *userbuf, int wr)
     b->file[cat].cache_entries = ce_this;
     ce_this->buf = xmalloc(ISAMB_CACHE_ENTRY_SIZE);
     ce_this->pos = norm;
-    yaz_log(b->log_io, "bf_read: get_block");
+    yaz_log(b->log_io, "bf_read: cache_block");
     if (!bf_read(b->file[cat].bf, norm, 0, 0, ce_this->buf))
         memset (ce_this->buf, 0, ISAMB_CACHE_ENTRY_SIZE);
     if (wr)
@@ -374,7 +387,7 @@ static int get_block (ISAMB b, ISAMC_P pos, char *userbuf, int wr)
 void isamb_close (ISAMB isamb)
 {
     int i;
-    for (i = 0;isamb->accessed_nodes[i];i++)
+    for (i = 0; isamb->accessed_nodes[i]; i++)
         yaz_log(YLOG_DEBUG, "isamb_close  level leaf-%d: "ZINT_FORMAT" read, "
                        ZINT_FORMAT" skipped",
              i, isamb->accessed_nodes[i], isamb->skipped_nodes[i]);
@@ -414,7 +427,8 @@ void isamb_close (ISAMB isamb)
                bf_write(isamb->file[i].bf, pos, 0, 0, hbuf + pos*b_size);
            }
        }
-        bf_close (isamb->file[i].bf);
+        if (isamb->file[i].bf)
+            bf_close (isamb->file[i].bf);
     }
     xfree(isamb->file);
     xfree(isamb->method);
@@ -431,7 +445,7 @@ void isamb_close (ISAMB isamb)
    * Reserve 5 bytes for large block sizes. 1 for small ones .. Number
    of items. We can thus have at most 2^40 nodes. 
 */
-static struct ISAMB_block *open_block(ISAMB b, ISAMC_P pos)
+static struct ISAMB_block *open_block(ISAMB b, ISAM_P pos)
 {
     int cat = (int) (pos&CAT_MASK);
     const char *src;
@@ -445,7 +459,7 @@ static struct ISAMB_block *open_block(ISAMB b, ISAMC_P pos)
     p->buf = xmalloc(b->file[cat].head.block_size);
     p->cbuf = 0;
 
-    if (!get_block (b, pos, p->buf, 0))
+    if (!cache_block (b, pos, p->buf, 0))
     {
         yaz_log(b->log_io, "bf_read: open_block");
         if (!bf_read(b->file[cat].bf, pos/CAT_MAX, 0, 0, p->buf))
@@ -455,7 +469,7 @@ static struct ISAMB_block *open_block(ISAMB b, ISAMC_P pos)
             abort();
         }
     }
-    p->bytes = p->buf + offset;
+    p->bytes = (char *)p->buf + offset;
     p->leaf = p->buf[0];
     p->size = (p->buf[1] + 256 * p->buf[2]) - offset;
     if (p->size < 0)
@@ -464,7 +478,7 @@ static struct ISAMB_block *open_block(ISAMB b, ISAMC_P pos)
                 p->size, pos);
     }
     assert (p->size >= 0);
-    src = p->buf + 3;
+    src = (char*) p->buf + 3;
     decode_ptr(&src, &p->no_items);
 
     p->offset = 0;
@@ -491,7 +505,7 @@ struct ISAMB_block *new_block (ISAMB b, int leaf, int cat)
     {
         p->pos = b->file[cat].head.free_list;
         assert((p->pos & CAT_MASK) == cat);
-        if (!get_block (b, p->pos, p->buf, 0))
+        if (!cache_block (b, p->pos, p->buf, 0))
         {
             yaz_log(b->log_io, "bf_read: new_block");
             if (!bf_read(b->file[cat].bf, p->pos/CAT_MAX, 0, 0, p->buf))
@@ -508,7 +522,7 @@ struct ISAMB_block *new_block (ISAMB b, int leaf, int cat)
     p->cat = cat;
     b->file[cat].head_dirty = 1;
     memset (p->buf, 0, b->file[cat].head.block_size);
-    p->bytes = p->buf + b->file[cat].head.block_offset;
+    p->bytes = (char*)p->buf + b->file[cat].head.block_offset;
     p->leaf = leaf;
     p->size = 0;
     p->dirty = 1;
@@ -543,7 +557,7 @@ static void check_block (ISAMB b, struct ISAMB_block *p)
         char *startp = p->bytes;
         const char *src = startp;
         char *endp = p->bytes + p->size;
-        ISAMB_P pos;
+        ISAM_P pos;
        void *c1 = (*b->method->codec.start)();
             
         decode_ptr(&src, &pos);
@@ -581,7 +595,7 @@ void close_block(ISAMB b, struct ISAMB_block *p)
                  p->pos, p->cat, p->pos/CAT_MAX);
         memcpy (p->buf, &b->file[p->cat].head.free_list, sizeof(zint));
         b->file[p->cat].head.free_list = p->pos;
-        if (!get_block (b, p->pos, p->buf, 1))
+        if (!cache_block (b, p->pos, p->buf, 1))
         {
             yaz_log(b->log_io, "bf_write: close_block (deleted)");
             bf_write(b->file[p->cat].bf, p->pos/CAT_MAX, 0, 0, p->buf);
@@ -591,7 +605,7 @@ void close_block(ISAMB b, struct ISAMB_block *p)
     {
        int offset = b->file[p->cat].head.block_offset;
         int size = p->size + offset;
-       char *dst =  p->buf + 3;
+       char *dst =  (char*)p->buf + 3;
         assert (p->size >= 0);
        
        /* memset becuase encode_ptr usually does not write all bytes */
@@ -601,7 +615,7 @@ void close_block(ISAMB b, struct ISAMB_block *p)
         p->buf[2] = size >> 8;
        encode_ptr(&dst, p->no_items);
         check_block(b, p);
-        if (!get_block (b, p->pos, p->buf, 1))
+        if (!cache_block (b, p->pos, p->buf, 1))
         {
             yaz_log(b->log_io, "bf_write: close_block");
             bf_write(b->file[p->cat].bf, p->pos/CAT_MAX, 0, 0, p->buf);
@@ -627,7 +641,7 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item,
     char *startp = p->bytes;
     const char *src = startp;
     char *endp = p->bytes + p->size;
-    ISAMB_P pos;
+    ISAM_P pos;
     struct ISAMB_block *sub_p1 = 0, *sub_p2 = 0;
     char sub_item[DST_ITEM_MAX];
     int sub_size;
@@ -731,11 +745,12 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item,
         p->size = dst - dst_buf;
         assert (p->size >= 0);
 
-
         if (p->size <= b->file[p->cat].head.block_max)
         {
            /* it fits OK in this block */
             memcpy (startp, dst_buf, dst - dst_buf);
+
+           close_block(b, sub_p2);
         }
         else
         {
@@ -753,6 +768,9 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item,
             src = dst_buf;
             endp = dst;
 
+           p->dirty = 1;
+           close_block(b, sub_p2);
+
             half = src + b->file[p->cat].head.block_size/2;
             decode_ptr(&src, &pos);
 
@@ -806,8 +824,7 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item,
            (*sp)->no_items = p->no_items - no_items_first_half;
            p->no_items = no_items_first_half;
         }
-        p->dirty = 1;
-        close_block(b, sub_p2);
+       p->dirty = 1;
     }
     close_block(b, sub_p1);
     (*b->method->codec.stop)(c1);
@@ -838,6 +855,7 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
     int cut_item_size = 0;
     int no_items = 0;    /* number of items (total) */
     int no_items_1 = 0;  /* number of items (first half) */
+    int inserted_dst_bytes = 0;
 
     if (p && p->size)
     {
@@ -851,6 +869,7 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
         {
             const char *dst_item = 0; /* resulting item to be inserted */
             char *lookahead_next;
+           char *dst_0 = dst;
             int d = -1;
             
             if (lookahead_item)
@@ -876,7 +895,6 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
             else
                 dst_item = file_item_buf;
 
-              
             if (!*lookahead_mode && d == 0)
             {
                /* it's a deletion and they match so there is nothing to be
@@ -913,7 +931,8 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
             {
                /* we must move the lookahead pointer */
 
-                if (dst > maxp)
+               inserted_dst_bytes += (dst - dst_0);
+                if (inserted_dst_bytes >=  quater)
                    /* no more room. Mark lookahead as "gone".. */
                     lookahead_item = 0;
                 else
@@ -965,17 +984,19 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
             }
         }
     }
-    maxp = dst_buf + b->file[b->no_cat-1].head.block_max + quater;
+
     /* this loop runs when we are "appending" to a leaf page. That is
        either it's empty (new) or all file items have been read in
        previous loop */
+
+    maxp = dst_buf + b->file[b->no_cat-1].head.block_max + quater;
     while (lookahead_item)
     {
         char *dst_item;
        const char *src = lookahead_item;
         char *dst_0 = dst;
         
-       /* compare lookahead with max item */
+       /* if we have a lookahead item, we stop if we exceed the value of it */
         if (max_item &&
             (*b->method->compare_item)(max_item, lookahead_item) <= 0)
         {
@@ -1053,6 +1074,7 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
        
        /* first half */
         p->size = half1 - dst_buf;
+       assert(p->size <=  b->file[p->cat].head.block_max);
         memcpy (p->bytes, dst_buf, half1 - dst_buf);
        p->no_items = no_items_1;
 
@@ -1068,6 +1090,7 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
         memcpy (first_dst, half2, dst - half2);
 
         (*sp2)->size = (first_dst - (*sp2)->bytes) + (dst - half2);
+       assert((*sp2)->size <=  b->file[p->cat].head.block_max);
        (*sp2)->no_items = no_items - no_items_1;
         (*sp2)->dirty = 1;
         p->dirty = 1;
@@ -1101,7 +1124,7 @@ int insert_sub (ISAMB b, struct ISAMB_block **p, void *new_item,
                            sub_size, max_item);
 }
 
-int isamb_unlink (ISAMB b, ISAMC_P pos)
+int isamb_unlink (ISAMB b, ISAM_P pos)
 {
     struct ISAMB_block *p1;
 
@@ -1142,7 +1165,7 @@ int isamb_unlink (ISAMB b, ISAMC_P pos)
     return 0;
 }
 
-ISAMB_P isamb_merge (ISAMB b, ISAMC_P pos, ISAMC_I *stream)
+void isamb_merge(ISAMB b, ISAM_P *pos, ISAMC_I *stream)
 {
     char item_buf[DST_ITEM_MAX];
     char *item_ptr;
@@ -1159,7 +1182,8 @@ ISAMB_P isamb_merge (ISAMB b, ISAMC_P pos, ISAMC_I *stream)
             more =
                 (*stream->read_item)(stream->clientData, &item_ptr, &i_mode);
         }
-        return 1;
+       *pos = 1;
+        return;
     }
     item_ptr = item_buf;
     more = (*stream->read_item)(stream->clientData, &item_ptr, &i_mode);
@@ -1169,8 +1193,8 @@ ISAMB_P isamb_merge (ISAMB b, ISAMC_P pos, ISAMC_I *stream)
         char sub_item[DST_ITEM_MAX];
         int sub_size;
         
-        if (pos)
-            p = open_block(b, pos);
+        if (*pos)
+            p = open_block(b, *pos);
         more = insert_sub (b, &p, item_buf, &i_mode, stream, &sp,
                           sub_item, &sub_size, 0);
         if (sp)
@@ -1196,7 +1220,7 @@ ISAMB_P isamb_merge (ISAMB b, ISAMC_P pos, ISAMC_I *stream)
             
             p2->size = dst - p2->bytes;
            p2->no_items = p->no_items + sp->no_items;
-            pos = p2->pos;  /* return new super page */
+            *pos = p2->pos;  /* return new super page */
             close_block(b, sp);
             close_block(b, p2);
 #if INT_ENCODE
@@ -1205,7 +1229,7 @@ ISAMB_P isamb_merge (ISAMB b, ISAMC_P pos, ISAMC_I *stream)
         }
         else
        {
-            pos = p->pos;   /* return current one (again) */
+            *pos = p->pos;   /* return current one (again) */
        }
        if (p->no_items == 0)
            must_delete = 1;
@@ -1215,13 +1239,12 @@ ISAMB_P isamb_merge (ISAMB b, ISAMC_P pos, ISAMC_I *stream)
     }
     if (must_delete)
     {
-       isamb_unlink(b, pos);
-       return 0;
+       isamb_unlink(b, *pos);
+       *pos = 0;
     }
-    return pos;
 }
 
-ISAMB_PP isamb_pp_open_x(ISAMB isamb, ISAMB_P pos, int *level, int scope)
+ISAMB_PP isamb_pp_open_x(ISAMB isamb, ISAM_P pos, int *level, int scope)
 {
     ISAMB_PP pp = xmalloc(sizeof(*pp));
     int i;
@@ -1239,8 +1262,8 @@ ISAMB_PP isamb_pp_open_x(ISAMB isamb, ISAMB_P pos, int *level, int scope)
     pp->skipped_numbers = 0;
     pp->returned_numbers = 0;
     pp->scope = scope;
-    for (i = 0;i<ISAMB_MAX_LEVEL;i++)
-        pp->skipped_nodes[i] = pp->accessed_nodes[i]=0;
+    for (i = 0; i<ISAMB_MAX_LEVEL; i++)
+        pp->skipped_nodes[i] = pp->accessed_nodes[i] = 0;
     while (1)
     {
         struct ISAMB_block *p = open_block(isamb, pos);
@@ -1263,12 +1286,12 @@ ISAMB_PP isamb_pp_open_x(ISAMB isamb, ISAMB_P pos, int *level, int scope)
     return pp;
 }
 
-ISAMB_PP isamb_pp_open (ISAMB isamb, ISAMB_P pos, int scope)
+ISAMB_PP isamb_pp_open (ISAMB isamb, ISAM_P pos, int scope)
 {
     return isamb_pp_open_x(isamb, pos, 0, scope);
 }
 
-void isamb_pp_close_x(ISAMB_PP pp, int *size, int *blocks)
+void isamb_pp_close_x(ISAMB_PP pp, zint *size, zint *blocks)
 {
     int i;
     if (!pp)
@@ -1276,14 +1299,14 @@ void isamb_pp_close_x(ISAMB_PP pp, int *size, int *blocks)
     yaz_log(YLOG_DEBUG, "isamb_pp_close lev=%d returned "ZINT_FORMAT" values, " 
                    "skipped "ZINT_FORMAT,
         pp->maxlevel, pp->skipped_numbers, pp->returned_numbers);
-    for (i = pp->maxlevel;i>=0;i--)
+    for (i = pp->maxlevel; i>=0; i--)
         if (pp->skipped_nodes[i] || pp->accessed_nodes[i])
             yaz_log(YLOG_DEBUG, "isamb_pp_close  level leaf-%d: "
                            ZINT_FORMAT" read, "ZINT_FORMAT" skipped", i,
                  pp->accessed_nodes[i], pp->skipped_nodes[i]);
     pp->isamb->skipped_numbers += pp->skipped_numbers;
     pp->isamb->returned_numbers += pp->returned_numbers;
-    for (i = pp->maxlevel;i>=0;i--)
+    for (i = pp->maxlevel; i>=0; i--)
     {
         pp->isamb->accessed_nodes[i] += pp->accessed_nodes[i];
         pp->isamb->skipped_nodes[i] += pp->skipped_nodes[i];
@@ -1311,7 +1334,7 @@ void isamb_pp_close (ISAMB_PP pp)
 }
 
 /* simple recursive dumper .. */
-static void isamb_dump_r (ISAMB b, ISAMB_P pos, void (*pr)(const char *str),
+static void isamb_dump_r (ISAMB b, ISAM_P pos, void (*pr)(const char *str),
                          int level)
 {
     char buf[1024];
@@ -1340,7 +1363,7 @@ static void isamb_dump_r (ISAMB b, ISAMB_P pos, void (*pr)(const char *str),
        else
        {
            const char *src = p->bytes + p->offset;
-           ISAMB_P sub;
+           ISAM_P sub;
 
            decode_ptr(&src, &sub);
            p->offset = src - (char*) p->bytes;
@@ -1373,7 +1396,7 @@ static void isamb_dump_r (ISAMB b, ISAMB_P pos, void (*pr)(const char *str),
     }
 }
 
-void isamb_dump(ISAMB b, ISAMB_P pos, void (*pr)(const char *str))
+void isamb_dump(ISAMB b, ISAM_P pos, void (*pr)(const char *str))
 {
     isamb_dump_r(b, pos, pr, 0);
 }
@@ -1507,7 +1530,7 @@ static int isamb_pp_forward_on_leaf(ISAMB_PP pp, void *buf, const void *untilbuf
     }
 } /* forward_on_leaf */
 
-static int isamb_pp_climb_level(ISAMB_PP pp, ISAMB_P *pos)
+static int isamb_pp_climb_level(ISAMB_PP pp, ISAM_P *pos)
 { /* climbs higher in the tree, until finds a level with data left */
   /* returns the node to (consider to) descend to in *pos) */
     struct ISAMB_block *p = pp->block[pp->level];
@@ -1528,7 +1551,7 @@ static int isamb_pp_climb_level(ISAMB_PP pp, ISAMB_P *pos)
     }
     assert(pp->level>0); 
     close_block(pp->isamb, pp->block[pp->level]);
-    pp->block[pp->level]=0;
+    pp->block[pp->level] = 0;
     (pp->level)--;
     p = pp->block[pp->level];
 #if ISAMB_DEBUG
@@ -1647,7 +1670,7 @@ static zint isamb_pp_forward_unode(ISAMB_PP pp, zint pos, const void *untilbuf)
     
 } /* forward_unode */
 
-static void isamb_pp_descend_to_leaf(ISAMB_PP pp, ISAMB_P pos,
+static void isamb_pp_descend_to_leaf(ISAMB_PP pp, ISAM_P pos,
                                     const void *untilbuf)
 { /* climbs down the tree, from pos, to the leftmost leaf */
     struct ISAMB_block *p = pp->block[pp->level];
@@ -1687,7 +1710,7 @@ static void isamb_pp_descend_to_leaf(ISAMB_PP pp, ISAMB_P pos,
 
 static int isamb_pp_find_next_leaf(ISAMB_PP pp)
 { /* finds the next leaf by climbing up and down */
-    ISAMB_P pos;
+    ISAM_P pos;
     if (!isamb_pp_climb_level(pp, &pos))
         return 0;
     isamb_pp_descend_to_leaf(pp, pos, 0);
@@ -1696,7 +1719,7 @@ static int isamb_pp_find_next_leaf(ISAMB_PP pp)
 
 static int isamb_pp_climb_desc(ISAMB_PP pp,  const void *untilbuf)
 { /* climbs up and descends to a leaf where values >= *untilbuf are found */
-    ISAMB_P pos;
+    ISAM_P pos;
 #if ISAMB_DEBUG
     struct ISAMB_block *p = pp->block[pp->level];
     yaz_log(YLOG_DEBUG, "isamb_pp_climb_desc starting "
@@ -1752,9 +1775,9 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf)
             if (isamb_pp_forward_on_leaf(pp, buf, untilbuf))
            {
 #if ISAMB_DEBUG
-            yaz_log(YLOG_DEBUG, "isamb_pp_forward (f) returning (C) "
-                   "at level %d node %d ofs=%d sz=%d",
-                    pp->level, p->pos, p->offset, p->size);
+               yaz_log(YLOG_DEBUG, "isamb_pp_forward (f) returning (c) "
+                       "at level %d node %d ofs=%d sz=%d",
+                       pp->level, p->pos, p->offset, p->size);
 #endif
                 return 1;
             }
@@ -1792,12 +1815,12 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf)
 void isamb_pp_pos(ISAMB_PP pp, double *current, double *total)
 { /* return an estimate of the current position and of the total number of */
   /* occureences in the isam tree, based on the current leaf */
-    struct ISAMB_block *p = pp->block[pp->level];
     assert(total);
     assert(current);
-    assert(p->leaf);
+    
+    /* if end-of-stream PP may not be leaf */
 
-    *total = pp->block[0]->no_items;
+    *total = (double) (pp->block[0]->no_items);
     *current = (double) pp->returned_numbers;
 #if ISAMB_DEBUG
     yaz_log(YLOG_LOG, "isamb_pp_pos returning: cur= %0.1f tot=%0.1f rn="
@@ -1816,7 +1839,7 @@ int isamb_pp_forward2(ISAMB_PP pp, void *buf, const void *untilb)
 again:
     while (p->offset == p->size)
     {
-        ISAMB_P pos;
+        ISAM_P pos;
 #if INT_ENCODE
        const char *src_0;
        void *c1;
@@ -1937,3 +1960,11 @@ again:
     }
     return 1;
 }
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+