发几个这两天的工作成果

PHP程序设计语言和相关项目讨论
Post Reply
User avatar
fanisky
技术组成员
技术组成员
Posts: 510
Joined: 2007-04-15 15:03

发几个这两天的工作成果

Post by fanisky » 2007-07-26 14:04

不好全发出来,因为是公司里用的
这几个函数相当于api,看得懂的就知道大概用法了。

;) 我就不做解释了。有兴趣的可以研究研究。嘿嘿

Code: Select all

function getAddr( $phone, &$seekstart )
{
	$phone = floatval( $phone );
	$hd = substr( $phone, 0, 3 );
	$jumpnum = $phone - $seekstart[$hd][0];
	$jumpbyte = $jumpnum / 8;
	$jumpbyte = intval( $jumpnum / 8 );
	$seekbyte = $jumpnum % 8;
	return array( $jumpbyte+$seekstart[$hd][1], $seekbyte );
}

function initDB( $file, $seekall )
{
	$fp = fopen( $file, 'wb' );
	ftruncate ( $fp, $seekall );
	fclose( $fp );
}

//echo getOne( 255-23, 0 );
function readOne( $byte, $seek )
{
	$byte = $byte >> $seek;
	$byte = $byte & 1;
	return $byte;
}

//echo writeOne( 255-23, 3, 0 );
function writeOne( $byte, $seek, $data )
{
	for( $i=0; $i<=7; $i++ )
	{
		$b[] = readOne( $byte, $i );
	}
	$b[$seek] = $data;
	$byte = $byte & 0;
	for( $i=7; $i>=0; $i-- )
	{
		$byte = $byte << 1;
		$byte = $byte | $b[$i];
	}
	return $byte;
}

function writeFile( $phone, $val, $blackFp, &$seekstart )
{
	$phone = floatval( $phone );
	$addr = getAddr( $phone, $seekstart );
	fseek( $blackFp, $addr[0] );
	$ret = fgetc( $blackFp );
	$ret = ord( $ret );
	$ret = writeOne( $ret, $addr[1], 1 );
	fseek( $blackFp, $addr[0] );
	fwrite( $blackFp, chr( $ret ), 1 );
}


function loadFile( $phone, $blackFp, &$seekstart )
{
	$phone = floatval( $phone );
	$addr = getAddr( $phone, $seekstart );
	fseek( $blackFp, $addr[0] );
	$ret = fgetc( $blackFp );
	$ret = ord( $ret );
	return readOne( $ret, $addr[1] );
}

User avatar
IOsetting
论坛管理员
论坛管理员
Posts: 3645
Joined: 2006-10-17 1:48

Re: 发几个这两天的工作成果

Post by IOsetting » 2007-07-26 19:16

像是用二进制文件来存电话号码? 有点像以前写c下面的存储. 通过左移右移和与来做取值, 太强了 :)

保留做参考...

User avatar
fanisky
技术组成员
技术组成员
Posts: 510
Joined: 2007-04-15 15:03

Re: 发几个这两天的工作成果

Post by fanisky » 2007-07-27 9:18

呵呵,最近要做筛号工作

用数据库筛选黑名单,实在太慢。

就想了这个办法。

240M的文件可以存下20亿个电话号码。

从一个收费的筛号软件上得到的灵感,不过不知道人家软件到底怎么做的。

对这个我算法,我非常满意,很重要的是算法,可以扩展到其他地方用。可以让某些特定应用的索引或者查找比数据库快几十倍。

User avatar
IOsetting
论坛管理员
论坛管理员
Posts: 3645
Joined: 2006-10-17 1:48

Re: 发几个这两天的工作成果

Post by IOsetting » 2007-07-31 20:36

能大概解释一下算法吗? 说实话... 没怎么看懂查找和写入的那几句 :redface:

User avatar
fanisky
技术组成员
技术组成员
Posts: 510
Joined: 2007-04-15 15:03

Re: 发几个这两天的工作成果

Post by fanisky » 2007-08-01 19:35

举个例子
假设该库文件存着所有130号段的号码

库文件的第一个字节是11100001

那么这个字节代表的可以表示4个号码

分别是
13000000000+0
13000000000+1
13000000000+2
13000000000+7

0位表示没有号码,当然0位的号码也是已经固定好的,只是表示没有存这个号码而已

查找每次都是相比定位,二分法也无法和随机定位相比

比如想找下 13000000001 这个号码在不在库里
13000000001-13000000000=1
计算出在字节中的偏移量为1,这样找出11100001这个字节数据的第1位(这里说的第1位其实是第二个1,根据C的思想,起始从0开始),如果第1位是1,那么表示库中有这个电话号码。

以上只是用一个例子简单说下算法,应用中除了字节中位的偏移量,还需要计算字节的偏移量,就是在库文件中的第几个字节,以及自己种的第几位。
每次查找都是随机定位,不需要做任何比较或者索引。

该算法的思想可以应用在所有可以转换成惟一数字编码的数据中。

Post Reply