說明
- 程式碼僅供參考實現方式
- 實際過程中
PHP
如果需要用到布隆過濾器還是得依賴於 Redis
布隆過濾器擴充套件 - 畢竟PHP並非常駐記憶體的應用程式,儲存在
BitSet表
裡面的資料當程式結束後會丟失
程式碼實現
<?php
class BitSet {
protected $bit = [];
public function add($index) {
$this->bit[$index] = 1;
}
public function has($index) {
if(isset($this->bit[$index])) {
return true;
}
return false;
}
}
class HashFunction
{
protected $size;
protected $seed;
public function __construct($size, $seed)
{
$this->size = $size;
$this->seed = $seed;
}
public function hash($value)
{
$r = 0;
$l = strlen($value);
for ($i = 0; $i < $l; $i++) {
$r = $this->seed * $r + ord($value[$i]);
}
return ($this->size - 1) & $r;
}
}
class BloomFilter
{
protected $size = 256 << 22;
protected $seeds = [3, 5, 7, 11, 13, 31, 37, 61];
protected $functions = [];
protected $bitset = [];
public function __construct($size = null, $seeds = null)
{
if($seeds != null) {
$this->size = $size;
}
if($seeds != null) {
$this->seeds = $seeds;
}
foreach ($this->seeds as $v) {
$this->functions[$v] = new HashFunction($this->size, $v);
$this->bitset[$v] = new BitSet();
}
}
public function add($str) {
if($str != null) {
foreach ($this->functions as $k => $fun) {
$this->bitset[$k]->add($fun->hash($str));
}
}
}
public function has($str) {
if($str != null) {
foreach ($this->functions as $k => $fun) {
if(!$this->bitset[$k]->has($fun->hash($str))) {
return false;
}
}
return true;
}
return false;
}
}
function d($str) {
if(is_array($str)) {
echo "[Array]:\n";
print_r($str);
echo "\n";
} else if(is_object($str)) {
echo "[Object]:\n";
print_r($str);
echo "\n";
} else if(is_bool($str)) {
echo "[Boolean]: " . ($str ? "true" : "false") . "\n";
} else {
echo "[String]: " . $str . "\n";
}
}
d("初始化布隆過濾器");
$f = new BloomFilter;
$l1 = 10000;
$l2 = 10;
d("新增初始資料");
for ($i = 0; $i < $l1; $i ++) {
$f->add("#" . $i);
}
d("測試判斷隨機數 {$l2}個");
for ($i = 0; $i < $l2; $i ++) {
$s = "#" . rand(0, $l1 * 2);
$r = $f->has($s);
d("判斷數字 {$s} >> " . ($r ? "true" : "false"));
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結