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.

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