IO分割

昨天写了一个小程序,具体功能是实现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<stdio.h>
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

起始位置能被16整除,且大于8192

         (内部逻辑同上)

起始位置不能被16整除,且小于8192

(同上);

起始位置不能被16整除,且大于8192

(同上)   

总结:不论是否是16整数倍,只要len大于需要补齐的big_tidy_need,就先填满再一次分割,否则,再big_tidy_need内部一次分割。

上面的代码虽然能够实现功能,但不够精简,不够健壮,于是,又写了另一个版本。

#include<stdio.h>

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;
}







猜你喜欢

转载自blog.csdn.net/Agoni_xiao/article/details/78410025