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