ParAnd computes the intersection (AND) 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)
| 262 | // where the parameter "parallelism" determines how many workers are to be used |
| 263 | // (if it is set to 0, a default number of workers is chosen) |
| 264 | func ParAnd(parallelism int, bitmaps ...*Bitmap) *Bitmap { |
| 265 | bitmapCount := len(bitmaps) |
| 266 | if bitmapCount == 0 { |
| 267 | return NewBitmap() |
| 268 | } else if bitmapCount == 1 { |
| 269 | return bitmaps[0].Clone() |
| 270 | } |
| 271 | |
| 272 | if parallelism == 0 { |
| 273 | parallelism = defaultWorkerCount |
| 274 | } |
| 275 | |
| 276 | h := newBitmapContainerHeap(bitmaps...) |
| 277 | |
| 278 | bitmapChan := make(chan *Bitmap) |
| 279 | inputChan := make(chan multipleContainers, 128) |
| 280 | resultChan := make(chan keyedContainer, 32) |
| 281 | expectedKeysChan := make(chan int) |
| 282 | |
| 283 | andFunc := func() { |
| 284 | // Assumes only structs with >=2 containers are passed |
| 285 | for input := range inputChan { |
| 286 | c := input.containers[0].and(input.containers[1]) |
| 287 | for _, next := range input.containers[2:] { |
| 288 | if c.isEmpty() { |
| 289 | break |
| 290 | } |
| 291 | c = c.iand(next) |
| 292 | } |
| 293 | |
| 294 | // Send a nil explicitly if the result of the intersection is an empty container |
| 295 | if c.isEmpty() { |
| 296 | c = nil |
| 297 | } |
| 298 | |
| 299 | kx := keyedContainer{ |
| 300 | input.key, |
| 301 | c, |
| 302 | input.idx, |
| 303 | } |
| 304 | resultChan <- kx |
| 305 | } |
| 306 | } |
| 307 | |
| 308 | go appenderRoutine(bitmapChan, resultChan, expectedKeysChan) |
| 309 | |
| 310 | for i := 0; i < parallelism; i++ { |
| 311 | go andFunc() |
| 312 | } |
| 313 | |
| 314 | idx := 0 |
| 315 | for h.Len() > 0 { |
| 316 | ck := h.Next(make([]container, 0, 4)) |
| 317 | if len(ck.containers) == bitmapCount { |
| 318 | ck.idx = idx |
| 319 | inputChan <- ck |
| 320 | idx++ |
| 321 | } |
searching dependent graphs…