⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lbalance.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* If cpy_bytes equals minus one than copy cpy_num whole items from SOURCE to DEST.   If cpy_bytes not equal to minus one than copy cpy_num-1 whole items from SOURCE to DEST.   From last item copy cpy_num bytes for regular item and cpy_num directory entries for   directory item. */static int leaf_copy_items (struct buffer_info * dest_bi, struct buffer_head * src, int last_first, int cpy_num,			    int cpy_bytes){  struct buffer_head * dest;  int pos, i, src_nr_item, bytes;  dest = dest_bi->bi_bh;  RFALSE( !dest || !src, "vs-10210: !dest || !src");  RFALSE( last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,	  "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");  RFALSE( B_NR_ITEMS(src) < cpy_num,	  "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src), cpy_num);  RFALSE( cpy_num < 0,"vs-10240: cpy_num < 0 (%d)", cpy_num); if ( cpy_num == 0 )   return 0;  if ( last_first == FIRST_TO_LAST ) {   /* copy items to left */   pos = 0;   if ( cpy_num == 1 )     bytes = cpy_bytes;   else     bytes = -1;      /* copy the first item or it part or nothing to the end of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes)) */   i = leaf_copy_boundary_item (dest_bi, src, FIRST_TO_LAST, bytes);   cpy_num -= i;   if ( cpy_num == 0 )     return i;   pos += i;   if ( cpy_bytes == -1 )     /* copy first cpy_num items starting from position 'pos' of SOURCE to end of DEST */     leaf_copy_items_entirely (dest_bi, src, FIRST_TO_LAST, pos, cpy_num);   else {     /* copy first cpy_num-1 items starting from position 'pos-1' of the SOURCE to the end of the DEST */     leaf_copy_items_entirely (dest_bi, src, FIRST_TO_LAST, pos, cpy_num-1);	          /* copy part of the item which number is cpy_num+pos-1 to the end of the DEST */     leaf_item_bottle (dest_bi, src, FIRST_TO_LAST, cpy_num+pos-1, cpy_bytes);   }  } else {   /* copy items to right */   src_nr_item = B_NR_ITEMS (src);   if ( cpy_num == 1 )     bytes = cpy_bytes;   else     bytes = -1;      /* copy the last item or it part or nothing to the begin of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes)); */   i = leaf_copy_boundary_item (dest_bi, src, LAST_TO_FIRST, bytes);      cpy_num -= i;   if ( cpy_num == 0 )     return i;      pos = src_nr_item - cpy_num - i;   if ( cpy_bytes == -1 ) {     /* starting from position 'pos' copy last cpy_num items of SOURCE to begin of DEST */     leaf_copy_items_entirely (dest_bi, src, LAST_TO_FIRST, pos, cpy_num);   } else {     /* copy last cpy_num-1 items starting from position 'pos+1' of the SOURCE to the begin of the DEST; */     leaf_copy_items_entirely (dest_bi, src, LAST_TO_FIRST, pos+1, cpy_num-1);     /* copy part of the item which number is pos to the begin of the DEST */     leaf_item_bottle (dest_bi, src, LAST_TO_FIRST, pos, cpy_bytes);   } } return i;}/* there are types of coping: from S[0] to L[0], from S[0] to R[0],   from R[0] to L[0]. for each of these we have to define parent and   positions of destination and source buffers */static void leaf_define_dest_src_infos (int shift_mode, struct tree_balance * tb, struct buffer_info * dest_bi,					struct buffer_info * src_bi, int * first_last,					struct buffer_head * Snew){    memset (dest_bi, 0, sizeof (struct buffer_info));    memset (src_bi, 0, sizeof (struct buffer_info));    /* define dest, src, dest parent, dest position */    switch (shift_mode) {    case LEAF_FROM_S_TO_L:    /* it is used in leaf_shift_left */	src_bi->tb = tb;	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);	/* src->b_item_order */	dest_bi->tb = tb;	dest_bi->bi_bh = tb->L[0];	dest_bi->bi_parent = tb->FL[0];	dest_bi->bi_position = get_left_neighbor_position (tb, 0);	*first_last = FIRST_TO_LAST;	break;    case LEAF_FROM_S_TO_R:  /* it is used in leaf_shift_right */	src_bi->tb = tb;	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);	dest_bi->tb = tb;	dest_bi->bi_bh = tb->R[0];	dest_bi->bi_parent = tb->FR[0];	dest_bi->bi_position = get_right_neighbor_position (tb, 0);	*first_last = LAST_TO_FIRST;	break;    case LEAF_FROM_R_TO_L:  /* it is used in balance_leaf_when_delete */	src_bi->tb = tb;	src_bi->bi_bh = tb->R[0];	src_bi->bi_parent = tb->FR[0];	src_bi->bi_position = get_right_neighbor_position (tb, 0);	dest_bi->tb = tb;	dest_bi->bi_bh = tb->L[0];	dest_bi->bi_parent = tb->FL[0];	dest_bi->bi_position = get_left_neighbor_position (tb, 0);	*first_last = FIRST_TO_LAST;	break;        case LEAF_FROM_L_TO_R:  /* it is used in balance_leaf_when_delete */	src_bi->tb = tb;	src_bi->bi_bh = tb->L[0];	src_bi->bi_parent = tb->FL[0];	src_bi->bi_position = get_left_neighbor_position (tb, 0);	dest_bi->tb = tb;	dest_bi->bi_bh = tb->R[0];	dest_bi->bi_parent = tb->FR[0];	dest_bi->bi_position = get_right_neighbor_position (tb, 0);	*first_last = LAST_TO_FIRST;	break;    case LEAF_FROM_S_TO_SNEW:	src_bi->tb = tb;	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);	dest_bi->tb = tb;	dest_bi->bi_bh = Snew;	dest_bi->bi_parent = 0;	dest_bi->bi_position = 0;	*first_last = LAST_TO_FIRST;	break;        default:	reiserfs_panic (0, "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", shift_mode);    }    RFALSE( src_bi->bi_bh == 0 || dest_bi->bi_bh == 0,	    "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",	    shift_mode, src_bi->bi_bh, dest_bi->bi_bh);}/* copy mov_num items and mov_bytes of the (mov_num-1)th item to   neighbor. Delete them from source */int leaf_move_items (int shift_mode, struct tree_balance * tb, int mov_num, int mov_bytes, struct buffer_head * Snew){  int ret_value;  struct buffer_info dest_bi, src_bi;  int first_last;  leaf_define_dest_src_infos (shift_mode, tb, &dest_bi, &src_bi, &first_last, Snew);  ret_value = leaf_copy_items (&dest_bi, src_bi.bi_bh, first_last, mov_num, mov_bytes);  leaf_delete_items (&src_bi, first_last, (first_last == FIRST_TO_LAST) ? 0 : (B_NR_ITEMS(src_bi.bi_bh) - mov_num), mov_num, mov_bytes);    return ret_value;}/* Shift shift_num items (and shift_bytes of last shifted item if shift_bytes != -1)   from S[0] to L[0] and replace the delimiting key */int leaf_shift_left (struct tree_balance * tb, int shift_num, int shift_bytes){  struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);  int i;  /* move shift_num (and shift_bytes bytes) items from S[0] to left neighbor L[0] */  i = leaf_move_items (LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, 0);  if ( shift_num ) {    if (B_NR_ITEMS (S0) == 0) { /* number of items in S[0] == 0 */      RFALSE( shift_bytes != -1,	      "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)", 	      shift_bytes);#ifdef CONFIG_REISERFS_CHECK      if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) {	print_cur_tb ("vs-10275");	reiserfs_panic (tb->tb_sb, "vs-10275: leaf_shift_left: balance condition corrupted (%c)", tb->tb_mode);      }#endif      if (PATH_H_POSITION (tb->tb_path, 1) == 0)	replace_key (tb, tb->CFL[0], tb->lkey[0], PATH_H_PPARENT (tb->tb_path, 0), 0);    } else {           /* replace lkey in CFL[0] by 0-th key from S[0]; */      replace_key (tb, tb->CFL[0], tb->lkey[0], S0, 0);            RFALSE( (shift_bytes != -1 &&              !(is_direntry_le_ih (B_N_PITEM_HEAD (S0, 0))                && !I_ENTRY_COUNT (B_N_PITEM_HEAD (S0, 0)))) &&	      (!op_is_left_mergeable (B_N_PKEY (S0, 0), S0->b_size)),	      "vs-10280: item must be mergeable");    }  }    return i;}/* CLEANING STOPPED HERE *//* Shift shift_num (shift_bytes) items from S[0] to the right neighbor, and replace the delimiting key */int	leaf_shift_right(		struct tree_balance * tb, 		int shift_num,		int shift_bytes	){  //  struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);  int ret_value;  /* move shift_num (and shift_bytes) items from S[0] to right neighbor R[0] */  ret_value = leaf_move_items (LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, 0);  /* replace rkey in CFR[0] by the 0-th key from R[0] */  if (shift_num) {    replace_key (tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);  }  return ret_value;}static void leaf_delete_items_entirely (struct buffer_info * bi,					int first, int del_num);/*  If del_bytes == -1, starting from position 'first' delete del_num items in whole in buffer CUR.    If not.     If last_first == 0. Starting from position 'first' delete del_num-1 items in whole. Delete part of body of    the first item. Part defined by del_bytes. Don't delete first item header    If last_first == 1. Starting from position 'first+1' delete del_num-1 items in whole. Delete part of body of    the last item . Part defined by del_bytes. Don't delete last item header.*/void leaf_delete_items (struct buffer_info * cur_bi, int last_first, 			int first, int del_num, int del_bytes){    struct buffer_head * bh;    int item_amount = B_NR_ITEMS (bh = cur_bi->bi_bh);    RFALSE( !bh, "10155: bh is not defined");    RFALSE( del_num < 0, "10160: del_num can not be < 0. del_num==%d", del_num);    RFALSE( first < 0 || first + del_num > item_amount,	    "10165: invalid number of first item to be deleted (%d) or "	    "no so much items (%d) to delete (only %d)", 	    first, first + del_num, item_amount);    if ( del_num == 0 )	return;    if ( first == 0 && del_num == item_amount && del_bytes == -1 ) {	make_empty_node (cur_bi);	do_balance_mark_leaf_dirty (cur_bi->tb, bh, 0);	return;    }    if ( del_bytes == -1 )	/* delete del_num items beginning from item in position first */	leaf_delete_items_entirely (cur_bi, first, del_num);    else {	if ( last_first == FIRST_TO_LAST ) {	    /* delete del_num-1 items beginning from item in position first  */	    leaf_delete_items_entirely (cur_bi, first, del_num-1);	    /* delete the part of the first item of the bh	       do not delete item header	    */	    leaf_cut_from_buffer (cur_bi, 0, 0, del_bytes);	} else  {	    struct item_head * ih;	    int len;	    /* delete del_num-1 items beginning from item in position first+1  */	    leaf_delete_items_entirely (cur_bi, first+1, del_num-1);	    if (is_direntry_le_ih (ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh)-1))) 	/* the last item is directory  */	        /* len = numbers of directory entries in this item */		len = ih_entry_count(ih);	    else	        /* len = body len of item */		len = ih_item_len(ih);	    /* delete the part of the last item of the bh 	       do not delete item header	    */	    leaf_cut_from_buffer (cur_bi, B_NR_ITEMS(bh)-1, len - del_bytes, del_bytes);	}    }}/* insert item into the leaf node in position before */void leaf_insert_into_buf (struct buffer_info * bi, int before,			   struct item_head * inserted_item_ih,			   const char * inserted_item_body,			   int zeros_number){    struct buffer_head * bh = bi->bi_bh;    int nr, free_space;    struct block_head * blkh;    struct item_head * ih;    int i;    int last_loc, unmoved_loc;    char * to;    blkh = B_BLK_HEAD(bh);    nr = blkh_nr_item(blkh);    free_space = blkh_free_space( blkh );    /* check free space */    RFALSE( free_space < ih_item_len(inserted_item_ih) + IH_SIZE,            "vs-10170: not enough free space in block %z, new item %h",            bh, inserted_item_ih);    RFALSE( zeros_number > ih_item_len(inserted_item_ih),	    "vs-10172: zero number == %d, item length == %d",            zeros_number, ih_item_len(inserted_item_ih));    /* get item new item must be inserted before */    ih = B_N_PITEM_HEAD (bh, before);    /* prepare space for the body of new item */    last_loc = nr ? ih_location( &(ih[nr - before - 1]) ) : bh->b_size;    unmoved_loc = before ? ih_location( ih-1 ) : bh->b_size;    memmove (bh->b_data + last_loc - ih_item_len(inserted_item_ih), 	     bh->b_data + last_loc, unmoved_loc - last_loc);    to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);    memset (to, 0, zeros_number);    to += zeros_number;    /* copy body to prepared space */    if (inserted_item_body)	memmove (to, inserted_item_body, ih_item_len(inserted_item_ih) - zeros_number);    else	memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);      /* insert item header */    memmove (ih + 1, ih, IH_SIZE * (nr - before));    memmove (ih, inserted_item_ih, IH_SIZE);      /* change locations */    for (i = before; i < nr + 1; i ++)    {        unmoved_loc -= ih_item_len( &(ih[i-before]));	put_ih_location( &(ih[i-before]), unmoved_loc );    }      /* sizes, free space, item number */    set_blkh_nr_item( blkh, blkh_nr_item(blkh) + 1 );    set_blkh_free_space( blkh,                    free_space - (IH_SIZE + ih_item_len(inserted_item_ih ) ) );    do_balance_mark_leaf_dirty (bi->tb, bh, 1);    if (bi->bi_parent) { 	struct disk_child *t_dc;	t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);	put_dc_size( t_dc, dc_size(t_dc) + (IH_SIZE + ih_item_len(inserted_item_ih)));	do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);    }}/* paste paste_size bytes to affected_item_num-th item.    When item is a directory, this only prepare space for new entries */void leaf_paste_in_buffer (struct buffer_info * bi, int affected_item_num,			   int pos_in_item, int paste_size,			   const char * body,			   int zeros_number){    struct buffer_head * bh = bi->bi_bh;    int nr, free_space;    struct block_head * blkh;    struct item_head * ih;    int i;    int last_loc, unmoved_loc;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -