Skip to content

Instantly share code, notes, and snippets.

@ego008
Last active April 27, 2018 11:06
Show Gist options
  • Save ego008/2fa25b704aa47dd38d3fa0b8b6288f5d to your computer and use it in GitHub Desktop.
Save ego008/2fa25b704aa47dd38d3fa0b8b6288f5d to your computer and use it in GitHub Desktop.
Simple bitmap in golang
package main
import (
"bytes"
"fmt"
)
//bitSet实现
type BitSet []uint64
const (
Address_Bits_Per_Word uint8 = 6
Words_Per_Size uint64 = 64 //单字64位
)
//创建指定初始化大小的bitSet
func NewBitMap(nbits int) *BitSet {
wordsLen := (nbits - 1) >> Address_Bits_Per_Word
temp := BitSet(make([]uint64, wordsLen+1, wordsLen+1))
return &temp
}
//把指定位置设为true
func (bs *BitSet) Set(bitIndex uint64) {
wIndex := bs.wordIndex(bitIndex)
bs.expandTo(wIndex)
(*bs)[wIndex] |= uint64(0x01) << (bitIndex % Words_Per_Size)
}
//设置指定位置为false
func (bs *BitSet) Clear(bitIndex uint64) {
wIndex := bs.wordIndex(bitIndex)
if wIndex < len(*bs) {
(*bs)[wIndex] &^= uint64(0x01) << (bitIndex % Words_Per_Size)
}
}
//获取指定位置的值
func (bs BitSet) Get(bitIndex uint64) bool {
wIndex := bs.wordIndex(bitIndex)
return (wIndex < len(bs)) && ((bs)[wIndex]&(uint64(0x01)<<(bitIndex%Words_Per_Size)) != 0)
}
//获取某个值的排位
func (bs BitSet) Rank(bitIndex uint64) uint64 {
var rank uint64
var temp uint64
for i := 0; i < len(bs); i++ {
temp = (bs)[i]
for j := 0; j < 64; j++ {
if temp&(uint64(0x01)<<uint64(j)) != 0 {
rank++
}
bitIndex--
if bitIndex == 0 {
return rank
}
}
}
return rank
}
//以二进制串的格式打印bitMap内容
func (bs BitSet) ToString() string {
var temp uint64
strAppend := &bytes.Buffer{}
for i := 0; i < len(bs); i++ {
temp = (bs)[i]
for j := 0; j < 64; j++ {
if temp&(uint64(0x01)<<uint64(j)) != 0 {
strAppend.WriteString("1")
} else {
strAppend.WriteString("0")
}
}
}
fmt.Println("len:", len(strAppend.Bytes()))
return strAppend.String()
}
//定位位置
func (bs BitSet) wordIndex(bitIndex uint64) int {
return int(bitIndex >> Address_Bits_Per_Word)
}
//扩容:每次扩容两倍
func (bs *BitSet) expandTo(wordIndex int) {
wordsRequired := wordIndex + 1
if len(*bs) < wordsRequired {
if wordsRequired < 2*len(*bs) {
wordsRequired = 2 * len(*bs)
}
newCap := make([]uint64, wordsRequired, wordsRequired)
copy(newCap, *bs)
*bs = newCap
}
}
func main() {
bMap := NewBitMap(64)
for i := 100; i < 1025; i++ {
bMap.Set(uint64(i))
}
fmt.Printf("bmap第133个位置:%v \n", bMap.Get(133))
fmt.Printf("bmap第133个的排位:%v \n", bMap.Rank(133))
fmt.Printf("bmap2string:%s \n", bMap.ToString())
fmt.Printf("end:cap=%d,len=%d \n", cap(*bMap), len(*bMap))
}
// 参考 https://play.golang.org/p/tPsib2JNyHq
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment