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.

420 lines
9.6 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package bits
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "regexp"
  6. "strings"
  7. "sync"
  8. tmmath "github.com/tendermint/tendermint/libs/math"
  9. tmrand "github.com/tendermint/tendermint/libs/rand"
  10. )
  11. // BitArray is a thread-safe implementation of a bit array.
  12. type BitArray struct {
  13. mtx sync.Mutex
  14. Bits int `json:"bits"` // NOTE: persisted via reflect, must be exported
  15. Elems []uint64 `json:"elems"` // NOTE: persisted via reflect, must be exported
  16. }
  17. // NewBitArray returns a new bit array.
  18. // It returns nil if the number of bits is zero.
  19. func NewBitArray(bits int) *BitArray {
  20. if bits <= 0 {
  21. return nil
  22. }
  23. return &BitArray{
  24. Bits: bits,
  25. Elems: make([]uint64, (bits+63)/64),
  26. }
  27. }
  28. // Size returns the number of bits in the bitarray
  29. func (bA *BitArray) Size() int {
  30. if bA == nil {
  31. return 0
  32. }
  33. return bA.Bits
  34. }
  35. // GetIndex returns the bit at index i within the bit array.
  36. // The behavior is undefined if i >= bA.Bits
  37. func (bA *BitArray) GetIndex(i int) bool {
  38. if bA == nil {
  39. return false
  40. }
  41. bA.mtx.Lock()
  42. defer bA.mtx.Unlock()
  43. return bA.getIndex(i)
  44. }
  45. func (bA *BitArray) getIndex(i int) bool {
  46. if i >= bA.Bits {
  47. return false
  48. }
  49. return bA.Elems[i/64]&(uint64(1)<<uint(i%64)) > 0
  50. }
  51. // SetIndex sets the bit at index i within the bit array.
  52. // The behavior is undefined if i >= bA.Bits
  53. func (bA *BitArray) SetIndex(i int, v bool) bool {
  54. if bA == nil {
  55. return false
  56. }
  57. bA.mtx.Lock()
  58. defer bA.mtx.Unlock()
  59. return bA.setIndex(i, v)
  60. }
  61. func (bA *BitArray) setIndex(i int, v bool) bool {
  62. if i >= bA.Bits {
  63. return false
  64. }
  65. if v {
  66. bA.Elems[i/64] |= (uint64(1) << uint(i%64))
  67. } else {
  68. bA.Elems[i/64] &= ^(uint64(1) << uint(i%64))
  69. }
  70. return true
  71. }
  72. // Copy returns a copy of the provided bit array.
  73. func (bA *BitArray) Copy() *BitArray {
  74. if bA == nil {
  75. return nil
  76. }
  77. bA.mtx.Lock()
  78. defer bA.mtx.Unlock()
  79. return bA.copy()
  80. }
  81. func (bA *BitArray) copy() *BitArray {
  82. c := make([]uint64, len(bA.Elems))
  83. copy(c, bA.Elems)
  84. return &BitArray{
  85. Bits: bA.Bits,
  86. Elems: c,
  87. }
  88. }
  89. func (bA *BitArray) copyBits(bits int) *BitArray {
  90. c := make([]uint64, (bits+63)/64)
  91. copy(c, bA.Elems)
  92. return &BitArray{
  93. Bits: bits,
  94. Elems: c,
  95. }
  96. }
  97. // Or returns a bit array resulting from a bitwise OR of the two bit arrays.
  98. // If the two bit-arrys have different lengths, Or right-pads the smaller of the two bit-arrays with zeroes.
  99. // Thus the size of the return value is the maximum of the two provided bit arrays.
  100. func (bA *BitArray) Or(o *BitArray) *BitArray {
  101. if bA == nil && o == nil {
  102. return nil
  103. }
  104. if bA == nil && o != nil {
  105. return o.Copy()
  106. }
  107. if o == nil {
  108. return bA.Copy()
  109. }
  110. bA.mtx.Lock()
  111. o.mtx.Lock()
  112. c := bA.copyBits(tmmath.MaxInt(bA.Bits, o.Bits))
  113. smaller := tmmath.MinInt(len(bA.Elems), len(o.Elems))
  114. for i := 0; i < smaller; i++ {
  115. c.Elems[i] |= o.Elems[i]
  116. }
  117. bA.mtx.Unlock()
  118. o.mtx.Unlock()
  119. return c
  120. }
  121. // And returns a bit array resulting from a bitwise AND of the two bit arrays.
  122. // If the two bit-arrys have different lengths, this truncates the larger of the two bit-arrays from the right.
  123. // Thus the size of the return value is the minimum of the two provided bit arrays.
  124. func (bA *BitArray) And(o *BitArray) *BitArray {
  125. if bA == nil || o == nil {
  126. return nil
  127. }
  128. bA.mtx.Lock()
  129. o.mtx.Lock()
  130. defer func() {
  131. bA.mtx.Unlock()
  132. o.mtx.Unlock()
  133. }()
  134. return bA.and(o)
  135. }
  136. func (bA *BitArray) and(o *BitArray) *BitArray {
  137. c := bA.copyBits(tmmath.MinInt(bA.Bits, o.Bits))
  138. for i := 0; i < len(c.Elems); i++ {
  139. c.Elems[i] &= o.Elems[i]
  140. }
  141. return c
  142. }
  143. // Not returns a bit array resulting from a bitwise Not of the provided bit array.
  144. func (bA *BitArray) Not() *BitArray {
  145. if bA == nil {
  146. return nil // Degenerate
  147. }
  148. bA.mtx.Lock()
  149. defer bA.mtx.Unlock()
  150. return bA.not()
  151. }
  152. func (bA *BitArray) not() *BitArray {
  153. c := bA.copy()
  154. for i := 0; i < len(c.Elems); i++ {
  155. c.Elems[i] = ^c.Elems[i]
  156. }
  157. return c
  158. }
  159. // Sub subtracts the two bit-arrays bitwise, without carrying the bits.
  160. // Note that carryless subtraction of a - b is (a and not b).
  161. // The output is the same as bA, regardless of o's size.
  162. // If bA is longer than o, o is right padded with zeroes
  163. func (bA *BitArray) Sub(o *BitArray) *BitArray {
  164. if bA == nil || o == nil {
  165. // TODO: Decide if we should do 1's complement here?
  166. return nil
  167. }
  168. bA.mtx.Lock()
  169. o.mtx.Lock()
  170. // output is the same size as bA
  171. c := bA.copyBits(bA.Bits)
  172. // Only iterate to the minimum size between the two.
  173. // If o is longer, those bits are ignored.
  174. // If bA is longer, then skipping those iterations is equivalent
  175. // to right padding with 0's
  176. smaller := tmmath.MinInt(len(bA.Elems), len(o.Elems))
  177. for i := 0; i < smaller; i++ {
  178. // &^ is and not in golang
  179. c.Elems[i] &^= o.Elems[i]
  180. }
  181. bA.mtx.Unlock()
  182. o.mtx.Unlock()
  183. return c
  184. }
  185. // IsEmpty returns true iff all bits in the bit array are 0
  186. func (bA *BitArray) IsEmpty() bool {
  187. if bA == nil {
  188. return true // should this be opposite?
  189. }
  190. bA.mtx.Lock()
  191. defer bA.mtx.Unlock()
  192. for _, e := range bA.Elems {
  193. if e > 0 {
  194. return false
  195. }
  196. }
  197. return true
  198. }
  199. // IsFull returns true iff all bits in the bit array are 1.
  200. func (bA *BitArray) IsFull() bool {
  201. if bA == nil {
  202. return true
  203. }
  204. bA.mtx.Lock()
  205. defer bA.mtx.Unlock()
  206. // Check all elements except the last
  207. for _, elem := range bA.Elems[:len(bA.Elems)-1] {
  208. if (^elem) != 0 {
  209. return false
  210. }
  211. }
  212. // Check that the last element has (lastElemBits) 1's
  213. lastElemBits := (bA.Bits+63)%64 + 1
  214. lastElem := bA.Elems[len(bA.Elems)-1]
  215. return (lastElem+1)&((uint64(1)<<uint(lastElemBits))-1) == 0
  216. }
  217. // PickRandom returns a random index for a set bit in the bit array.
  218. // If there is no such value, it returns 0, false.
  219. // It uses the global randomness in `random.go` to get this index.
  220. func (bA *BitArray) PickRandom() (int, bool) {
  221. if bA == nil {
  222. return 0, false
  223. }
  224. bA.mtx.Lock()
  225. trueIndices := bA.getTrueIndices()
  226. bA.mtx.Unlock()
  227. if len(trueIndices) == 0 { // no bits set to true
  228. return 0, false
  229. }
  230. return trueIndices[tmrand.Intn(len(trueIndices))], true
  231. }
  232. func (bA *BitArray) getTrueIndices() []int {
  233. trueIndices := make([]int, 0, bA.Bits)
  234. curBit := 0
  235. numElems := len(bA.Elems)
  236. // set all true indices
  237. for i := 0; i < numElems-1; i++ {
  238. elem := bA.Elems[i]
  239. if elem == 0 {
  240. curBit += 64
  241. continue
  242. }
  243. for j := 0; j < 64; j++ {
  244. if (elem & (uint64(1) << uint64(j))) > 0 {
  245. trueIndices = append(trueIndices, curBit)
  246. }
  247. curBit++
  248. }
  249. }
  250. // handle last element
  251. lastElem := bA.Elems[numElems-1]
  252. numFinalBits := bA.Bits - curBit
  253. for i := 0; i < numFinalBits; i++ {
  254. if (lastElem & (uint64(1) << uint64(i))) > 0 {
  255. trueIndices = append(trueIndices, curBit)
  256. }
  257. curBit++
  258. }
  259. return trueIndices
  260. }
  261. // String returns a string representation of BitArray: BA{<bit-string>},
  262. // where <bit-string> is a sequence of 'x' (1) and '_' (0).
  263. // The <bit-string> includes spaces and newlines to help people.
  264. // For a simple sequence of 'x' and '_' characters with no spaces or newlines,
  265. // see the MarshalJSON() method.
  266. // Example: "BA{_x_}" or "nil-BitArray" for nil.
  267. func (bA *BitArray) String() string {
  268. return bA.StringIndented("")
  269. }
  270. // StringIndented returns the same thing as String(), but applies the indent
  271. // at every 10th bit, and twice at every 50th bit.
  272. func (bA *BitArray) StringIndented(indent string) string {
  273. if bA == nil {
  274. return "nil-BitArray"
  275. }
  276. bA.mtx.Lock()
  277. defer bA.mtx.Unlock()
  278. return bA.stringIndented(indent)
  279. }
  280. func (bA *BitArray) stringIndented(indent string) string {
  281. lines := []string{}
  282. bits := ""
  283. for i := 0; i < bA.Bits; i++ {
  284. if bA.getIndex(i) {
  285. bits += "x"
  286. } else {
  287. bits += "_"
  288. }
  289. if i%100 == 99 {
  290. lines = append(lines, bits)
  291. bits = ""
  292. }
  293. if i%10 == 9 {
  294. bits += indent
  295. }
  296. if i%50 == 49 {
  297. bits += indent
  298. }
  299. }
  300. if len(bits) > 0 {
  301. lines = append(lines, bits)
  302. }
  303. return fmt.Sprintf("BA{%v:%v}", bA.Bits, strings.Join(lines, indent))
  304. }
  305. // Bytes returns the byte representation of the bits within the bitarray.
  306. func (bA *BitArray) Bytes() []byte {
  307. bA.mtx.Lock()
  308. defer bA.mtx.Unlock()
  309. numBytes := (bA.Bits + 7) / 8
  310. bytes := make([]byte, numBytes)
  311. for i := 0; i < len(bA.Elems); i++ {
  312. elemBytes := [8]byte{}
  313. binary.LittleEndian.PutUint64(elemBytes[:], bA.Elems[i])
  314. copy(bytes[i*8:], elemBytes[:])
  315. }
  316. return bytes
  317. }
  318. // Update sets the bA's bits to be that of the other bit array.
  319. // The copying begins from the begin of both bit arrays.
  320. func (bA *BitArray) Update(o *BitArray) {
  321. if bA == nil || o == nil {
  322. return
  323. }
  324. bA.mtx.Lock()
  325. o.mtx.Lock()
  326. defer func() {
  327. bA.mtx.Unlock()
  328. o.mtx.Unlock()
  329. }()
  330. copy(bA.Elems, o.Elems)
  331. }
  332. // MarshalJSON implements json.Marshaler interface by marshaling bit array
  333. // using a custom format: a string of '-' or 'x' where 'x' denotes the 1 bit.
  334. func (bA *BitArray) MarshalJSON() ([]byte, error) {
  335. if bA == nil {
  336. return []byte("null"), nil
  337. }
  338. bA.mtx.Lock()
  339. defer bA.mtx.Unlock()
  340. bits := `"`
  341. for i := 0; i < bA.Bits; i++ {
  342. if bA.getIndex(i) {
  343. bits += `x`
  344. } else {
  345. bits += `_`
  346. }
  347. }
  348. bits += `"`
  349. return []byte(bits), nil
  350. }
  351. var bitArrayJSONRegexp = regexp.MustCompile(`\A"([_x]*)"\z`)
  352. // UnmarshalJSON implements json.Unmarshaler interface by unmarshaling a custom
  353. // JSON description.
  354. func (bA *BitArray) UnmarshalJSON(bz []byte) error {
  355. b := string(bz)
  356. if b == "null" {
  357. // This is required e.g. for encoding/json when decoding
  358. // into a pointer with pre-allocated BitArray.
  359. bA.Bits = 0
  360. bA.Elems = nil
  361. return nil
  362. }
  363. // Validate 'b'.
  364. match := bitArrayJSONRegexp.FindStringSubmatch(b)
  365. if match == nil {
  366. return fmt.Errorf("bitArray in JSON should be a string of format %q but got %s", bitArrayJSONRegexp.String(), b)
  367. }
  368. bits := match[1]
  369. // Construct new BitArray and copy over.
  370. numBits := len(bits)
  371. bA2 := NewBitArray(numBits)
  372. for i := 0; i < numBits; i++ {
  373. if bits[i] == 'x' {
  374. bA2.SetIndex(i, true)
  375. }
  376. }
  377. *bA = *bA2 //nolint:govet
  378. return nil
  379. }