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.

315 lines
6.4 KiB

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