bitmap.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright 2019 Yunion
  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. package bitmap
  15. // Uint2IntArray transfer bitmap displayed as n to int array
  16. func Uint2IntArray(n uint32) []int {
  17. return Uint64ToIntArray(uint64(n))
  18. }
  19. // IntArray2Uint transfer int array nums to bitmap number
  20. func IntArray2Uint(nums []int) uint32 {
  21. return uint32(IntArrayToUint64(nums))
  22. }
  23. func Uint64ToIntArray(n uint64) []int {
  24. ret := make([]int, 0, 2)
  25. var i uint = 0
  26. for n != 0 {
  27. if n&(1<<i) != 0 {
  28. n &= uint64(^(1 << i))
  29. ret = append(ret, int(i))
  30. }
  31. i++
  32. }
  33. return ret
  34. }
  35. func IntArrayToUint64(nums []int) uint64 {
  36. var ret uint64 = 0
  37. for _, i := range nums {
  38. ret |= (1 << uint(i))
  39. }
  40. return ret
  41. }
  42. // Determine if int slice a euqals b
  43. func IntSliceEqual(a, b []int) bool {
  44. if len(a) != len(b) {
  45. return false
  46. }
  47. for i := 0; i < len(a); i++ {
  48. if a[i] != b[i] {
  49. return false
  50. }
  51. }
  52. return true
  53. }
  54. type BitMap struct {
  55. bits []byte
  56. size int64
  57. }
  58. func (bm *BitMap) Set(idx int64) {
  59. if idx > bm.size {
  60. return
  61. }
  62. subscript := idx / 8
  63. var pos = uint64(idx % 8)
  64. bm.bits[subscript] = (bm.bits[subscript] | 1<<pos)
  65. }
  66. func (bm *BitMap) Has(idx int64) bool {
  67. if idx > bm.size {
  68. return false
  69. }
  70. subscript := idx / 8
  71. var pos = uint64(idx % 8)
  72. return bm.bits[subscript]&(1<<pos) > 0
  73. }
  74. func (bm *BitMap) Clean(idx int64) {
  75. if idx > bm.size {
  76. return
  77. }
  78. subscript := idx / 8
  79. var pos = uint64(idx % 8)
  80. bm.bits[subscript] &= ^(1 << pos)
  81. }
  82. func NewBitMap(size int64) *BitMap {
  83. bits := make([]byte, (size>>3)+1)
  84. return &BitMap{bits: bits, size: size}
  85. }