+ char *startp = p->bytes + ISAMB_DATA_OFFSET;
+ char *src = startp;
+ char *endp = p->bytes + p->size;
+ int pos;
+ struct ISAMB_block *sub_p1 = 0, *sub_p2 = 0;
+ char sub_item[DST_ITEM_MAX];
+ int sub_size;
+
+ *sp = 0;
+
+ decode_ptr (&src, &pos);
+ while (src != endp)
+ {
+ int item_len;
+ int d;
+ decode_ptr (&src, &item_len);
+ d = (*b->method->compare_item)(src, new_item);
+ if (d > 0)
+ {
+ sub_p1 = open_block (b, pos);
+ assert (sub_p1);
+ insert_sub (b, sub_p1, new_item, &sub_p2,
+ sub_item, &sub_size);
+ break;
+ }
+ src += item_len;
+ decode_ptr (&src, &pos);
+ }
+ if (!sub_p1)
+ {
+ sub_p1 = open_block (b, pos);
+ assert (sub_p1);
+ insert_sub (b, sub_p1, new_item, &sub_p2,
+ sub_item, &sub_size);
+ }
+ if (sub_p2)
+ {
+ char dst_buf[DST_BUF_SIZE];
+ char *dst = dst_buf;
+
+ assert (sub_size < 20);
+
+ memcpy (dst, startp, src - startp);
+
+ dst += src - startp;
+
+ encode_ptr (&dst, sub_size); /* sub length and item */
+ memcpy (dst, sub_item, sub_size);
+ dst += sub_size;
+
+ encode_ptr (&dst, sub_p2->pos); /* pos */
+
+ if (endp - src) /* remaining data */
+ {
+ memcpy (dst, src, endp - src);
+ dst += endp - src;
+ }
+ p->size = dst - dst_buf + ISAMB_DATA_OFFSET;
+ if (p->size <= b->file[p->cat].head.block_size)
+ {
+ memcpy (startp, dst_buf, dst - dst_buf);
+ }
+ else
+ {
+ int p_new_size;
+ char *half;
+ src = dst_buf;
+ endp = dst;
+
+ half = src + b->file[p->cat].head.block_size/2;
+ decode_ptr (&src, &pos);
+ while (src <= half)
+ {
+ decode_ptr (&src, split_size);
+ src += *split_size;
+ decode_ptr (&src, &pos);
+ }
+ p_new_size = src - dst_buf;
+ memcpy (p->bytes + ISAMB_DATA_OFFSET, dst_buf, p_new_size);
+ p_new_size += ISAMB_DATA_OFFSET;
+
+ decode_ptr (&src, split_size);
+ memcpy (split_item, src, *split_size);
+ src += *split_size;
+
+ *sp = new_block (b, 0, p->cat);
+ (*sp)->size = endp - src;
+ memcpy ((*sp)->bytes+ISAMB_DATA_OFFSET, src, (*sp)->size);
+ (*sp)->size += ISAMB_DATA_OFFSET;
+
+ yaz_log (LOG_LOG, "i split %d -> %d %d",
+ p->size, p_new_size, (*sp)->size);
+ p->size = p_new_size;
+ }
+ p->dirty = 1;
+ close_block (b, sub_p2);
+ }
+ close_block (b, sub_p1);
+}
+
+void insert_sub (ISAMB b, struct ISAMB_block *p, const void *new_item,
+ struct ISAMB_block **sp,
+ void *sub_item, int *sub_size)
+{
+ if (p->leaf)
+ insert_leaf (b, p, new_item, sp, sub_item, sub_size);
+ else
+ insert_int (b, p, new_item, sp, sub_item, sub_size);