github.com/matrixorigin/matrixone@v1.2.0/pkg/common/bitmap/bitmap.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package bitmap 16 17 import ( 18 "bytes" 19 "encoding" 20 "fmt" 21 "math/bits" 22 "unsafe" 23 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 ) 26 27 // 28 // In case len is not multiple of 64, many of these code following assumes the trailing 29 // bits of last uint64 are zero. This may well be true in all our usage. So let's 30 // leave as it is for now. 31 // 32 33 type bitmask = uint64 34 35 /* 36 * Array giving the position of the right-most set bit for each possible 37 * byte value. count the right-most position as the 0th bit, and the 38 * left-most the 7th bit. The 0th entry of the array should not be used. 39 * e.g. 2 = 0x10 ==> rightmost_one_pos_8[2] = 1, 3 = 0x11 ==> rightmost_one_pos_8[3] = 0 40 */ 41 var rightmost_one_pos_8 = [256]uint8{ 42 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 43 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 44 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 45 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 46 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 47 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 48 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 49 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 50 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 51 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 52 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 53 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 54 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 55 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 56 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 57 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 58 } 59 60 func (n *Bitmap) InitWith(other *Bitmap) { 61 n.len = other.len 62 n.emptyFlag.Store(other.emptyFlag.Load()) 63 n.data = append([]uint64(nil), other.data...) 64 } 65 66 func (n *Bitmap) InitWithSize(len int64) { 67 n.len = len 68 n.emptyFlag.Store(kEmptyFlagEmpty) 69 n.data = make([]uint64, (len+63)/64) 70 } 71 72 func (n *Bitmap) Clone() *Bitmap { 73 if n == nil { 74 return nil 75 } 76 var ret Bitmap 77 ret.InitWith(n) 78 return &ret 79 } 80 81 func (n *Bitmap) Iterator() Iterator { 82 // When initialization, the itr.i is set to the first rightmost_one position. 83 itr := BitmapIterator{i: 0, bm: n} 84 if first_1_pos, has_next := itr.hasNext(0); has_next { 85 itr.i = first_1_pos 86 itr.has_next = true 87 return &itr 88 } 89 itr.has_next = false 90 return &itr 91 } 92 93 func rightmost_one_pos_64(word uint64) uint64 { 94 // find out the rightmost_one position. 95 // Firstly, use eight bits as a group to quickly determine whether there is a 1 in it. 96 // if not, then rightmost_one exists in next group, add up the distance with result and shift the word 97 // if rightmost_one exists in this group, get the distance directly from a pre-made hash table 98 var result uint64 99 for { 100 if (word & 0xFF) == 0 { 101 word >>= 8 102 result += 8 103 } else { 104 break 105 } 106 } 107 result += uint64(rightmost_one_pos_8[word&255]) 108 return result 109 } 110 111 func (itr *BitmapIterator) hasNext(i uint64) (uint64, bool) { 112 // if the uint64 is 0, move forward to next word 113 // if the uint64 is not 0, then calculate the rightest_one position in a word, add up prev result and return. 114 // when there is 1 in bitmap, return true, otherwise bitmap is empty and return false. 115 // either case loop over words not bits 116 nwords := (itr.bm.len + 63) / 64 117 current_word := i >> 6 118 mask := (^(bitmask)(0)) << (i & 0x3F) // ignore bits check before 119 var result uint64 120 121 for ; current_word < uint64(nwords); current_word++ { 122 word := itr.bm.data[current_word] 123 word &= mask 124 125 if word != 0 { 126 result = rightmost_one_pos_64(word) + current_word*64 127 return result, true 128 } 129 mask = (^(bitmask)(0)) // in subsequent words, consider all bits 130 } 131 return result, false 132 } 133 134 func (itr *BitmapIterator) HasNext() bool { 135 // maintain a bool var to avoid unnecessary calculations. 136 return itr.has_next 137 } 138 139 func (itr *BitmapIterator) PeekNext() uint64 { 140 if itr.has_next { 141 return itr.i 142 } 143 return 0 144 } 145 146 func (itr *BitmapIterator) Next() uint64 { 147 // When a iterator is initialized, the itr.i is set to the first rightmost_one pos. 148 // so current itr.i is a rightmost_one pos, cal the next one pos and return current pos. 149 pos := itr.i 150 if next, has_next := itr.hasNext(itr.i + 1); has_next { // itr.i + 1 to ignore bits check before 151 itr.i = next 152 itr.has_next = true 153 return pos 154 } 155 itr.has_next = false 156 return pos 157 } 158 159 // Reset set n.data to nil 160 func (n *Bitmap) Reset() { 161 n.len = 0 162 n.emptyFlag.Store(kEmptyFlagEmpty) 163 n.data = nil 164 } 165 166 // Len returns the number of bits in the Bitmap. 167 func (n *Bitmap) Len() int64 { 168 return n.len 169 } 170 171 // Size return number of bytes in n.data 172 // XXX WTF Note that this size is not the same as InitWithSize. 173 func (n *Bitmap) Size() int { 174 return len(n.data) * 8 175 } 176 177 func (n *Bitmap) Ptr() *uint64 { 178 if n == nil || len(n.data) == 0 { 179 return nil 180 } 181 return &n.data[0] 182 } 183 184 // EmptyByFlag is a quick and dirty way to check if the bitmap is empty. 185 // If it retruns true, the bitmap is empty. Otherwise, it may or may not be empty. 186 func (n *Bitmap) EmptyByFlag() bool { 187 return n == nil || n.emptyFlag.Load() == kEmptyFlagEmpty || len(n.data) == 0 188 } 189 190 // IsEmpty returns true if no bit in the Bitmap is set, otherwise it will return false. 191 func (n *Bitmap) IsEmpty() bool { 192 flag := n.emptyFlag.Load() 193 if flag == kEmptyFlagEmpty { 194 return true 195 } else if flag == kEmptyFlagNotEmpty { 196 return false 197 } 198 for i := 0; i < len(n.data); i++ { 199 if n.data[i] != 0 { 200 n.emptyFlag.Store(kEmptyFlagNotEmpty) 201 return false 202 } 203 } 204 n.emptyFlag.Store(kEmptyFlagEmpty) 205 return true 206 } 207 208 // We always assume that bitmap has been extended to at least row. 209 func (n *Bitmap) Add(row uint64) { 210 n.data[row>>6] |= 1 << (row & 0x3F) 211 n.emptyFlag.Store(kEmptyFlagNotEmpty) 212 } 213 214 func (n *Bitmap) AddMany(rows []uint64) { 215 for _, row := range rows { 216 n.data[row>>6] |= 1 << (row & 0x3F) 217 } 218 n.emptyFlag.Store(kEmptyFlagNotEmpty) 219 } 220 221 func (n *Bitmap) Remove(row uint64) { 222 if row >= uint64(n.len) { 223 return 224 } 225 n.data[row>>6] &^= (uint64(1) << (row & 0x3F)) 226 n.emptyFlag.CompareAndSwap(kEmptyFlagNotEmpty, kEmptyFlagUnknown) 227 } 228 229 // Contains returns true if the row is contained in the Bitmap 230 func (n *Bitmap) Contains(row uint64) bool { 231 if row >= uint64(n.len) { 232 return false 233 } 234 idx := row >> 6 235 return (n.data[idx] & (1 << (row & 0x3F))) != 0 236 } 237 238 func (n *Bitmap) AddRange(start, end uint64) { 239 if start >= end { 240 return 241 } 242 i, j := start>>6, (end-1)>>6 243 if i == j { 244 n.data[i] |= (^uint64(0) << uint(start&0x3F)) & (^uint64(0) >> (uint(-end) & 0x3F)) 245 n.emptyFlag.Store(kEmptyFlagNotEmpty) 246 return 247 } 248 n.data[i] |= (^uint64(0) << uint(start&0x3F)) 249 for k := i + 1; k < j; k++ { 250 n.data[k] = ^uint64(0) 251 } 252 n.data[j] |= (^uint64(0) >> (uint(-end) & 0x3F)) 253 254 n.emptyFlag.Store(kEmptyFlagNotEmpty) 255 } 256 257 func (n *Bitmap) RemoveRange(start, end uint64) { 258 if end > uint64(n.len) { 259 end = uint64(n.len) 260 } 261 if start >= end { 262 return 263 } 264 i, j := start>>6, (end-1)>>6 265 if i == j { 266 n.data[i] &= ^((^uint64(0) << uint(start&0x3F)) & (^uint64(0) >> (uint(-end) % 0x3F))) 267 n.emptyFlag.CompareAndSwap(kEmptyFlagNotEmpty, kEmptyFlagUnknown) 268 return 269 } 270 n.data[i] &= ^(^uint64(0) << uint(start&0x3F)) 271 for k := i + 1; k < j; k++ { 272 n.data[k] = 0 273 } 274 n.data[j] &= ^(^uint64(0) >> (uint(-end) & 0x3F)) 275 n.emptyFlag.CompareAndSwap(kEmptyFlagNotEmpty, kEmptyFlagUnknown) 276 } 277 278 func (n *Bitmap) IsSame(m *Bitmap) bool { 279 //if n.len != m.len || 280 if len(m.data) != len(n.data) { 281 return false 282 } 283 for i := 0; i < len(n.data); i++ { 284 if n.data[i] != m.data[i] { 285 return false 286 } 287 } 288 return true 289 } 290 291 func (n *Bitmap) Or(m *Bitmap) { 292 n.TryExpand(m) 293 size := (int(m.len) + 63) / 64 294 for i := 0; i < size; i++ { 295 n.data[i] |= m.data[i] 296 } 297 n.emptyFlag.CompareAndSwap(kEmptyFlagEmpty, kEmptyFlagUnknown) 298 } 299 300 func (n *Bitmap) And(m *Bitmap) { 301 n.TryExpand(m) 302 size := (int(m.len) + 63) / 64 303 for i := 0; i < size; i++ { 304 n.data[i] &= m.data[i] 305 } 306 for i := size; i < len(n.data); i++ { 307 n.data[i] = 0 308 } 309 n.emptyFlag.CompareAndSwap(kEmptyFlagNotEmpty, kEmptyFlagUnknown) 310 } 311 312 func (n *Bitmap) Negate() { 313 nBlock, nTail := int(n.len)/64, int(n.len)%64 314 for i := 0; i < nBlock; i++ { 315 n.data[i] = ^n.data[i] 316 } 317 if nTail > 0 { 318 mask := (uint64(1) << nTail) - 1 319 n.data[nBlock] ^= mask 320 } 321 } 322 323 func (n *Bitmap) TryExpand(m *Bitmap) { 324 n.TryExpandWithSize(int(m.len)) 325 } 326 327 func (n *Bitmap) TryExpandWithSize(size int) { 328 if int(n.len) >= size { 329 return 330 } 331 newCap := (size + 63) / 64 332 n.len = int64(size) 333 if newCap > cap(n.data) { 334 data := make([]uint64, newCap) 335 copy(data, n.data) 336 n.data = data 337 return 338 } 339 if len(n.data) < newCap { 340 n.data = n.data[:newCap] 341 } 342 } 343 344 func (n *Bitmap) Filter(sels []int64) *Bitmap { 345 var m Bitmap 346 m.InitWithSize(n.len) 347 for i, sel := range sels { 348 if n.Contains(uint64(sel)) { 349 m.Add(uint64(i)) 350 } 351 } 352 return &m 353 } 354 355 func (n *Bitmap) Count() int { 356 var cnt int 357 if n.emptyFlag.Load() == kEmptyFlagEmpty { //must be empty 358 return 0 359 } 360 for i := int64(0); i < n.len/64; i++ { 361 cnt += bits.OnesCount64(n.data[i]) 362 } 363 if offset := n.len % 64; offset > 0 { 364 start := (n.len / 64) * 64 365 for i, j := start, start+offset; i < j; i++ { 366 if n.Contains(uint64(i)) { 367 cnt++ 368 } 369 } 370 } 371 if cnt > 0 { 372 n.emptyFlag.Store(kEmptyFlagNotEmpty) 373 } else { 374 n.emptyFlag.Store(kEmptyFlagEmpty) 375 } 376 return cnt 377 } 378 379 func (n *Bitmap) ToArray() []uint64 { 380 var rows []uint64 381 if n.EmptyByFlag() { 382 return rows 383 } 384 385 itr := n.Iterator() 386 for itr.HasNext() { 387 r := itr.Next() 388 rows = append(rows, r) 389 } 390 return rows 391 } 392 393 func (n *Bitmap) ToI64Arrary() []int64 { 394 var rows []int64 395 if n.EmptyByFlag() { 396 return rows 397 } 398 399 itr := n.Iterator() 400 for itr.HasNext() { 401 r := itr.Next() 402 rows = append(rows, int64(r)) 403 } 404 return rows 405 } 406 407 func (n *Bitmap) Marshal() []byte { 408 var buf bytes.Buffer 409 flag := n.emptyFlag.Load() 410 u1 := uint64(n.len) 411 u2 := uint64(len(n.data) * 8) 412 buf.Write(types.EncodeInt32(&flag)) 413 buf.Write(types.EncodeUint64(&u1)) 414 buf.Write(types.EncodeUint64(&u2)) 415 buf.Write(types.EncodeSlice(n.data)) 416 return buf.Bytes() 417 } 418 419 func (n *Bitmap) Unmarshal(data []byte) { 420 n.emptyFlag.Store(types.DecodeInt32(data[:4])) 421 data = data[4:] 422 n.len = int64(types.DecodeUint64(data[:8])) 423 data = data[8:] 424 size := int(types.DecodeUint64(data[:8])) 425 data = data[8:] 426 if size == 0 { 427 n.data = nil 428 } else { 429 n.data = types.DecodeSlice[uint64](data[:size]) 430 } 431 } 432 433 func (n *Bitmap) UnmarshalNoCopy(data []byte) { 434 n.emptyFlag.Store(types.DecodeInt32(data[:4])) 435 data = data[4:] 436 n.len = int64(types.DecodeUint64(data[:8])) 437 data = data[8:] 438 size := int(types.DecodeUint64(data[:8])) 439 data = data[8:] 440 if size == 0 { 441 n.data = nil 442 } else { 443 n.data = unsafe.Slice((*uint64)(unsafe.Pointer(&data[0])), size/8) 444 } 445 } 446 447 func (n *Bitmap) String() string { 448 return fmt.Sprintf("%v", n.ToArray()) 449 } 450 451 var _ encoding.BinaryMarshaler = new(Bitmap) 452 453 func (n *Bitmap) MarshalBinary() ([]byte, error) { 454 return n.Marshal(), nil 455 } 456 457 var _ encoding.BinaryUnmarshaler = new(Bitmap) 458 459 func (n *Bitmap) UnmarshalBinary(data []byte) error { 460 n.Unmarshal(data) 461 return nil 462 }