SeekToBlock will find the block containing the uid, and unpack it. When we are going to intersect the list later, this function is useful. As this function skips the search function and returns the entire block, it is faster than Seek. Unlike seek, we don't truncate the uids returned, which would be
(uid uint64, whence seekPos)
| 217 | // and returns the entire block, it is faster than Seek. Unlike seek, we don't truncate the uids |
| 218 | // returned, which would be done by the intersect function anyways. |
| 219 | func (d *Decoder) SeekToBlock(uid uint64, whence seekPos) []uint64 { |
| 220 | if d.Pack == nil { |
| 221 | return []uint64{} |
| 222 | } |
| 223 | prevBlockIdx := d.blockIdx |
| 224 | d.blockIdx = 0 |
| 225 | if uid == 0 { |
| 226 | return d.UnpackBlock() |
| 227 | } |
| 228 | |
| 229 | // If for some reason we are searching an older uid, we need to search the entire pack |
| 230 | if prevBlockIdx > 0 && uid < d.Pack.Blocks[prevBlockIdx].Base { |
| 231 | prevBlockIdx = 0 |
| 232 | } |
| 233 | |
| 234 | blocksFunc := func() searchFunc { |
| 235 | var f searchFunc |
| 236 | switch whence { |
| 237 | case SeekStart: |
| 238 | f = func(i int) bool { return d.Pack.Blocks[i+prevBlockIdx].Base >= uid } |
| 239 | case SeekCurrent: |
| 240 | f = func(i int) bool { return d.Pack.Blocks[i+prevBlockIdx].Base > uid } |
| 241 | } |
| 242 | return f |
| 243 | } |
| 244 | |
| 245 | idx := sort.Search(len(d.Pack.Blocks[prevBlockIdx:]), blocksFunc()) + prevBlockIdx |
| 246 | // The first block.Base >= uid. |
| 247 | if idx == 0 { |
| 248 | return d.UnpackBlock() |
| 249 | } |
| 250 | // The uid is the first entry in the block. |
| 251 | if idx < len(d.Pack.Blocks) && d.Pack.Blocks[idx].Base == uid { |
| 252 | d.blockIdx = idx |
| 253 | return d.UnpackBlock() |
| 254 | } |
| 255 | |
| 256 | // Either the idx = len(pack.Blocks) that means it wasn't found in any of the block's base. Or, |
| 257 | // we found the first block index whose base is greater than uid. In these cases, go to the |
| 258 | // previous block and search there. |
| 259 | d.blockIdx = idx - 1 // Move to the previous block. If blockIdx<0, unpack will deal with it. |
| 260 | if d.blockIdx != prevBlockIdx { |
| 261 | d.UnpackBlock() // And get all their uids. |
| 262 | } |
| 263 | |
| 264 | if uid <= d.uids[len(d.uids)-1] { |
| 265 | return d.uids |
| 266 | } |
| 267 | |
| 268 | // Could not find any uid in the block, which is >= uid. The next block might still have valid |
| 269 | // entries > uid. |
| 270 | return d.Next() |
| 271 | } |
| 272 | |
| 273 | // Seek will search for uid in a packed block using the specified whence position. |
| 274 | // The value of whence must be one of the predefined values SeekStart or SeekCurrent. |
no test coverage detected