newRunContainer16FromBitmapContainer makes a new run container from bc, somewhat efficiently. For reference, see the Java https://github.com/RoaringBitmap/RoaringBitmap/blob/master/src/main/java/org/roaringbitmap/RunContainer.java#L145-L192
(bc *bitmapContainer)
| 199 | // somewhat efficiently. For reference, see the Java |
| 200 | // https://github.com/RoaringBitmap/RoaringBitmap/blob/master/src/main/java/org/roaringbitmap/RunContainer.java#L145-L192 |
| 201 | func newRunContainer16FromBitmapContainer(bc *bitmapContainer) *runContainer16 { |
| 202 | rc := &runContainer16{} |
| 203 | nbrRuns := bc.numberOfRuns() |
| 204 | if nbrRuns == 0 { |
| 205 | return rc |
| 206 | } |
| 207 | rc.iv = make([]interval16, nbrRuns) |
| 208 | |
| 209 | longCtr := 0 // index of current long in bitmap |
| 210 | curWord := bc.bitmap[0] // its value |
| 211 | runCount := 0 |
| 212 | for { |
| 213 | // potentially multiword advance to first 1 bit |
| 214 | for curWord == 0 && longCtr < len(bc.bitmap)-1 { |
| 215 | longCtr++ |
| 216 | curWord = bc.bitmap[longCtr] |
| 217 | } |
| 218 | |
| 219 | if curWord == 0 { |
| 220 | // wrap up, no more runs |
| 221 | return rc |
| 222 | } |
| 223 | localRunStart := countTrailingZeros(curWord) |
| 224 | runStart := localRunStart + 64*longCtr |
| 225 | // stuff 1s into number's LSBs |
| 226 | curWordWith1s := curWord | (curWord - 1) |
| 227 | |
| 228 | // find the next 0, potentially in a later word |
| 229 | runEnd := 0 |
| 230 | for curWordWith1s == maxWord && longCtr < len(bc.bitmap)-1 { |
| 231 | longCtr++ |
| 232 | curWordWith1s = bc.bitmap[longCtr] |
| 233 | } |
| 234 | |
| 235 | if curWordWith1s == maxWord { |
| 236 | // a final unterminated run of 1s |
| 237 | runEnd = wordSizeInBits + longCtr*64 |
| 238 | rc.iv[runCount].start = uint16(runStart) |
| 239 | rc.iv[runCount].length = uint16(runEnd) - uint16(runStart) - 1 |
| 240 | return rc |
| 241 | } |
| 242 | localRunEnd := countTrailingZeros(^curWordWith1s) |
| 243 | runEnd = localRunEnd + longCtr*64 |
| 244 | rc.iv[runCount].start = uint16(runStart) |
| 245 | rc.iv[runCount].length = uint16(runEnd) - 1 - uint16(runStart) |
| 246 | runCount++ |
| 247 | // now, zero out everything right of runEnd. |
| 248 | curWord = curWordWith1s & (curWordWith1s + 1) |
| 249 | // We've lathered and rinsed, so repeat... |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | // newRunContainer16FromArray populates a new |
| 254 | // runContainer16 from the contents of arr. |
searching dependent graphs…