@@ -286,41 +286,58 @@ func (d *Decoder) Seek(uid uint64, whence seekPos) []uint64 {
286286 if d .Pack == nil {
287287 return []uint64 {}
288288 }
289+
289290 prevBlockIdx := d .blockIdx
290- d .blockIdx = 0
291+ pack := d .Pack
292+ blocksToSearch := pack .Blocks
293+ offset := 0
294+ if len (d .uids ) > 0 {
295+ first := d .uids [0 ]
296+ second := d .uids [len (d .uids )- 1 ]
297+
298+ if uid >= first && uid <= second {
299+ blocksToSearch = nil
300+ } else if uid > second {
301+ blocksToSearch = blocksToSearch [prevBlockIdx :]
302+ offset = prevBlockIdx
303+ } else {
304+ blocksToSearch = blocksToSearch [:prevBlockIdx ]
305+ }
306+ }
307+
291308 if uid == 0 {
292309 return d .UnpackBlock ()
293310 }
294311
295- pack := d .Pack
296312 blocksFunc := func () searchFunc {
297313 var f searchFunc
298314 switch whence {
299315 case SeekStart :
300- f = func (i int ) bool { return pack . Blocks [ i + prevBlockIdx ].Base >= uid }
316+ f = func (i int ) bool { return blocksToSearch [ i ].Base >= uid }
301317 case SeekCurrent :
302- f = func (i int ) bool { return pack . Blocks [ i + prevBlockIdx ].Base > uid }
318+ f = func (i int ) bool { return blocksToSearch [ i ].Base > uid }
303319 }
304320 return f
305321 }
306322
307- idx := sort .Search (len (pack .Blocks [prevBlockIdx :]), blocksFunc ()) + prevBlockIdx
308- // The first block.Base >= uid.
309- if idx == 0 {
310- return d .UnpackBlock ()
311- }
312- // The uid is the first entry in the block.
313- if idx < len (pack .Blocks ) && pack .Blocks [idx ].Base == uid {
314- d .blockIdx = idx
315- return d .UnpackBlock ()
316- }
317-
318323 // Either the idx = len(pack.Blocks) that means it wasn't found in any of the block's base. Or,
319324 // we found the first block index whose base is greater than uid. In these cases, go to the
320325 // previous block and search there.
321- d .blockIdx = idx - 1 // Move to the previous block. If blockIdx<0, unpack will deal with it.
322- if d .blockIdx != prevBlockIdx {
323- d .UnpackBlock () // And get all their uids.
326+ if blocksToSearch != nil {
327+ idx := sort .Search (len (blocksToSearch ), blocksFunc ()) + offset
328+ // The first block.Base >= uid.
329+ if idx == 0 {
330+ return d .UnpackBlock ()
331+ }
332+
333+ // The uid is the first entry in the block.
334+ if idx < len (pack .Blocks ) && pack .Blocks [idx ].Base == uid {
335+ d .blockIdx = idx
336+ return d .UnpackBlock ()
337+ }
338+
339+ d .blockIdx = idx - 1 // Move to the previous block. If blockIdx<0, unpack will deal with it.
340+ d .UnpackBlock () // And get all their uids.
324341 }
325342
326343 uidsFunc := func () searchFunc {
0 commit comments