More digits in output for total docs
[idzebra-moved-to-github.git] / isamb / isamb.c
index 8e464ba..3e85ee1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isamb.c,v 1.85 2006-11-14 08:12:08 adam Exp $
+/* $Id: isamb.c,v 1.88 2006-12-12 13:46:41 adam Exp $
    Copyright (C) 1995-2006
    Index Data ApS
 
@@ -53,8 +53,9 @@ struct ISAMB_head {
 
 #define ISAMB_MAX_LEVEL 10
 /* approx 2*max page + max size of item */
-#define DST_BUF_SIZE 16840
+#define DST_BUF_SIZE (2*4096+300)
 
+/* should be maximum block size of multiple thereof */
 #define ISAMB_CACHE_ENTRY_SIZE 4096
 
 /* CAT_MAX: _must_ be power of 2 */
@@ -99,6 +100,10 @@ struct ISAMB_s {
     zint returned_numbers; 
     zint skipped_nodes[ISAMB_MAX_LEVEL]; /* [0]=skipped leaves, 1 = higher etc */
     zint accessed_nodes[ISAMB_MAX_LEVEL]; /* nodes we did not skip */
+    zint number_of_int_splits;
+    zint number_of_leaf_splits;
+    int enable_int_count; /* whether we count nodes (or not) */
+    int cache_size; /* size of blocks to cache (if cache=1) */
 };
 
 struct ISAMB_block {
@@ -179,6 +184,17 @@ static void decode_ptr(const char **src, zint *pos)
 }
 #endif
 
+
+void isamb_set_int_count(ISAMB b, int v)
+{
+    b->enable_int_count = v;
+}
+
+void isamb_set_cache_size(ISAMB b, int v)
+{
+    b->cache_size = v;
+}
+
 ISAMB isamb_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method,
                 int cache)
 {
@@ -194,10 +210,22 @@ ISAMB isamb_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method,
     isamb->cache = cache;
     isamb->skipped_numbers = 0;
     isamb->returned_numbers = 0;
+    isamb->number_of_int_splits = 0;
+    isamb->number_of_leaf_splits = 0;
+    isamb->enable_int_count = 1;
+    isamb->cache_size = 40;
+
     for (i = 0; i<ISAMB_MAX_LEVEL; i++)
        isamb->skipped_nodes[i] = isamb->accessed_nodes[i] = 0;
 
-    assert(cache == 0);
+    if (cache == -1)
+    {
+        yaz_log(YLOG_WARN, "isamb_open %s. Degraded TEST mode", name);
+    }
+    else
+    {
+        assert(cache == 0 || cache == 1);
+    }
     isamb->file = xmalloc(sizeof(*isamb->file) * isamb->no_cat);
 
     for (i = 0; i < isamb->no_cat; i++)
@@ -229,6 +257,7 @@ ISAMB isamb_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method,
        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;
        isamb->file[i].head.block_size = b_size;
+        assert(b_size <= ISAMB_CACHE_ENTRY_SIZE);
 #if ISAMB_PTR_CODEC
        if (i == isamb->no_cat-1 || b_size > 128)
            isamb->file[i].head.block_offset = 8;
@@ -348,9 +377,8 @@ static int cache_block (ISAMB b, ISAM_P pos, unsigned char *userbuf, int wr)
             return 1;
         }
     }
-    if (no >= 40)
+    if (no >= b->cache_size)
     {
-        assert (no == 40);
         assert (ce_last && *ce_last);
         ce_this = *ce_last;
         *ce_last = 0;  /* remove the last entry from list */
@@ -462,11 +490,11 @@ static struct ISAMB_block *open_block(ISAMB b, ISAM_P pos)
     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))
+        if (bf_read(b->file[cat].bf, pos/CAT_MAX, 0, 0, p->buf) != 1)
         {
             yaz_log(YLOG_FATAL, "isamb: read fail for pos=%ld block=%ld",
                      (long) pos, (long) pos/CAT_MAX);
-            abort();
+            zebra_exit("isamb:open_block");
         }
     }
     p->bytes = (char *)p->buf + offset;
@@ -512,7 +540,7 @@ struct ISAMB_block *new_block (ISAMB b, int leaf, int cat)
             {
                 yaz_log(YLOG_FATAL, "isamb: read fail for pos=%ld block=%ld",
                          (long) p->pos/CAT_MAX, (long) p->pos/CAT_MAX);
-                abort ();
+                zebra_exit("isamb:new_block");
             }
         }
         yaz_log(b->log_freelist, "got block " ZINT_FORMAT " from freelist %d:" ZINT_FORMAT, p->pos,
@@ -767,6 +795,8 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item,
             const char *half;
             src = dst_buf;
             endp = dst;
+            
+            b->number_of_int_splits++;
 
            p->dirty = 1;
            close_block(b, sub_p2);
@@ -774,10 +804,13 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item,
             half = src + b->file[p->cat].head.block_size/2;
             decode_ptr(&src, &pos);
 
-           /* read sub block so we can get no_items for it */
-           sub_p3 = open_block(b, pos);
-           no_items_first_half += sub_p3->no_items;
-           close_block(b, sub_p3);
+            if (b->enable_int_count)
+            {
+                /* read sub block so we can get no_items for it */
+                sub_p3 = open_block(b, pos);
+                no_items_first_half += sub_p3->no_items;
+                close_block(b, sub_p3);
+            }
 
             while (src <= half)
             {
@@ -792,10 +825,13 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item,
 #endif
                 decode_ptr(&src, &pos);
 
-               /* read sub block so we can get no_items for it */
-               sub_p3 = open_block(b, pos);
-               no_items_first_half += sub_p3->no_items;
-               close_block(b, sub_p3);
+                if (b->enable_int_count)
+                {
+                    /* read sub block so we can get no_items for it */
+                    sub_p3 = open_block(b, pos);
+                    no_items_first_half += sub_p3->no_items;
+                    close_block(b, sub_p3);
+                }
             }
            /*  p is first half */
             p_new_size = src - dst_buf;
@@ -889,7 +925,7 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
                 if (!*lookahead_mode)
                 {
                     yaz_log(YLOG_WARN, "isamb: Inconsistent register (1)");
-                    assert (*lookahead_mode);
+                    assert(*lookahead_mode);
                 }
             }
             else
@@ -1007,7 +1043,7 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
         {
            /* this is append. So a delete is bad */
             yaz_log(YLOG_WARN, "isamb: Inconsistent register (2)");
-            abort();
+            assert(*lookahead_mode);
         }
         else if (!half1 && dst > tail_cut)
         {
@@ -1083,6 +1119,8 @@ int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,
 
         (*b->method->codec.reset)(c2);
 
+        b->number_of_leaf_splits++;
+
         first_dst = (*sp2)->bytes;
 
         (*b->method->codec.encode)(c2, &first_dst, &cut_item);
@@ -1960,6 +1998,17 @@ again:
     }
     return 1;
 }
+
+zint isamb_get_int_splits(ISAMB b)
+{
+    return b->number_of_int_splits;
+}
+
+zint isamb_get_leaf_splits(ISAMB b)
+{
+    return b->number_of_leaf_splits;
+}
+
 /*
  * Local variables:
  * c-basic-offset: 4