+ /* merge first item (or its part) of src buffer with the last
+ item of dest buffer. Both are of the same file */
+ leaf_paste_in_buffer(dest_bi,
+ dest_nr_item - 1, ih_item_len(dih),
+ bytes_or_entries, B_I_PITEM(src, ih), 0);
+
+ if (is_indirect_le_ih(dih)) {
+ RFALSE(get_ih_free_space(dih),
+ "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
+ ih);
+ if (bytes_or_entries == ih_item_len(ih))
+ set_ih_free_space(dih, get_ih_free_space(ih));
+ }
+
+ return 1;
+ }
+
+ /* copy boundary item to right (last_first == LAST_TO_FIRST) */
+
+ /* ( DEST is empty or last item of SOURCE and first item of DEST
+ are the items of different object or of different types )
+ */
+ src_nr_item = B_NR_ITEMS(src);
+ ih = B_N_PITEM_HEAD(src, src_nr_item - 1);
+ dih = B_N_PITEM_HEAD(dest, 0);
+
+ if (!dest_nr_item || !op_is_left_mergeable(&(dih->ih_key), src->b_size))
+ return 0;
+
+ if (is_direntry_le_ih(ih)) {
+ if (bytes_or_entries == -1)
+ /* bytes_or_entries = entries number in last item body of SOURCE */
+ bytes_or_entries = ih_entry_count(ih);
+
+ leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
+ src_nr_item - 1,
+ ih_entry_count(ih) - bytes_or_entries,
+ bytes_or_entries);
+ return 1;
+ }
+
+ /* copy part of the body of the last item of SOURCE to the begin of the body of the first item of the DEST;
+ part defined by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body; change first item key of the DEST;
+ don't create new item header
+ */
+
+ RFALSE(is_indirect_le_ih(ih) && get_ih_free_space(ih),
+ "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
+ ih);
+
+ if (bytes_or_entries == -1) {
+ /* bytes_or_entries = length of last item body of SOURCE */
+ bytes_or_entries = ih_item_len(ih);
+
+ RFALSE(le_ih_k_offset(dih) !=
+ le_ih_k_offset(ih) + op_bytes_number(ih, src->b_size),
+ "vs-10050: items %h and %h do not match", ih, dih);
+
+ /* change first item key of the DEST */
+ set_le_ih_k_offset(dih, le_ih_k_offset(ih));
+
+ /* item becomes non-mergeable */
+ /* or mergeable if left item was */
+ set_le_ih_k_type(dih, le_ih_k_type(ih));
+ } else {
+ /* merge to right only part of item */
+ RFALSE(ih_item_len(ih) <= bytes_or_entries,
+ "vs-10060: no so much bytes %lu (needed %lu)",
+ (unsigned long)ih_item_len(ih),
+ (unsigned long)bytes_or_entries);
+
+ /* change first item key of the DEST */
+ if (is_direct_le_ih(dih)) {
+ RFALSE(le_ih_k_offset(dih) <=
+ (unsigned long)bytes_or_entries,
+ "vs-10070: dih %h, bytes_or_entries(%d)", dih,
+ bytes_or_entries);
+ set_le_ih_k_offset(dih,
+ le_ih_k_offset(dih) -
+ bytes_or_entries);
+ } else {
+ RFALSE(le_ih_k_offset(dih) <=
+ (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
+ "vs-10080: dih %h, bytes_or_entries(%d)",
+ dih,
+ (bytes_or_entries / UNFM_P_SIZE) * dest->b_size);
+ set_le_ih_k_offset(dih,
+ le_ih_k_offset(dih) -
+ ((bytes_or_entries / UNFM_P_SIZE) *
+ dest->b_size));
+ }
+ }
+
+ leaf_paste_in_buffer(dest_bi, 0, 0, bytes_or_entries,
+ B_I_PITEM(src,
+ ih) + ih_item_len(ih) - bytes_or_entries,
+ 0);
+ return 1;
+}