昨天写了一个小程序,具体功能是实现IO分割的。
题目:将给定的一个IO的起始位置,再给定一个长度,比如(24542,16438),将其分割成几个小的IO,分割要求是
1, 不足16的单独处理
2, 满8192的一大块,单独处理
3, 不足8192但大于16的放一起处理。
例子, 如给定IO(24542,16438),分割结果如下:
(24542,24544)
(24544,24576)
(24576,32768)
(32768,40960)
(40960,40976)
(40976,40980)
也就是说,给定IO的起始位置,加上IO的长度,等于最终的值。即24542+16438=40980;也有2+32+8192+8192+16+4 = 16438;
话不多说,直接上代码:#include
int is_division(int tmp);
void deal_big_tidy(int begin,int len);
void deal_big_untidy(int begin,int len);
int is_division(int tmp)
{
printf("isdivision hahaha\n");
if((tmp % 16) == 0)
{
printf("the begin is division\n");
return 1;
}
else
{
printf("the begin is not division\n");
return 0;
}
}
void deal_big_tidy(int begin,int len) //IO大于8192,对齐的方式
{
int big_tidy_need,m,n,big_residue,tmp,pos,i,len_change,opt,opt_n;
if(begin >= 8192) //起始位置是否处于一个8192中
{
big_tidy_need = 8192 - (begin%8192);
}
else
{
big_tidy_need = 8192 - begin;
}
printf("the big_tidy_need is :%d\n",big_tidy_need);
opt = big_tidy_need % 16; //补填剩余不够16的大小
opt_n = (big_tidy_need - opt) / 16; //要补填的16的个数
if(big_tidy_need < len)
{
printf("%d %d %d\n",begin,begin+opt_n*16,opt_n*16);
tmp = begin+big_tidy_need; //其实big_tidy_need == opt_n*16,由于是整除16,所以余数为0
len_change = len - big_tidy_need;
if(len_change >= 8192) //判断len的长度,并分割
{
m = len_change / 8192;
n = (len_change - 8192 * m) / 16;
big_residue = len_change - (8192 * m +16 *n);
for(i= 0; i < m; i++)
{
pos = tmp;
pos += 8192;
printf("the num i:%d\n",i);
printf("%d %d %d\n",tmp,pos,8192);
tmp = pos;
}
pos = tmp;
printf("the pos is :%d\n",pos);
printf("%d %d %d\n",pos,pos+n*16,n * 16);
printf("%d %d %d\n",pos+n*16,pos+n*16+big_residue,big_residue);
}
else if(len > 16)
{
n = len_change / 16;
big_residue = len_change - n*16;
printf("%d %d %d\n",tmp,tmp+n*16,n*16);
printf("%d %d %d\n",tmp+n*16,tmp+n*16+big_residue,big_residue);
}
else
{
printf("%d %d %d\n",begin,begin+len,len);
}
}
else if(big_tidy_need > 16)
{
n = len / 16;
big_residue = len - n*16;
printf("%d %d %d\n",begin,begin+n*16,n*16);
printf("%d %d %d\n",begin+n*16,begin+n*16+big_residue,big_residue);
}
else
{
printf("%d %d %d\n",begin,begin+len,len);
}
}
void deal_big_untidy(int begin,int len) //IO大于8192,不对齐的方式
{
int big_untidy_need,m,n,big_residue,tmp,pos,i,offest_num,len_change,storage;
storage = 8192;
if(begin >= 8192)
{
big_untidy_need = 8192 - (begin%8192);
}
else
{
big_untidy_need = 8192 - begin;
}
offest_num = 16 - (begin % 16);
if(big_untidy_need < len)
{
printf("%d %d %d\n",begin,begin+offest_num,offest_num);
printf("%d %d %d\n",begin+offest_num,begin+big_untidy_need,big_untidy_need-offest_num);
tmp = begin+big_untidy_need;
len_change = len - big_untidy_need; //补齐8192后判断剩余的len是否大于8192;
if(len_change >= 8192)
{
m = len_change / 8192;
n = (len_change - 8192 * m) / 16;
big_residue = len_change - (8192 * m +16 *n);
for(i=0;i < m;i++)
{
pos = tmp;
pos += 8192;
printf("%d %d %d\n",tmp,pos,storage);
tmp = pos;
}
printf("%d %d %d\n",pos,pos+n*16,n*16);
printf("%d %d %d\n",pos+n * 16,pos+n * 16+big_residue,big_residue);
}
else if(len > 16)
{
n = len_change / 16;
big_residue = len_change - 16*n;
printf("%d %d %d\n",begin+offest_num,begin+offest_num+ n*16,n*16);
printf("%d %d %d\n",begin+offest_num+ n*16,begin+offest_num+ n*16+big_residue,big_residue);
}
else
{
printf("%d %d %d\n",begin,begin+len,len);
}
}
else if(big_untidy_need > 16)
{
printf("%d %d %d\n",begin,begin+offest_num,offest_num);
n = (len - offest_num)/16;
big_residue = len - n*16-offest_num;
printf("%d %d %d\n",begin+offest_num,begin+offest_num+n*16,n*16);
printf("%d %d %d\n",begin+offest_num+n*16,begin+offest_num+n*16+big_residue,big_residue);
}
else
{
printf("%d %d %d\n",begin,begin+len,len);
}
}
int main()
{
int begin,length;
printf("please input two number:\n");
scanf("%d%d",&begin,&length);
if(is_division(begin))
{
printf("the begin bigger 8192 and is tidy\n");
deal_big_tidy(begin,length);
}
else
{
printf("the begin is bigger 8192 and is not tidy\n");
deal_big_untidy(begin,length);
}
return 0;
}
要实现这个小功能,必须屡清楚思路,我简单的画草图理解下这几种情况:
1 起始位置能被16整除,且小于8192
比较要补齐8192所缺IO大小big_tidy_need 和 总IO大小len
a. big_tidy_need > len
b. big_tidy_need > 16
c. big_tidy_need < 16
2 起始位置能被16整除,且大于8192
(内部逻辑同上)
3 起始位置不能被16整除,且小于8192;
(同上);
4 起始位置不能被16整除,且大于8192;
(同上)
总结:不论是否是16整数倍,只要len大于需要补齐的big_tidy_need,就先填满再一次分割,否则,再big_tidy_need内部一次分割。
上面的代码虽然能够实现功能,但不够精简,不够健壮,于是,又写了另一个版本。#include
int offset_tail_16(int lba)
{
return (((lba>>4)<<4)+16-lba);
}
int offset_tail_8192(int lba)
{
return (((lba>>13)<<13)+8192-lba);
}
int floor_16(int size)
{
return ((size>>4)<<4);
}
#define SUWEI_MIN(a,b) ((a>b?b:a))
int main()
{
#define SUWEI_16 16
#define SUWEI_8192 8192
int begin, length;
int tmp_start, tmp_len=0;
int remain_size;
int cmd_id = 0;
printf("please input two number:\n");
scanf("%d%d", &begin, &length);
tmp_start = begin;
remain_size = length;
while(remain_size>0)
{
if(tmp_start%SUWEI_16)
{
tmp_len= SUWEI_MIN(remain_size, offset_tail_16(tmp_start));
}
else if(tmp_start%SUWEI_8192)
{
if(remain_size >= offset_tail_8192(tmp_start))
{
tmp_len= offset_tail_8192(tmp_start);
}
else if(remain_size >= offset_tail_16(tmp_start))
{
tmp_len= floor_16(remain_size);
}
else
{
tmp_len= remain_size;
}
}
else
{
if(remain_size >= SUWEI_8192)
{
tmp_len= SUWEI_8192;
}
else if(remain_size < SUWEI_16)
{
tmp_len= remain_size;
}
else
{
tmp_len= floor_16(remain_size);
}
}
printf("CMD%d : Start=%d, len=%d\n", cmd_id++, tmp_start, tmp_len);
remain_size -= tmp_len;
tmp_start += tmp_len;
}
printf("DONE!!!\n");
return 0;
}