ParOr computes the union (OR) of all provided bitmaps in parallel, where the parameter "parallelism" determines how many workers are to be used (if it is set to 0, a default number of workers is chosen)
(parallelism int, bitmaps ...*Bitmap)
| 335 | // where the parameter "parallelism" determines how many workers are to be used |
| 336 | // (if it is set to 0, a default number of workers is chosen) |
| 337 | func ParOr(parallelism int, bitmaps ...*Bitmap) *Bitmap { |
| 338 | var lKey uint16 = MaxUint16 |
| 339 | var hKey uint16 |
| 340 | |
| 341 | bitmapsFiltered := bitmaps[:0] |
| 342 | for _, b := range bitmaps { |
| 343 | if !b.IsEmpty() { |
| 344 | bitmapsFiltered = append(bitmapsFiltered, b) |
| 345 | } |
| 346 | } |
| 347 | bitmaps = bitmapsFiltered |
| 348 | |
| 349 | for _, b := range bitmaps { |
| 350 | lKey = minOfUint16(lKey, b.highlowcontainer.keys[0]) |
| 351 | hKey = maxOfUint16(hKey, b.highlowcontainer.keys[b.highlowcontainer.size()-1]) |
| 352 | } |
| 353 | |
| 354 | if lKey == MaxUint16 && hKey == 0 { |
| 355 | return New() |
| 356 | } else if len(bitmaps) == 1 { |
| 357 | return bitmaps[0].Clone() |
| 358 | } |
| 359 | |
| 360 | keyRange := int(hKey) - int(lKey) + 1 |
| 361 | if keyRange == 1 { |
| 362 | // revert to FastOr. Since the key range is 0 |
| 363 | // no container-level aggregation parallelism is achievable |
| 364 | return FastOr(bitmaps...) |
| 365 | } |
| 366 | |
| 367 | if parallelism == 0 { |
| 368 | parallelism = defaultWorkerCount |
| 369 | } |
| 370 | |
| 371 | var chunkSize int |
| 372 | var chunkCount int |
| 373 | if parallelism*4 > keyRange { |
| 374 | chunkSize = 1 |
| 375 | chunkCount = keyRange |
| 376 | } else { |
| 377 | chunkCount = parallelism * 4 |
| 378 | chunkSize = (keyRange + chunkCount - 1) / chunkCount |
| 379 | } |
| 380 | |
| 381 | if chunkCount*chunkSize < keyRange { |
| 382 | // it's fine to panic to indicate an implementation error |
| 383 | panic(fmt.Sprintf("invariant check failed: chunkCount * chunkSize < keyRange, %d * %d < %d", chunkCount, chunkSize, keyRange)) |
| 384 | } |
| 385 | |
| 386 | chunks := make([]*roaringArray, chunkCount) |
| 387 | |
| 388 | chunkSpecChan := make(chan parChunkSpec, minOfInt(maxOfInt(64, 2*parallelism), chunkCount)) |
| 389 | chunkChan := make(chan parChunk, minOfInt(32, chunkCount)) |
| 390 | |
| 391 | orFunc := func() { |
| 392 | for spec := range chunkSpecChan { |
| 393 | ra := lazyOrOnRange(&bitmaps[0].highlowcontainer, &bitmaps[1].highlowcontainer, spec.start, spec.end) |
| 394 | for _, b := range bitmaps[2:] { |
searching dependent graphs…