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.

960 lines
24 KiB

  1. package roaring
  2. import (
  3. "fmt"
  4. )
  5. //go:generate msgp -unexported
  6. type arrayContainer struct {
  7. content []uint16
  8. }
  9. func (ac *arrayContainer) String() string {
  10. s := "{"
  11. for it := ac.getShortIterator(); it.hasNext(); {
  12. s += fmt.Sprintf("%v, ", it.next())
  13. }
  14. return s + "}"
  15. }
  16. func (ac *arrayContainer) fillLeastSignificant16bits(x []uint32, i int, mask uint32) {
  17. for k := 0; k < len(ac.content); k++ {
  18. x[k+i] = uint32(ac.content[k]) | mask
  19. }
  20. }
  21. func (ac *arrayContainer) getShortIterator() shortIterable {
  22. return &shortIterator{ac.content, 0}
  23. }
  24. func (ac *arrayContainer) getManyIterator() manyIterable {
  25. return &manyIterator{ac.content, 0}
  26. }
  27. func (ac *arrayContainer) minimum() uint16 {
  28. return ac.content[0] // assume not empty
  29. }
  30. func (ac *arrayContainer) maximum() uint16 {
  31. return ac.content[len(ac.content)-1] // assume not empty
  32. }
  33. func (ac *arrayContainer) getSizeInBytes() int {
  34. return ac.getCardinality() * 2
  35. }
  36. func (ac *arrayContainer) serializedSizeInBytes() int {
  37. return ac.getCardinality() * 2
  38. }
  39. func arrayContainerSizeInBytes(card int) int {
  40. return card * 2
  41. }
  42. // add the values in the range [firstOfRange,endx)
  43. func (ac *arrayContainer) iaddRange(firstOfRange, endx int) container {
  44. if firstOfRange >= endx {
  45. return ac
  46. }
  47. indexstart := binarySearch(ac.content, uint16(firstOfRange))
  48. if indexstart < 0 {
  49. indexstart = -indexstart - 1
  50. }
  51. indexend := binarySearch(ac.content, uint16(endx-1))
  52. if indexend < 0 {
  53. indexend = -indexend - 1
  54. } else {
  55. indexend++
  56. }
  57. rangelength := endx - firstOfRange
  58. newcardinality := indexstart + (ac.getCardinality() - indexend) + rangelength
  59. if newcardinality > arrayDefaultMaxSize {
  60. a := ac.toBitmapContainer()
  61. return a.iaddRange(firstOfRange, endx)
  62. }
  63. if cap(ac.content) < newcardinality {
  64. tmp := make([]uint16, newcardinality, newcardinality)
  65. copy(tmp[:indexstart], ac.content[:indexstart])
  66. copy(tmp[indexstart+rangelength:], ac.content[indexend:])
  67. ac.content = tmp
  68. } else {
  69. ac.content = ac.content[:newcardinality]
  70. copy(ac.content[indexstart+rangelength:], ac.content[indexend:])
  71. }
  72. for k := 0; k < rangelength; k++ {
  73. ac.content[k+indexstart] = uint16(firstOfRange + k)
  74. }
  75. return ac
  76. }
  77. // remove the values in the range [firstOfRange,endx)
  78. func (ac *arrayContainer) iremoveRange(firstOfRange, endx int) container {
  79. if firstOfRange >= endx {
  80. return ac
  81. }
  82. indexstart := binarySearch(ac.content, uint16(firstOfRange))
  83. if indexstart < 0 {
  84. indexstart = -indexstart - 1
  85. }
  86. indexend := binarySearch(ac.content, uint16(endx-1))
  87. if indexend < 0 {
  88. indexend = -indexend - 1
  89. } else {
  90. indexend++
  91. }
  92. rangelength := indexend - indexstart
  93. answer := ac
  94. copy(answer.content[indexstart:], ac.content[indexstart+rangelength:])
  95. answer.content = answer.content[:ac.getCardinality()-rangelength]
  96. return answer
  97. }
  98. // flip the values in the range [firstOfRange,endx)
  99. func (ac *arrayContainer) not(firstOfRange, endx int) container {
  100. if firstOfRange >= endx {
  101. //p("arrayContainer.not(): exiting early with ac.clone()")
  102. return ac.clone()
  103. }
  104. return ac.notClose(firstOfRange, endx-1) // remove everything in [firstOfRange,endx-1]
  105. }
  106. // flip the values in the range [firstOfRange,lastOfRange]
  107. func (ac *arrayContainer) notClose(firstOfRange, lastOfRange int) container {
  108. if firstOfRange > lastOfRange { // unlike add and remove, not uses an inclusive range [firstOfRange,lastOfRange]
  109. //p("arrayContainer.notClose(): exiting early with ac.clone()")
  110. return ac.clone()
  111. }
  112. // determine the span of array indices to be affected^M
  113. startIndex := binarySearch(ac.content, uint16(firstOfRange))
  114. //p("startIndex=%v", startIndex)
  115. if startIndex < 0 {
  116. startIndex = -startIndex - 1
  117. }
  118. lastIndex := binarySearch(ac.content, uint16(lastOfRange))
  119. //p("lastIndex=%v", lastIndex)
  120. if lastIndex < 0 {
  121. lastIndex = -lastIndex - 2
  122. }
  123. currentValuesInRange := lastIndex - startIndex + 1
  124. spanToBeFlipped := lastOfRange - firstOfRange + 1
  125. newValuesInRange := spanToBeFlipped - currentValuesInRange
  126. cardinalityChange := newValuesInRange - currentValuesInRange
  127. newCardinality := len(ac.content) + cardinalityChange
  128. //p("new card is %v", newCardinality)
  129. if newCardinality > arrayDefaultMaxSize {
  130. //p("new card over arrayDefaultMaxSize, so returning bitmap")
  131. return ac.toBitmapContainer().not(firstOfRange, lastOfRange+1)
  132. }
  133. answer := newArrayContainer()
  134. answer.content = make([]uint16, newCardinality, newCardinality) //a hack for sure
  135. copy(answer.content, ac.content[:startIndex])
  136. outPos := startIndex
  137. inPos := startIndex
  138. valInRange := firstOfRange
  139. for ; valInRange <= lastOfRange && inPos <= lastIndex; valInRange++ {
  140. if uint16(valInRange) != ac.content[inPos] {
  141. answer.content[outPos] = uint16(valInRange)
  142. outPos++
  143. } else {
  144. inPos++
  145. }
  146. }
  147. for ; valInRange <= lastOfRange; valInRange++ {
  148. answer.content[outPos] = uint16(valInRange)
  149. outPos++
  150. }
  151. for i := lastIndex + 1; i < len(ac.content); i++ {
  152. answer.content[outPos] = ac.content[i]
  153. outPos++
  154. }
  155. answer.content = answer.content[:newCardinality]
  156. return answer
  157. }
  158. func (ac *arrayContainer) equals(o container) bool {
  159. srb, ok := o.(*arrayContainer)
  160. if ok {
  161. // Check if the containers are the same object.
  162. if ac == srb {
  163. return true
  164. }
  165. if len(srb.content) != len(ac.content) {
  166. return false
  167. }
  168. for i, v := range ac.content {
  169. if v != srb.content[i] {
  170. return false
  171. }
  172. }
  173. return true
  174. }
  175. // use generic comparison
  176. bCard := o.getCardinality()
  177. aCard := ac.getCardinality()
  178. if bCard != aCard {
  179. return false
  180. }
  181. ait := ac.getShortIterator()
  182. bit := o.getShortIterator()
  183. for ait.hasNext() {
  184. if bit.next() != ait.next() {
  185. return false
  186. }
  187. }
  188. return true
  189. }
  190. func (ac *arrayContainer) toBitmapContainer() *bitmapContainer {
  191. bc := newBitmapContainer()
  192. bc.loadData(ac)
  193. return bc
  194. }
  195. func (ac *arrayContainer) iadd(x uint16) (wasNew bool) {
  196. // Special case adding to the end of the container.
  197. l := len(ac.content)
  198. if l > 0 && l < arrayDefaultMaxSize && ac.content[l-1] < x {
  199. ac.content = append(ac.content, x)
  200. return true
  201. }
  202. loc := binarySearch(ac.content, x)
  203. if loc < 0 {
  204. s := ac.content
  205. i := -loc - 1
  206. s = append(s, 0)
  207. copy(s[i+1:], s[i:])
  208. s[i] = x
  209. ac.content = s
  210. return true
  211. }
  212. return false
  213. }
  214. func (ac *arrayContainer) iaddReturnMinimized(x uint16) container {
  215. // Special case adding to the end of the container.
  216. l := len(ac.content)
  217. if l > 0 && l < arrayDefaultMaxSize && ac.content[l-1] < x {
  218. ac.content = append(ac.content, x)
  219. return ac
  220. }
  221. loc := binarySearch(ac.content, x)
  222. if loc < 0 {
  223. if len(ac.content) >= arrayDefaultMaxSize {
  224. a := ac.toBitmapContainer()
  225. a.iadd(x)
  226. return a
  227. }
  228. s := ac.content
  229. i := -loc - 1
  230. s = append(s, 0)
  231. copy(s[i+1:], s[i:])
  232. s[i] = x
  233. ac.content = s
  234. }
  235. return ac
  236. }
  237. // iremoveReturnMinimized is allowed to change the return type to minimize storage.
  238. func (ac *arrayContainer) iremoveReturnMinimized(x uint16) container {
  239. ac.iremove(x)
  240. return ac
  241. }
  242. func (ac *arrayContainer) iremove(x uint16) bool {
  243. loc := binarySearch(ac.content, x)
  244. if loc >= 0 {
  245. s := ac.content
  246. s = append(s[:loc], s[loc+1:]...)
  247. ac.content = s
  248. return true
  249. }
  250. return false
  251. }
  252. func (ac *arrayContainer) remove(x uint16) container {
  253. out := &arrayContainer{make([]uint16, len(ac.content))}
  254. copy(out.content, ac.content[:])
  255. loc := binarySearch(out.content, x)
  256. if loc >= 0 {
  257. s := out.content
  258. s = append(s[:loc], s[loc+1:]...)
  259. out.content = s
  260. }
  261. return out
  262. }
  263. func (ac *arrayContainer) or(a container) container {
  264. switch x := a.(type) {
  265. case *arrayContainer:
  266. return ac.orArray(x)
  267. case *bitmapContainer:
  268. return x.orArray(ac)
  269. case *runContainer16:
  270. if x.isFull() {
  271. return x.clone()
  272. }
  273. return x.orArray(ac)
  274. }
  275. panic("unsupported container type")
  276. }
  277. func (ac *arrayContainer) orCardinality(a container) int {
  278. switch x := a.(type) {
  279. case *arrayContainer:
  280. return ac.orArrayCardinality(x)
  281. case *bitmapContainer:
  282. return x.orArrayCardinality(ac)
  283. case *runContainer16:
  284. return x.orArrayCardinality(ac)
  285. }
  286. panic("unsupported container type")
  287. }
  288. func (ac *arrayContainer) ior(a container) container {
  289. switch x := a.(type) {
  290. case *arrayContainer:
  291. return ac.iorArray(x)
  292. case *bitmapContainer:
  293. return a.(*bitmapContainer).orArray(ac)
  294. //return ac.iorBitmap(x) // note: this does not make sense
  295. case *runContainer16:
  296. if x.isFull() {
  297. return x.clone()
  298. }
  299. return ac.iorRun16(x)
  300. }
  301. panic("unsupported container type")
  302. }
  303. func (ac *arrayContainer) iorArray(value2 *arrayContainer) container {
  304. value1 := ac
  305. len1 := value1.getCardinality()
  306. len2 := value2.getCardinality()
  307. maxPossibleCardinality := len1 + len2
  308. if maxPossibleCardinality > arrayDefaultMaxSize { // it could be a bitmap!
  309. bc := newBitmapContainer()
  310. for k := 0; k < len(value2.content); k++ {
  311. v := value2.content[k]
  312. i := uint(v) >> 6
  313. mask := uint64(1) << (v % 64)
  314. bc.bitmap[i] |= mask
  315. }
  316. for k := 0; k < len(ac.content); k++ {
  317. v := ac.content[k]
  318. i := uint(v) >> 6
  319. mask := uint64(1) << (v % 64)
  320. bc.bitmap[i] |= mask
  321. }
  322. bc.cardinality = int(popcntSlice(bc.bitmap))
  323. if bc.cardinality <= arrayDefaultMaxSize {
  324. return bc.toArrayContainer()
  325. }
  326. return bc
  327. }
  328. if maxPossibleCardinality > cap(value1.content) {
  329. newcontent := make([]uint16, 0, maxPossibleCardinality)
  330. copy(newcontent[len2:maxPossibleCardinality], ac.content[0:len1])
  331. ac.content = newcontent
  332. } else {
  333. copy(ac.content[len2:maxPossibleCardinality], ac.content[0:len1])
  334. }
  335. nl := union2by2(value1.content[len2:maxPossibleCardinality], value2.content, ac.content)
  336. ac.content = ac.content[:nl] // reslice to match actual used capacity
  337. return ac
  338. }
  339. // Note: such code does not make practical sense, except for lazy evaluations
  340. func (ac *arrayContainer) iorBitmap(bc2 *bitmapContainer) container {
  341. bc1 := ac.toBitmapContainer()
  342. bc1.iorBitmap(bc2)
  343. *ac = *newArrayContainerFromBitmap(bc1)
  344. return ac
  345. }
  346. func (ac *arrayContainer) iorRun16(rc *runContainer16) container {
  347. bc1 := ac.toBitmapContainer()
  348. bc2 := rc.toBitmapContainer()
  349. bc1.iorBitmap(bc2)
  350. *ac = *newArrayContainerFromBitmap(bc1)
  351. return ac
  352. }
  353. func (ac *arrayContainer) lazyIOR(a container) container {
  354. switch x := a.(type) {
  355. case *arrayContainer:
  356. return ac.lazyIorArray(x)
  357. case *bitmapContainer:
  358. return ac.lazyIorBitmap(x)
  359. case *runContainer16:
  360. if x.isFull() {
  361. return x.clone()
  362. }
  363. return ac.lazyIorRun16(x)
  364. }
  365. panic("unsupported container type")
  366. }
  367. func (ac *arrayContainer) lazyIorArray(ac2 *arrayContainer) container {
  368. // TODO actually make this lazy
  369. return ac.iorArray(ac2)
  370. }
  371. func (ac *arrayContainer) lazyIorBitmap(bc *bitmapContainer) container {
  372. // TODO actually make this lazy
  373. return ac.iorBitmap(bc)
  374. }
  375. func (ac *arrayContainer) lazyIorRun16(rc *runContainer16) container {
  376. // TODO actually make this lazy
  377. return ac.iorRun16(rc)
  378. }
  379. func (ac *arrayContainer) lazyOR(a container) container {
  380. switch x := a.(type) {
  381. case *arrayContainer:
  382. return ac.lazyorArray(x)
  383. case *bitmapContainer:
  384. return a.lazyOR(ac)
  385. case *runContainer16:
  386. if x.isFull() {
  387. return x.clone()
  388. }
  389. return x.orArray(ac)
  390. }
  391. panic("unsupported container type")
  392. }
  393. func (ac *arrayContainer) orArray(value2 *arrayContainer) container {
  394. value1 := ac
  395. maxPossibleCardinality := value1.getCardinality() + value2.getCardinality()
  396. if maxPossibleCardinality > arrayDefaultMaxSize { // it could be a bitmap!
  397. bc := newBitmapContainer()
  398. for k := 0; k < len(value2.content); k++ {
  399. v := value2.content[k]
  400. i := uint(v) >> 6
  401. mask := uint64(1) << (v % 64)
  402. bc.bitmap[i] |= mask
  403. }
  404. for k := 0; k < len(ac.content); k++ {
  405. v := ac.content[k]
  406. i := uint(v) >> 6
  407. mask := uint64(1) << (v % 64)
  408. bc.bitmap[i] |= mask
  409. }
  410. bc.cardinality = int(popcntSlice(bc.bitmap))
  411. if bc.cardinality <= arrayDefaultMaxSize {
  412. return bc.toArrayContainer()
  413. }
  414. return bc
  415. }
  416. answer := newArrayContainerCapacity(maxPossibleCardinality)
  417. nl := union2by2(value1.content, value2.content, answer.content)
  418. answer.content = answer.content[:nl] // reslice to match actual used capacity
  419. return answer
  420. }
  421. func (ac *arrayContainer) orArrayCardinality(value2 *arrayContainer) int {
  422. return union2by2Cardinality(ac.content, value2.content)
  423. }
  424. func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container {
  425. value1 := ac
  426. maxPossibleCardinality := value1.getCardinality() + value2.getCardinality()
  427. if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap!^M
  428. bc := newBitmapContainer()
  429. for k := 0; k < len(value2.content); k++ {
  430. v := value2.content[k]
  431. i := uint(v) >> 6
  432. mask := uint64(1) << (v % 64)
  433. bc.bitmap[i] |= mask
  434. }
  435. for k := 0; k < len(ac.content); k++ {
  436. v := ac.content[k]
  437. i := uint(v) >> 6
  438. mask := uint64(1) << (v % 64)
  439. bc.bitmap[i] |= mask
  440. }
  441. bc.cardinality = invalidCardinality
  442. return bc
  443. }
  444. answer := newArrayContainerCapacity(maxPossibleCardinality)
  445. nl := union2by2(value1.content, value2.content, answer.content)
  446. answer.content = answer.content[:nl] // reslice to match actual used capacity
  447. return answer
  448. }
  449. func (ac *arrayContainer) and(a container) container {
  450. //p("ac.and() called")
  451. switch x := a.(type) {
  452. case *arrayContainer:
  453. return ac.andArray(x)
  454. case *bitmapContainer:
  455. return x.and(ac)
  456. case *runContainer16:
  457. if x.isFull() {
  458. return ac.clone()
  459. }
  460. return x.andArray(ac)
  461. }
  462. panic("unsupported container type")
  463. }
  464. func (ac *arrayContainer) andCardinality(a container) int {
  465. switch x := a.(type) {
  466. case *arrayContainer:
  467. return ac.andArrayCardinality(x)
  468. case *bitmapContainer:
  469. return x.andCardinality(ac)
  470. case *runContainer16:
  471. return x.andArrayCardinality(ac)
  472. }
  473. panic("unsupported container type")
  474. }
  475. func (ac *arrayContainer) intersects(a container) bool {
  476. switch x := a.(type) {
  477. case *arrayContainer:
  478. return ac.intersectsArray(x)
  479. case *bitmapContainer:
  480. return x.intersects(ac)
  481. case *runContainer16:
  482. return x.intersects(ac)
  483. }
  484. panic("unsupported container type")
  485. }
  486. func (ac *arrayContainer) iand(a container) container {
  487. switch x := a.(type) {
  488. case *arrayContainer:
  489. return ac.iandArray(x)
  490. case *bitmapContainer:
  491. return ac.iandBitmap(x)
  492. case *runContainer16:
  493. if x.isFull() {
  494. return ac.clone()
  495. }
  496. return x.andArray(ac)
  497. }
  498. panic("unsupported container type")
  499. }
  500. func (ac *arrayContainer) iandBitmap(bc *bitmapContainer) container {
  501. pos := 0
  502. c := ac.getCardinality()
  503. for k := 0; k < c; k++ {
  504. // branchless
  505. v := ac.content[k]
  506. ac.content[pos] = v
  507. pos += int(bc.bitValue(v))
  508. }
  509. ac.content = ac.content[:pos]
  510. return ac
  511. }
  512. func (ac *arrayContainer) xor(a container) container {
  513. switch x := a.(type) {
  514. case *arrayContainer:
  515. return ac.xorArray(x)
  516. case *bitmapContainer:
  517. return a.xor(ac)
  518. case *runContainer16:
  519. return x.xorArray(ac)
  520. }
  521. panic("unsupported container type")
  522. }
  523. func (ac *arrayContainer) xorArray(value2 *arrayContainer) container {
  524. value1 := ac
  525. totalCardinality := value1.getCardinality() + value2.getCardinality()
  526. if totalCardinality > arrayDefaultMaxSize { // it could be a bitmap!
  527. bc := newBitmapContainer()
  528. for k := 0; k < len(value2.content); k++ {
  529. v := value2.content[k]
  530. i := uint(v) >> 6
  531. bc.bitmap[i] ^= (uint64(1) << (v % 64))
  532. }
  533. for k := 0; k < len(ac.content); k++ {
  534. v := ac.content[k]
  535. i := uint(v) >> 6
  536. bc.bitmap[i] ^= (uint64(1) << (v % 64))
  537. }
  538. bc.computeCardinality()
  539. if bc.cardinality <= arrayDefaultMaxSize {
  540. return bc.toArrayContainer()
  541. }
  542. return bc
  543. }
  544. desiredCapacity := totalCardinality
  545. answer := newArrayContainerCapacity(desiredCapacity)
  546. length := exclusiveUnion2by2(value1.content, value2.content, answer.content)
  547. answer.content = answer.content[:length]
  548. return answer
  549. }
  550. func (ac *arrayContainer) andNot(a container) container {
  551. switch x := a.(type) {
  552. case *arrayContainer:
  553. return ac.andNotArray(x)
  554. case *bitmapContainer:
  555. return ac.andNotBitmap(x)
  556. case *runContainer16:
  557. return ac.andNotRun16(x)
  558. }
  559. panic("unsupported container type")
  560. }
  561. func (ac *arrayContainer) andNotRun16(rc *runContainer16) container {
  562. acb := ac.toBitmapContainer()
  563. rcb := rc.toBitmapContainer()
  564. return acb.andNotBitmap(rcb)
  565. }
  566. func (ac *arrayContainer) iandNot(a container) container {
  567. switch x := a.(type) {
  568. case *arrayContainer:
  569. return ac.iandNotArray(x)
  570. case *bitmapContainer:
  571. return ac.iandNotBitmap(x)
  572. case *runContainer16:
  573. return ac.iandNotRun16(x)
  574. }
  575. panic("unsupported container type")
  576. }
  577. func (ac *arrayContainer) iandNotRun16(rc *runContainer16) container {
  578. rcb := rc.toBitmapContainer()
  579. acb := ac.toBitmapContainer()
  580. acb.iandNotBitmapSurely(rcb)
  581. *ac = *(acb.toArrayContainer())
  582. return ac
  583. }
  584. func (ac *arrayContainer) andNotArray(value2 *arrayContainer) container {
  585. value1 := ac
  586. desiredcapacity := value1.getCardinality()
  587. answer := newArrayContainerCapacity(desiredcapacity)
  588. length := difference(value1.content, value2.content, answer.content)
  589. answer.content = answer.content[:length]
  590. return answer
  591. }
  592. func (ac *arrayContainer) iandNotArray(value2 *arrayContainer) container {
  593. length := difference(ac.content, value2.content, ac.content)
  594. ac.content = ac.content[:length]
  595. return ac
  596. }
  597. func (ac *arrayContainer) andNotBitmap(value2 *bitmapContainer) container {
  598. desiredcapacity := ac.getCardinality()
  599. answer := newArrayContainerCapacity(desiredcapacity)
  600. answer.content = answer.content[:desiredcapacity]
  601. pos := 0
  602. for _, v := range ac.content {
  603. answer.content[pos] = v
  604. pos += 1 - int(value2.bitValue(v))
  605. }
  606. answer.content = answer.content[:pos]
  607. return answer
  608. }
  609. func (ac *arrayContainer) andBitmap(value2 *bitmapContainer) container {
  610. desiredcapacity := ac.getCardinality()
  611. answer := newArrayContainerCapacity(desiredcapacity)
  612. answer.content = answer.content[:desiredcapacity]
  613. pos := 0
  614. for _, v := range ac.content {
  615. answer.content[pos] = v
  616. pos += int(value2.bitValue(v))
  617. }
  618. answer.content = answer.content[:pos]
  619. return answer
  620. }
  621. func (ac *arrayContainer) iandNotBitmap(value2 *bitmapContainer) container {
  622. pos := 0
  623. for _, v := range ac.content {
  624. ac.content[pos] = v
  625. pos += 1 - int(value2.bitValue(v))
  626. }
  627. ac.content = ac.content[:pos]
  628. return ac
  629. }
  630. func copyOf(array []uint16, size int) []uint16 {
  631. result := make([]uint16, size)
  632. for i, x := range array {
  633. if i == size {
  634. break
  635. }
  636. result[i] = x
  637. }
  638. return result
  639. }
  640. // flip the values in the range [firstOfRange,endx)
  641. func (ac *arrayContainer) inot(firstOfRange, endx int) container {
  642. if firstOfRange >= endx {
  643. return ac
  644. }
  645. return ac.inotClose(firstOfRange, endx-1) // remove everything in [firstOfRange,endx-1]
  646. }
  647. // flip the values in the range [firstOfRange,lastOfRange]
  648. func (ac *arrayContainer) inotClose(firstOfRange, lastOfRange int) container {
  649. //p("ac.inotClose() starting")
  650. if firstOfRange > lastOfRange { // unlike add and remove, not uses an inclusive range [firstOfRange,lastOfRange]
  651. return ac
  652. }
  653. // determine the span of array indices to be affected
  654. startIndex := binarySearch(ac.content, uint16(firstOfRange))
  655. if startIndex < 0 {
  656. startIndex = -startIndex - 1
  657. }
  658. lastIndex := binarySearch(ac.content, uint16(lastOfRange))
  659. if lastIndex < 0 {
  660. lastIndex = -lastIndex - 1 - 1
  661. }
  662. currentValuesInRange := lastIndex - startIndex + 1
  663. spanToBeFlipped := lastOfRange - firstOfRange + 1
  664. newValuesInRange := spanToBeFlipped - currentValuesInRange
  665. buffer := make([]uint16, newValuesInRange)
  666. cardinalityChange := newValuesInRange - currentValuesInRange
  667. newCardinality := len(ac.content) + cardinalityChange
  668. if cardinalityChange > 0 {
  669. if newCardinality > len(ac.content) {
  670. if newCardinality > arrayDefaultMaxSize {
  671. //p("ac.inotClose() converting to bitmap and doing inot there")
  672. bcRet := ac.toBitmapContainer()
  673. bcRet.inot(firstOfRange, lastOfRange+1)
  674. *ac = *bcRet.toArrayContainer()
  675. return bcRet
  676. }
  677. ac.content = copyOf(ac.content, newCardinality)
  678. }
  679. base := lastIndex + 1
  680. copy(ac.content[lastIndex+1+cardinalityChange:], ac.content[base:base+len(ac.content)-1-lastIndex])
  681. ac.negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange+1)
  682. } else { // no expansion needed
  683. ac.negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange+1)
  684. if cardinalityChange < 0 {
  685. for i := startIndex + newValuesInRange; i < newCardinality; i++ {
  686. ac.content[i] = ac.content[i-cardinalityChange]
  687. }
  688. }
  689. }
  690. ac.content = ac.content[:newCardinality]
  691. //p("bottom of ac.inotClose(): returning ac")
  692. return ac
  693. }
  694. func (ac *arrayContainer) negateRange(buffer []uint16, startIndex, lastIndex, startRange, lastRange int) {
  695. // compute the negation into buffer
  696. outPos := 0
  697. inPos := startIndex // value here always >= valInRange,
  698. // until it is exhausted
  699. // n.b., we can start initially exhausted.
  700. valInRange := startRange
  701. for ; valInRange < lastRange && inPos <= lastIndex; valInRange++ {
  702. if uint16(valInRange) != ac.content[inPos] {
  703. buffer[outPos] = uint16(valInRange)
  704. outPos++
  705. } else {
  706. inPos++
  707. }
  708. }
  709. // if there are extra items (greater than the biggest
  710. // pre-existing one in range), buffer them
  711. for ; valInRange < lastRange; valInRange++ {
  712. buffer[outPos] = uint16(valInRange)
  713. outPos++
  714. }
  715. if outPos != len(buffer) {
  716. panic("negateRange: internal bug")
  717. }
  718. for i, item := range buffer {
  719. ac.content[i+startIndex] = item
  720. }
  721. }
  722. func (ac *arrayContainer) isFull() bool {
  723. return false
  724. }
  725. func (ac *arrayContainer) andArray(value2 *arrayContainer) container {
  726. desiredcapacity := minOfInt(ac.getCardinality(), value2.getCardinality())
  727. answer := newArrayContainerCapacity(desiredcapacity)
  728. length := intersection2by2(
  729. ac.content,
  730. value2.content,
  731. answer.content)
  732. answer.content = answer.content[:length]
  733. return answer
  734. }
  735. func (ac *arrayContainer) andArrayCardinality(value2 *arrayContainer) int {
  736. return intersection2by2Cardinality(
  737. ac.content,
  738. value2.content)
  739. }
  740. func (ac *arrayContainer) intersectsArray(value2 *arrayContainer) bool {
  741. return intersects2by2(
  742. ac.content,
  743. value2.content)
  744. }
  745. func (ac *arrayContainer) iandArray(value2 *arrayContainer) container {
  746. length := intersection2by2(
  747. ac.content,
  748. value2.content,
  749. ac.content)
  750. ac.content = ac.content[:length]
  751. return ac
  752. }
  753. func (ac *arrayContainer) getCardinality() int {
  754. return len(ac.content)
  755. }
  756. func (ac *arrayContainer) rank(x uint16) int {
  757. answer := binarySearch(ac.content, x)
  758. if answer >= 0 {
  759. return answer + 1
  760. }
  761. return -answer - 1
  762. }
  763. func (ac *arrayContainer) selectInt(x uint16) int {
  764. return int(ac.content[x])
  765. }
  766. func (ac *arrayContainer) clone() container {
  767. ptr := arrayContainer{make([]uint16, len(ac.content))}
  768. copy(ptr.content, ac.content[:])
  769. return &ptr
  770. }
  771. func (ac *arrayContainer) contains(x uint16) bool {
  772. return binarySearch(ac.content, x) >= 0
  773. }
  774. func (ac *arrayContainer) loadData(bitmapContainer *bitmapContainer) {
  775. ac.content = make([]uint16, bitmapContainer.cardinality, bitmapContainer.cardinality)
  776. bitmapContainer.fillArray(ac.content)
  777. }
  778. func newArrayContainer() *arrayContainer {
  779. p := new(arrayContainer)
  780. return p
  781. }
  782. func newArrayContainerFromBitmap(bc *bitmapContainer) *arrayContainer {
  783. ac := &arrayContainer{}
  784. ac.loadData(bc)
  785. return ac
  786. }
  787. func newArrayContainerCapacity(size int) *arrayContainer {
  788. p := new(arrayContainer)
  789. p.content = make([]uint16, 0, size)
  790. return p
  791. }
  792. func newArrayContainerSize(size int) *arrayContainer {
  793. p := new(arrayContainer)
  794. p.content = make([]uint16, size, size)
  795. return p
  796. }
  797. func newArrayContainerRange(firstOfRun, lastOfRun int) *arrayContainer {
  798. valuesInRange := lastOfRun - firstOfRun + 1
  799. this := newArrayContainerCapacity(valuesInRange)
  800. for i := 0; i < valuesInRange; i++ {
  801. this.content = append(this.content, uint16(firstOfRun+i))
  802. }
  803. return this
  804. }
  805. func (ac *arrayContainer) numberOfRuns() (nr int) {
  806. n := len(ac.content)
  807. var runlen uint16
  808. var cur, prev uint16
  809. switch n {
  810. case 0:
  811. return 0
  812. case 1:
  813. return 1
  814. default:
  815. for i := 1; i < n; i++ {
  816. prev = ac.content[i-1]
  817. cur = ac.content[i]
  818. if cur == prev+1 {
  819. runlen++
  820. } else {
  821. if cur < prev {
  822. panic("then fundamental arrayContainer assumption of sorted ac.content was broken")
  823. }
  824. if cur == prev {
  825. panic("then fundamental arrayContainer assumption of deduplicated content was broken")
  826. } else {
  827. nr++
  828. runlen = 0
  829. }
  830. }
  831. }
  832. nr++
  833. }
  834. return
  835. }
  836. // convert to run or array *if needed*
  837. func (ac *arrayContainer) toEfficientContainer() container {
  838. numRuns := ac.numberOfRuns()
  839. sizeAsRunContainer := runContainer16SerializedSizeInBytes(numRuns)
  840. sizeAsBitmapContainer := bitmapContainerSizeInBytes()
  841. card := ac.getCardinality()
  842. sizeAsArrayContainer := arrayContainerSizeInBytes(card)
  843. if sizeAsRunContainer <= minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) {
  844. return newRunContainer16FromArray(ac)
  845. }
  846. if card <= arrayDefaultMaxSize {
  847. return ac
  848. }
  849. return ac.toBitmapContainer()
  850. }
  851. func (ac *arrayContainer) containerType() contype {
  852. return arrayContype
  853. }