AndAny provides a result equivalent to x1.And(FastOr(bitmaps)). It's optimized to minimize allocations. It also might be faster than separate calls.
(bitmaps ...*Bitmap)
| 208 | // AndAny provides a result equivalent to x1.And(FastOr(bitmaps)). |
| 209 | // It's optimized to minimize allocations. It also might be faster than separate calls. |
| 210 | func (x1 *Bitmap) AndAny(bitmaps ...*Bitmap) { |
| 211 | if len(bitmaps) == 0 { |
| 212 | return |
| 213 | } else if len(bitmaps) == 1 { |
| 214 | x1.And(bitmaps[0]) |
| 215 | return |
| 216 | } |
| 217 | |
| 218 | type withPos struct { |
| 219 | bitmap *roaringArray |
| 220 | pos int |
| 221 | key uint16 |
| 222 | } |
| 223 | filters := make([]withPos, 0, len(bitmaps)) |
| 224 | |
| 225 | for _, b := range bitmaps { |
| 226 | if b.highlowcontainer.size() > 0 { |
| 227 | filters = append(filters, withPos{ |
| 228 | bitmap: &b.highlowcontainer, |
| 229 | pos: 0, |
| 230 | key: b.highlowcontainer.getKeyAtIndex(0), |
| 231 | }) |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | basePos := 0 |
| 236 | intersections := 0 |
| 237 | keyContainers := make([]container, 0, len(filters)) |
| 238 | var ( |
| 239 | tmpArray *arrayContainer |
| 240 | tmpBitmap *bitmapContainer |
| 241 | minNextKey uint16 |
| 242 | ) |
| 243 | |
| 244 | for basePos < x1.highlowcontainer.size() && len(filters) > 0 { |
| 245 | baseKey := x1.highlowcontainer.getKeyAtIndex(basePos) |
| 246 | |
| 247 | // accumulate containers for current key, find next minimal key in filters |
| 248 | // and exclude filters that do not have related values anymore |
| 249 | i := 0 |
| 250 | maxPossibleOr := 0 |
| 251 | minNextKey = MaxUint16 |
| 252 | for _, f := range filters { |
| 253 | if f.key < baseKey { |
| 254 | f.pos = f.bitmap.advanceUntil(baseKey, f.pos) |
| 255 | if f.pos == f.bitmap.size() { |
| 256 | continue |
| 257 | } |
| 258 | f.key = f.bitmap.getKeyAtIndex(f.pos) |
| 259 | } |
| 260 | |
| 261 | if f.key == baseKey { |
| 262 | cont := f.bitmap.getContainerAtIndex(f.pos) |
| 263 | keyContainers = append(keyContainers, cont) |
| 264 | maxPossibleOr += cont.getCardinality() |
| 265 | |
| 266 | f.pos++ |
| 267 | if f.pos == f.bitmap.size() { |