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.

util.go 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. package roaring
  2. import (
  3. "math/rand"
  4. "sort"
  5. )
  6. const (
  7. arrayDefaultMaxSize = 4096 // containers with 4096 or fewer integers should be array containers.
  8. arrayLazyLowerBound = 1024
  9. maxCapacity = 1 << 16
  10. serialCookieNoRunContainer = 12346 // only arrays and bitmaps
  11. invalidCardinality = -1
  12. serialCookie = 12347 // runs, arrays, and bitmaps
  13. noOffsetThreshold = 4
  14. // MaxUint32 is the largest uint32 value.
  15. MaxUint32 = 4294967295
  16. // MaxRange is One more than the maximum allowed bitmap bit index. For use as an upper
  17. // bound for ranges.
  18. MaxRange uint64 = MaxUint32 + 1
  19. // MaxUint16 is the largest 16 bit unsigned int.
  20. // This is the largest value an interval16 can store.
  21. MaxUint16 = 65535
  22. // Compute wordSizeInBytes, the size of a word in bytes.
  23. _m = ^uint64(0)
  24. _logS = _m>>8&1 + _m>>16&1 + _m>>32&1
  25. wordSizeInBytes = 1 << _logS
  26. // other constants used in ctz_generic.go
  27. wordSizeInBits = wordSizeInBytes << 3 // word size in bits
  28. )
  29. const maxWord = 1<<wordSizeInBits - 1
  30. // doesn't apply to runContainers
  31. func getSizeInBytesFromCardinality(card int) int {
  32. if card > arrayDefaultMaxSize {
  33. // bitmapContainer
  34. return maxCapacity / 8
  35. }
  36. // arrayContainer
  37. return 2 * card
  38. }
  39. func fill(arr []uint64, val uint64) {
  40. for i := range arr {
  41. arr[i] = val
  42. }
  43. }
  44. func fillRange(arr []uint64, start, end int, val uint64) {
  45. for i := start; i < end; i++ {
  46. arr[i] = val
  47. }
  48. }
  49. func fillArrayAND(container []uint16, bitmap1, bitmap2 []uint64) {
  50. if len(bitmap1) != len(bitmap2) {
  51. panic("array lengths don't match")
  52. }
  53. // TODO: rewrite in assembly
  54. pos := 0
  55. for k := range bitmap1 {
  56. bitset := bitmap1[k] & bitmap2[k]
  57. for bitset != 0 {
  58. t := bitset & -bitset
  59. container[pos] = uint16((k*64 + int(popcount(t-1))))
  60. pos = pos + 1
  61. bitset ^= t
  62. }
  63. }
  64. }
  65. func fillArrayANDNOT(container []uint16, bitmap1, bitmap2 []uint64) {
  66. if len(bitmap1) != len(bitmap2) {
  67. panic("array lengths don't match")
  68. }
  69. // TODO: rewrite in assembly
  70. pos := 0
  71. for k := range bitmap1 {
  72. bitset := bitmap1[k] &^ bitmap2[k]
  73. for bitset != 0 {
  74. t := bitset & -bitset
  75. container[pos] = uint16((k*64 + int(popcount(t-1))))
  76. pos = pos + 1
  77. bitset ^= t
  78. }
  79. }
  80. }
  81. func fillArrayXOR(container []uint16, bitmap1, bitmap2 []uint64) {
  82. if len(bitmap1) != len(bitmap2) {
  83. panic("array lengths don't match")
  84. }
  85. // TODO: rewrite in assembly
  86. pos := 0
  87. for k := 0; k < len(bitmap1); k++ {
  88. bitset := bitmap1[k] ^ bitmap2[k]
  89. for bitset != 0 {
  90. t := bitset & -bitset
  91. container[pos] = uint16((k*64 + int(popcount(t-1))))
  92. pos = pos + 1
  93. bitset ^= t
  94. }
  95. }
  96. }
  97. func highbits(x uint32) uint16 {
  98. return uint16(x >> 16)
  99. }
  100. func lowbits(x uint32) uint16 {
  101. return uint16(x & maxLowBit)
  102. }
  103. const maxLowBit = 0xFFFF
  104. func flipBitmapRange(bitmap []uint64, start int, end int) {
  105. if start >= end {
  106. return
  107. }
  108. firstword := start / 64
  109. endword := (end - 1) / 64
  110. bitmap[firstword] ^= ^(^uint64(0) << uint(start%64))
  111. for i := firstword; i < endword; i++ {
  112. bitmap[i] = ^bitmap[i]
  113. }
  114. bitmap[endword] ^= ^uint64(0) >> (uint(-end) % 64)
  115. }
  116. func resetBitmapRange(bitmap []uint64, start int, end int) {
  117. if start >= end {
  118. return
  119. }
  120. firstword := start / 64
  121. endword := (end - 1) / 64
  122. if firstword == endword {
  123. bitmap[firstword] &= ^((^uint64(0) << uint(start%64)) & (^uint64(0) >> (uint(-end) % 64)))
  124. return
  125. }
  126. bitmap[firstword] &= ^(^uint64(0) << uint(start%64))
  127. for i := firstword + 1; i < endword; i++ {
  128. bitmap[i] = 0
  129. }
  130. bitmap[endword] &= ^(^uint64(0) >> (uint(-end) % 64))
  131. }
  132. func setBitmapRange(bitmap []uint64, start int, end int) {
  133. if start >= end {
  134. return
  135. }
  136. firstword := start / 64
  137. endword := (end - 1) / 64
  138. if firstword == endword {
  139. bitmap[firstword] |= (^uint64(0) << uint(start%64)) & (^uint64(0) >> (uint(-end) % 64))
  140. return
  141. }
  142. bitmap[firstword] |= ^uint64(0) << uint(start%64)
  143. for i := firstword + 1; i < endword; i++ {
  144. bitmap[i] = ^uint64(0)
  145. }
  146. bitmap[endword] |= ^uint64(0) >> (uint(-end) % 64)
  147. }
  148. func flipBitmapRangeAndCardinalityChange(bitmap []uint64, start int, end int) int {
  149. before := wordCardinalityForBitmapRange(bitmap, start, end)
  150. flipBitmapRange(bitmap, start, end)
  151. after := wordCardinalityForBitmapRange(bitmap, start, end)
  152. return int(after - before)
  153. }
  154. func resetBitmapRangeAndCardinalityChange(bitmap []uint64, start int, end int) int {
  155. before := wordCardinalityForBitmapRange(bitmap, start, end)
  156. resetBitmapRange(bitmap, start, end)
  157. after := wordCardinalityForBitmapRange(bitmap, start, end)
  158. return int(after - before)
  159. }
  160. func setBitmapRangeAndCardinalityChange(bitmap []uint64, start int, end int) int {
  161. before := wordCardinalityForBitmapRange(bitmap, start, end)
  162. setBitmapRange(bitmap, start, end)
  163. after := wordCardinalityForBitmapRange(bitmap, start, end)
  164. return int(after - before)
  165. }
  166. func wordCardinalityForBitmapRange(bitmap []uint64, start int, end int) uint64 {
  167. answer := uint64(0)
  168. if start >= end {
  169. return answer
  170. }
  171. firstword := start / 64
  172. endword := (end - 1) / 64
  173. for i := firstword; i <= endword; i++ {
  174. answer += popcount(bitmap[i])
  175. }
  176. return answer
  177. }
  178. func selectBitPosition(w uint64, j int) int {
  179. seen := 0
  180. // Divide 64bit
  181. part := w & 0xFFFFFFFF
  182. n := popcount(part)
  183. if n <= uint64(j) {
  184. part = w >> 32
  185. seen += 32
  186. j -= int(n)
  187. }
  188. w = part
  189. // Divide 32bit
  190. part = w & 0xFFFF
  191. n = popcount(part)
  192. if n <= uint64(j) {
  193. part = w >> 16
  194. seen += 16
  195. j -= int(n)
  196. }
  197. w = part
  198. // Divide 16bit
  199. part = w & 0xFF
  200. n = popcount(part)
  201. if n <= uint64(j) {
  202. part = w >> 8
  203. seen += 8
  204. j -= int(n)
  205. }
  206. w = part
  207. // Lookup in final byte
  208. var counter uint
  209. for counter = 0; counter < 8; counter++ {
  210. j -= int((w >> counter) & 1)
  211. if j < 0 {
  212. break
  213. }
  214. }
  215. return seen + int(counter)
  216. }
  217. func panicOn(err error) {
  218. if err != nil {
  219. panic(err)
  220. }
  221. }
  222. type ph struct {
  223. orig int
  224. rand int
  225. }
  226. type pha []ph
  227. func (p pha) Len() int { return len(p) }
  228. func (p pha) Less(i, j int) bool { return p[i].rand < p[j].rand }
  229. func (p pha) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  230. func getRandomPermutation(n int) []int {
  231. r := make([]ph, n)
  232. for i := 0; i < n; i++ {
  233. r[i].orig = i
  234. r[i].rand = rand.Intn(1 << 29)
  235. }
  236. sort.Sort(pha(r))
  237. m := make([]int, n)
  238. for i := range m {
  239. m[i] = r[i].orig
  240. }
  241. return m
  242. }
  243. func minOfInt(a, b int) int {
  244. if a < b {
  245. return a
  246. }
  247. return b
  248. }
  249. func maxOfInt(a, b int) int {
  250. if a > b {
  251. return a
  252. }
  253. return b
  254. }
  255. func maxOfUint16(a, b uint16) uint16 {
  256. if a > b {
  257. return a
  258. }
  259. return b
  260. }
  261. func minOfUint16(a, b uint16) uint16 {
  262. if a < b {
  263. return a
  264. }
  265. return b
  266. }