bitmap,统计业务中一个不得不考虑的数据结构
bitmap是什么
php操作bitmap
PHP实现Bitmap的探索 - GMP扩展使用 | Orlion的博客 (fanscore.cn)
redis中的bitmap
php操作redis的bitmap,请自行学习,这里我提一点,redis中的bitmap缺陷:不能存储太大的int
,原因和上面博客中提到的内存浪费示例类似,redis的bitmap会占用太大内存导致redis崩溃。
更多的操作bitmap的方式
php的GMP扩展提供的操作bitmap的方式十分有限,只提供了以下操作方法,远不能满足需求:
- gmp_or — Bitwise OR
- gmp_and — Bitwise AND
- gmp_xor — Bitwise XOR
而且,即便自己基于该扩展去实现各种bitmap操作,比如:交集、并集、差集、对称差集、迭代,也十分麻烦,内存浪费的情况不好处理。
这里我介绍一个高效、通用的bitmap方案:
Roaring Bitmaps
目前Java、Go、Rust、Swift、C、C++,都有实现,它们之间可以互通。
如果有大神给php也搞个这样的C扩展,那简直是给php做出了巨大贡献。
我基于Go版的实现,用进程间通信的方式进行封装得到了一个php版的composer包:php的bitmap操作类,该包封装了大部分的bitmap操作,可堪一用,缺点是进程间通信会牺牲效率,部署的时候还得部署对应的bitmap服务端。
————–分割线—————–
最近用php的ffi方式,重新写了一版:composer require buexplain/roaring,如有需求,请使用这个版本。
示例:
require "vendor/autoload.php";
use Roaring\Bitmap;
//求并集
$a = new Bitmap();
$b = new Bitmap();
$a->addMany([1, 2]);
$b->addMany([2, 3]);
$c = $a->or($b);
print_r($c->toArray()); //[1, 2, 3]
//求交集
$a = new Bitmap();
$b = new Bitmap();
$a->addMany([1, 2, 3]);
$b->addMany([2, 3, 4]);
$c = $a->and($b);
print_r($c->toArray()); //[2, 3]
//求差集
$a = new Bitmap();
$b = new Bitmap();
$a->addMany([1, 2, 3]);
$b->addMany([1, 3, 4]);
$c = $a->andNot($b);
print_r($c->toArray()); //[2]
//求对称差集
$a = new Bitmap();
$b = new Bitmap();
$a->addMany([1, 2, 3]);
$b->addMany([3, 4, 5]);
$c = $a->xOr($b);
print_r($c->toArray()); //[1, 2, 4, 5]
//批量迭代整个bitmap
$a = new Bitmap();
$a->addRange(0, 100);
$generator = $a->iterate(10);
foreach ($generator as $v) {
print_r($v); //每次循环最多获取10个值
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: