ParHeapOr 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) ParHeapOr uses a heap to compute the union. For rare cases it might be faster than ParOr
(parallelism int, bitmaps ...*Bitmap)
| 182 | // (if it is set to 0, a default number of workers is chosen) |
| 183 | // ParHeapOr uses a heap to compute the union. For rare cases it might be faster than ParOr |
| 184 | func ParHeapOr(parallelism int, bitmaps ...*Bitmap) *Bitmap { |
| 185 | |
| 186 | bitmapCount := len(bitmaps) |
| 187 | if bitmapCount == 0 { |
| 188 | return NewBitmap() |
| 189 | } else if bitmapCount == 1 { |
| 190 | return bitmaps[0].Clone() |
| 191 | } |
| 192 | |
| 193 | if parallelism == 0 { |
| 194 | parallelism = defaultWorkerCount |
| 195 | } |
| 196 | |
| 197 | h := newBitmapContainerHeap(bitmaps...) |
| 198 | |
| 199 | bitmapChan := make(chan *Bitmap) |
| 200 | inputChan := make(chan multipleContainers, 128) |
| 201 | resultChan := make(chan keyedContainer, 32) |
| 202 | expectedKeysChan := make(chan int) |
| 203 | |
| 204 | pool := sync.Pool{ |
| 205 | New: func() interface{} { |
| 206 | return make([]container, 0, len(bitmaps)) |
| 207 | }, |
| 208 | } |
| 209 | |
| 210 | orFunc := func() { |
| 211 | // Assumes only structs with >=2 containers are passed |
| 212 | for input := range inputChan { |
| 213 | c := toBitmapContainer(input.containers[0]).lazyOR(input.containers[1]) |
| 214 | for _, next := range input.containers[2:] { |
| 215 | c = c.lazyIOR(next) |
| 216 | } |
| 217 | c = repairAfterLazy(c) |
| 218 | kx := keyedContainer{ |
| 219 | input.key, |
| 220 | c, |
| 221 | input.idx, |
| 222 | } |
| 223 | resultChan <- kx |
| 224 | pool.Put(input.containers[:0]) |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | go appenderRoutine(bitmapChan, resultChan, expectedKeysChan) |
| 229 | |
| 230 | for i := 0; i < parallelism; i++ { |
| 231 | go orFunc() |
| 232 | } |
| 233 | |
| 234 | idx := 0 |
| 235 | for h.Len() > 0 { |
| 236 | ck := h.Next(pool.Get().([]container)) |
| 237 | if len(ck.containers) == 1 { |
| 238 | resultChan <- keyedContainer{ |
| 239 | ck.key, |
| 240 | ck.containers[0], |
| 241 | idx, |
searching dependent graphs…