5百万 uid 白名单 之 PHP Bit地图 处理

WBOY
Release: 2016-06-13 13:04:43
Original
1222 people have browsed it

5百万 uid 白名单 之 PHP Bitmap 处理

近日,有同事说有个 5百万 的白名单处理, 到网上查找 相似案例, 说是有个bitmap的解法,

再次 google ,baidu 无相关 PHP 的解法, 于是自己写了一个:

?

<?php
/* 5百万 uid 白名单 之 PHP Bitmap 处理 
 * author: hushuilong
 * email: hushuilong at gmail dot com
 * */
class Bitmap 
{
	private $handler = NULL;
	private $max = 0;
	public function __construct($file) 
	{
		clearstatcache(true, $file);	
		if(file_exists($file))
			$this->handler = @fopen($file , 'r+') OR die('open bitmap file failed');
		else
			$this->handler = @fopen($file , 'w+') OR die('open bitmap file failed');

		$this->max = file_exists($file) ? (filesize($file) * 8 - 1) : 0;
	}
	public function __destruct() 
	{
		@fclose($this->handler);
	}
	
	private function binary_dump($binary_data)
	{
		return sprintf('%08d',decbin(hexdec(bin2hex($binary_data))));
	}
	
	private function num_check($num)
	{
		($num > -1) OR die('number must be greater than -1');
		($num < 4294967296) or die('number must be less than 4294967296'); // 2^32
		if ($this->max < $num) {
			fseek($this->handler, 0, SEEK_END);
			fwrite($this->handler , str_repeat("\x00",ceil(($num - $this->max)/8))); // fill with 0
			$this->max = ceil($num/8)*8 - 1;
		}		
	}
	
	public function set($num)
	{
		$this->num_check($num);
		fseek($this->handler, floor($num/8), SEEK_SET);
		$bin = fread($this->handler, 1) | pack('C',0x100 >> fmod($num,8)+1); // mark with 1
		
		fseek($this->handler, ftell($this->handler)-1, SEEK_SET); // write a new byte
		fwrite($this->handler, $bin); 
		fflush($this->handler);
	}
	
	public function del($num)
	{
		$this->num_check($num);
		fseek($this->handler, floor($num/8), SEEK_SET);
		$bin = fread($this->handler, 1) & ~pack('C',0x100 >> fmod($num,8)+1); // mark with 0
		
		fseek($this->handler, ftell($this->handler)-1, SEEK_SET); // write a new byte
		fwrite($this->handler, $bin); 
		fflush($this->handler);
	}	
	
	public function find($num)
	{
		if (fseek($this->handler, floor($num/8), SEEK_SET) == -1) return FALSE;
		$bin = fread($this->handler , 1);
		if ($bin === FALSE || strlen($bin) == 0) return FALSE;

		$bin = $bin & pack('C',0x100 >> fmod($num,8)+1);
		if($bin === "\x00") return FALSE;
		return TRUE;
	}
}

$b = new Bitmap('/dev/shm/bitmapdata');

// 设置白名单
$b->set(1); $b->set(3); $b->set(5);
$b->set(7); $b->set(9); $b->set(501);

$uid = 501;
var_dump($b->find($uid)); // 查找白名单

$b->del($uid); // 删除白名单
var_dump($b->find($uid)); // 查找白名单



Copy after login

?

其中 “$b = new Bitmap('/dev/shm/bitmapdata');”? 把文件,放在内存里,增加读写速度

执行结果如下:

hu@xunleiman-desktop:~/web/test/shm$ /bin/sh ./geany_run_script.sh
bool(true)
bool(false)

?

生成的bitmapdata文件 在附件里面:


?

?

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template