You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
5.2 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package common
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "strings"
  6. "sync"
  7. )
  8. type BitArray struct {
  9. mtx sync.Mutex
  10. Bits uint `json:"bits"` // NOTE: persisted via reflect, must be exported
  11. Elems []uint64 `json:"elems"` // NOTE: persisted via reflect, must be exported
  12. }
  13. func NewBitArray(bits uint) *BitArray {
  14. return &BitArray{
  15. Bits: bits,
  16. Elems: make([]uint64, (bits+63)/64),
  17. }
  18. }
  19. func (bA *BitArray) Size() uint {
  20. if bA == nil {
  21. return 0
  22. }
  23. return bA.Bits
  24. }
  25. // NOTE: behavior is undefined if i >= bA.Bits
  26. func (bA *BitArray) GetIndex(i uint) bool {
  27. if bA == nil {
  28. return false
  29. }
  30. bA.mtx.Lock()
  31. defer bA.mtx.Unlock()
  32. return bA.getIndex(i)
  33. }
  34. func (bA *BitArray) getIndex(i uint) bool {
  35. if i >= bA.Bits {
  36. return false
  37. }
  38. return bA.Elems[i/64]&(uint64(1)<<(i%64)) > 0
  39. }
  40. // NOTE: behavior is undefined if i >= bA.Bits
  41. func (bA *BitArray) SetIndex(i uint, v bool) bool {
  42. if bA == nil {
  43. return false
  44. }
  45. bA.mtx.Lock()
  46. defer bA.mtx.Unlock()
  47. return bA.setIndex(i, v)
  48. }
  49. func (bA *BitArray) setIndex(i uint, v bool) bool {
  50. if i >= bA.Bits {
  51. return false
  52. }
  53. if v {
  54. bA.Elems[i/64] |= (uint64(1) << (i % 64))
  55. } else {
  56. bA.Elems[i/64] &= ^(uint64(1) << (i % 64))
  57. }
  58. return true
  59. }
  60. func (bA *BitArray) Copy() *BitArray {
  61. if bA == nil {
  62. return nil
  63. }
  64. bA.mtx.Lock()
  65. defer bA.mtx.Unlock()
  66. return bA.copy()
  67. }
  68. func (bA *BitArray) copy() *BitArray {
  69. c := make([]uint64, len(bA.Elems))
  70. copy(c, bA.Elems)
  71. return &BitArray{
  72. Bits: bA.Bits,
  73. Elems: c,
  74. }
  75. }
  76. func (bA *BitArray) copyBits(bits uint) *BitArray {
  77. c := make([]uint64, (bits+63)/64)
  78. copy(c, bA.Elems)
  79. return &BitArray{
  80. Bits: bits,
  81. Elems: c,
  82. }
  83. }
  84. // Returns a BitArray of larger bits size.
  85. func (bA *BitArray) Or(o *BitArray) *BitArray {
  86. if bA == nil {
  87. o.Copy()
  88. }
  89. bA.mtx.Lock()
  90. defer bA.mtx.Unlock()
  91. c := bA.copyBits(MaxUint(bA.Bits, o.Bits))
  92. for i := 0; i < len(c.Elems); i++ {
  93. c.Elems[i] |= o.Elems[i]
  94. }
  95. return c
  96. }
  97. // Returns a BitArray of smaller bit size.
  98. func (bA *BitArray) And(o *BitArray) *BitArray {
  99. if bA == nil {
  100. return nil
  101. }
  102. bA.mtx.Lock()
  103. defer bA.mtx.Unlock()
  104. return bA.and(o)
  105. }
  106. func (bA *BitArray) and(o *BitArray) *BitArray {
  107. c := bA.copyBits(MinUint(bA.Bits, o.Bits))
  108. for i := 0; i < len(c.Elems); i++ {
  109. c.Elems[i] &= o.Elems[i]
  110. }
  111. return c
  112. }
  113. func (bA *BitArray) Not() *BitArray {
  114. if bA == nil {
  115. return nil // Degenerate
  116. }
  117. bA.mtx.Lock()
  118. defer bA.mtx.Unlock()
  119. c := bA.copy()
  120. for i := 0; i < len(c.Elems); i++ {
  121. c.Elems[i] = ^c.Elems[i]
  122. }
  123. return c
  124. }
  125. func (bA *BitArray) Sub(o *BitArray) *BitArray {
  126. if bA == nil {
  127. return nil
  128. }
  129. bA.mtx.Lock()
  130. defer bA.mtx.Unlock()
  131. if bA.Bits > o.Bits {
  132. c := bA.copy()
  133. for i := 0; i < len(o.Elems)-1; i++ {
  134. c.Elems[i] &= ^c.Elems[i]
  135. }
  136. i := uint(len(o.Elems) - 1)
  137. if i >= 0 {
  138. for idx := i * 64; idx < o.Bits; idx++ {
  139. c.setIndex(idx, c.getIndex(idx) && !o.GetIndex(idx))
  140. }
  141. }
  142. return c
  143. } else {
  144. return bA.and(o.Not()) // Note degenerate case where o == nil
  145. }
  146. }
  147. func (bA *BitArray) IsFull() bool {
  148. if bA == nil {
  149. return true
  150. }
  151. bA.mtx.Lock()
  152. defer bA.mtx.Unlock()
  153. if bA.Bits == 0 {
  154. return false
  155. }
  156. // Check all elements except the last
  157. for _, elem := range bA.Elems[:len(bA.Elems)-1] {
  158. if (^elem) != 0 {
  159. return false
  160. }
  161. }
  162. // Check that the last element has (lastElemBits) 1's
  163. lastElemBits := (bA.Bits+63)%64 + 1
  164. lastElem := bA.Elems[len(bA.Elems)-1]
  165. return (lastElem+1)&((uint64(1)<<lastElemBits)-1) == 0
  166. }
  167. func (bA *BitArray) PickRandom() (uint, bool) {
  168. if bA == nil {
  169. return 0, false
  170. }
  171. bA.mtx.Lock()
  172. defer bA.mtx.Unlock()
  173. length := len(bA.Elems)
  174. if length == 0 {
  175. return 0, false
  176. }
  177. randElemStart := rand.Intn(length)
  178. for i := 0; i < length; i++ {
  179. elemIdx := ((i + randElemStart) % length)
  180. if elemIdx < length-1 {
  181. if bA.Elems[elemIdx] > 0 {
  182. randBitStart := rand.Intn(64)
  183. for j := 0; j < 64; j++ {
  184. bitIdx := ((j + randBitStart) % 64)
  185. if (bA.Elems[elemIdx] & (uint64(1) << uint(bitIdx))) > 0 {
  186. return 64*uint(elemIdx) + uint(bitIdx), true
  187. }
  188. }
  189. panic("should not happen")
  190. }
  191. } else {
  192. // Special case for last elem, to ignore straggler bits
  193. elemBits := int(bA.Bits) % 64
  194. if elemBits == 0 {
  195. elemBits = 64
  196. }
  197. randBitStart := rand.Intn(elemBits)
  198. for j := 0; j < elemBits; j++ {
  199. bitIdx := ((j + randBitStart) % elemBits)
  200. if (bA.Elems[elemIdx] & (uint64(1) << uint(bitIdx))) > 0 {
  201. return 64*uint(elemIdx) + uint(bitIdx), true
  202. }
  203. }
  204. }
  205. }
  206. return 0, false
  207. }
  208. func (bA *BitArray) String() string {
  209. if bA == nil {
  210. return "nil-BitArray"
  211. }
  212. bA.mtx.Lock()
  213. defer bA.mtx.Unlock()
  214. return bA.stringIndented("")
  215. }
  216. func (bA *BitArray) StringIndented(indent string) string {
  217. if bA == nil {
  218. return "nil-BitArray"
  219. }
  220. bA.mtx.Lock()
  221. defer bA.mtx.Unlock()
  222. return bA.stringIndented(indent)
  223. }
  224. func (bA *BitArray) stringIndented(indent string) string {
  225. lines := []string{}
  226. bits := ""
  227. for i := uint(0); i < bA.Bits; i++ {
  228. if bA.getIndex(i) {
  229. bits += "X"
  230. } else {
  231. bits += "_"
  232. }
  233. if i%100 == 99 {
  234. lines = append(lines, bits)
  235. bits = ""
  236. }
  237. if i%10 == 9 {
  238. bits += " "
  239. }
  240. if i%50 == 49 {
  241. bits += " "
  242. }
  243. }
  244. if len(bits) > 0 {
  245. lines = append(lines, bits)
  246. }
  247. return fmt.Sprintf("BA{%v:%v}", bA.Bits, strings.Join(lines, indent))
  248. }