首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

golang之路-bit地图 实现

2013-02-24 
golang之路--bitmap 实现介绍一下bitmap的思想:?情景1:有些时候我们为了判断一个某个元素是否存在一个集合

golang之路--bitmap 实现

介绍一下bitmap的思想:

?

情景1:

有些时候我们为了判断一个某个元素是否存在一个集合中,普通的方式是map[int]xxxx存储。数据量小的时候还可以

待数据量庞大的时候,比如我们判断某人的momoid是否在某个Momoid切片中,存储就悲剧了。算一下:

一个int = 4byte ?倘若存储500W个数据 4 * 500 * 1000 ?/ 1024 /1024 = 2G的存储,怎么办放弃吧…

?

改进:

对于这种数字形式存在性问题上完全可以用bit的0,1来确定数字的存在。那么之前的一个int = 32bit 只能存储 1种状态

现在可以存储 32X ?个数字状态。瞬间 存储空间降低额32倍。

?

算法:

设定 : int ?为 32 bit ????

?int[] bitmap ?

1.给定一个整数计算其归属的数组下标,因为是 0 - 31 ,32 - 63 ….为一个整数 很显然下标计算就是

?

??????idx = momoid ?/ 32 = momoid >> 5?

?

2,设置改下标 bitmap[ idx ] 对应整数的位标识,很显然,只要对 momoid 对 32 取余即可得到状态位下标

?

bitIdx = momoid % 32 ?

?

3. 设置该数的状态, 只要将1<< bitidx 位 再与bitmap[idx] 值求或就可完成

?

bitmap[idx] = bitmap[idx] | ( 1 << bitidx)

?

状态位,删除、判断存在性与否 不再赘述了。

?

?

好处:

省空间、查询方便

?

用途:

准备在附近列表mongo拆分中用来用户地点更新时,来查询此用户上一次位置属于哪个mongo中,来删除旧记录

旧方案中,得查一次redis获取上一次位置,再判断从属哪个mongo,替换后只要内存查询即可。

?

?

附上实现代码:

?

?

var bitmap []uint32 = make([]uint32, MAX)

?

const (

SHIFT = uint32(5)

MASK ?= 0x1F

MAX ??= 1024 * 1024 * 1024

)

?

/**

* 整数32Bit可表示32个整数是否存在

* 只要将整数除以32既可以得到下标

* 而32位的置位0或1可以直接通过对

* momoid求mod获取对第几位置位

*/

func AddUser(momoid uint32) {

//对32位置位即对momoid进行取mod获得第几位置位

bitmap[momoid>>SHIFT] |= (1 << (momoid & MASK))

}

?

/**?

* 判断是否存在

* 直接取出 第几位判断该位是否为1即可

*/

func ContainUser(momoid uint32) bool {

return (bitmap[momoid>>SHIFT]>>(momoid&MASK))&0x01 == 1

}

?

/**

* 删除用户

* 把momoid % MASK 位数 设置为 0即可

* 方式下:

* ^(momoid % MASK) & bitmap?

*/

func DelUser(momoid uint32) {

bitNum := ^(bitmap[momoid>>SHIFT] & (1 << (momoid & MASK)))

bitmap[momoid>>SHIFT] &= bitNum

}

热点排行