-void insert_sub (ISAMB b, struct ISAMB_block *p, const void *new_item,
- struct ISAMB_block **sp,
- void *sub_item, int *sub_size);
-
-void insert_leaf (ISAMB b, struct ISAMB_block *p, const void *new_item,
- struct ISAMB_block **sp,
- void *sub_item, int *sub_size)
-{
- char dst_buf[DST_BUF_SIZE];
- char *dst = dst_buf;
- char *src = p->bytes + ISAMB_DATA_OFFSET;
- char *endp = p->bytes + p->size;
- void *c1 = (*b->method->code_start)(ISAMC_DECODE);
- void *c2 = (*b->method->code_start)(ISAMC_ENCODE);
- char *half1 = 0;
- char *half2 = 0;
- char *cut = dst_buf + p->size / 2;
- char cut_item_buf[DST_ITEM_MAX];
- int cut_item_size = 0;
-
- while (src != endp)
- {
- char file_item_buf[DST_ITEM_MAX];
- char *file_item = file_item_buf;
-
- (*b->method->code_item)(ISAMC_DECODE, c1, &file_item, &src);
- if (new_item)
- {
- int d = (*b->method->compare_item)(file_item_buf, new_item);
- if (d > 0)
- {
- char *item_ptr = (char*) new_item;
- (*b->method->code_item)(ISAMC_ENCODE, c2, &dst, &item_ptr);
- new_item = 0;
- p->dirty = 1;
- }
- else if (d == 0)
- {
- new_item = 0;
- }
- }
-
- if (!half1 && dst > cut)
- {
- half1 = dst; /* candidate for splitting */
-
- file_item = file_item_buf;
- (*b->method->code_item)(ISAMC_ENCODE, c2, &dst, &file_item);
-
- cut_item_size = file_item - file_item_buf;
- memcpy (cut_item_buf, file_item_buf, cut_item_size);
-
- half2 = dst;
- }
- else
- {
- file_item = file_item_buf;
- (*b->method->code_item)(ISAMC_ENCODE, c2, &dst, &file_item);
- }
- }
- if (new_item)
- {
- char *item_ptr = (char*) new_item;
- (*b->method->code_item)(ISAMC_ENCODE, c2, &dst, &item_ptr);
- new_item = 0;
- p->dirty = 1;
- }
- p->size = dst - dst_buf + ISAMB_DATA_OFFSET;
- if (p->size > b->file[p->cat].head.block_size)
- {
- char *first_dst;
- char *cut_item = cut_item_buf;
-
- /* first half */
- p->size = half1 - dst_buf + ISAMB_DATA_OFFSET;
- memcpy (p->bytes+ISAMB_DATA_OFFSET, dst_buf, half1 - dst_buf);
-
- /* second half */
- *sp = new_block (b, 1, p->cat);
-
- (*b->method->code_reset)(c2);
-
- first_dst = (*sp)->bytes + ISAMB_DATA_OFFSET;
-
- (*b->method->code_item)(ISAMC_ENCODE, c2, &first_dst, &cut_item);
-
- memcpy (first_dst, half2, dst - half2);
-
- (*sp)->size = (first_dst - (char*) (*sp)->bytes) + (dst - half2);
- (*sp)->dirty = 1;
- p->dirty = 1;
- memcpy (sub_item, cut_item_buf, cut_item_size);
- *sub_size = cut_item_size;
-
- yaz_log (LOG_LOG, "l split %d / %d", p->size, (*sp)->size);
-
- }
- else
- {
- assert (p->size > ISAMB_DATA_OFFSET);
- assert (p->size <= b->file[p->cat].head.block_size);
- memcpy (p->bytes+ISAMB_DATA_OFFSET, dst_buf, dst - dst_buf);
- *sp = 0;
- }
- (*b->method->code_stop)(ISAMC_DECODE, c1);
- (*b->method->code_stop)(ISAMC_ENCODE, c2);
-}