Commit 498fc0bd authored by Timothy B. Terriberry's avatar Timothy B. Terriberry
Browse files

Bias the offsets in op_predict_link_start().

We apply a positive bias when the previous bisection point was
 inside the current link, causing us to scan forward a bit instead
 of seeking to a new location.
This knocks up to 18% off the number of seeks required to open very
 large files with lots of links.
parent 21f72850
...@@ -918,7 +918,7 @@ opus_int64 op_rescale64(opus_int64 _x,opus_int64 _from,opus_int64 _to){ ...@@ -918,7 +918,7 @@ opus_int64 op_rescale64(opus_int64 _x,opus_int64 _from,opus_int64 _to){
records, assuming the initial granule position of any streams we've found is records, assuming the initial granule position of any streams we've found is
0.*/ 0.*/
static opus_int64 op_predict_link_start(const OpusSeekRecord *_sr,int _nsr, static opus_int64 op_predict_link_start(const OpusSeekRecord *_sr,int _nsr,
opus_int64 _searched,opus_int64 _end_searched){ opus_int64 _searched,opus_int64 _end_searched,opus_int32 _bias){
opus_int64 bisect; opus_int64 bisect;
int sri; int sri;
int srj; int srj;
...@@ -969,7 +969,7 @@ static opus_int64 op_predict_link_start(const OpusSeekRecord *_sr,int _nsr, ...@@ -969,7 +969,7 @@ static opus_int64 op_predict_link_start(const OpusSeekRecord *_sr,int _nsr,
if(ipart>0&&(offset2-_searched)/ipart<num)continue; if(ipart>0&&(offset2-_searched)/ipart<num)continue;
offset2-=ipart*num; offset2-=ipart*num;
gp2-=ipart*den; gp2-=ipart*den;
offset2-=op_rescale64(gp2,den,num); offset2-=op_rescale64(gp2,den,num)-_bias;
if(offset2<_searched)continue; if(offset2<_searched)continue;
bisect=OP_MIN(bisect,offset2); bisect=OP_MIN(bisect,offset2);
break; break;
...@@ -1065,6 +1065,7 @@ static int op_bisect_forward_serialno(OggOpusFile *_of, ...@@ -1065,6 +1065,7 @@ static int op_bisect_forward_serialno(OggOpusFile *_of,
/*We guard against garbage separating the last and first pages of two /*We guard against garbage separating the last and first pages of two
links below.*/ links below.*/
while(_searched<end_searched){ while(_searched<end_searched){
opus_int32 next_bias;
/*If we don't have a better estimate, use simple bisection.*/ /*If we don't have a better estimate, use simple bisection.*/
if(bisect==-1)bisect=_searched+(end_searched-_searched>>1); if(bisect==-1)bisect=_searched+(end_searched-_searched>>1);
/*If we're within OP_CHUNK_SIZE of the start, scan forward.*/ /*If we're within OP_CHUNK_SIZE of the start, scan forward.*/
...@@ -1083,6 +1084,7 @@ static int op_bisect_forward_serialno(OggOpusFile *_of, ...@@ -1083,6 +1084,7 @@ static int op_bisect_forward_serialno(OggOpusFile *_of,
if(!op_lookup_serialno(_sr[nsr].serialno,serialnos,nserialnos)){ if(!op_lookup_serialno(_sr[nsr].serialno,serialnos,nserialnos)){
end_searched=bisect; end_searched=bisect;
next=last; next=last;
next_bias=0;
/*In reality we should always have enough room, but be paranoid.*/ /*In reality we should always have enough room, but be paranoid.*/
if(OP_LIKELY(nsr+1<_csr)){ if(OP_LIKELY(nsr+1<_csr)){
_sr[nsr].search_start=bisect; _sr[nsr].search_start=bisect;
...@@ -1095,6 +1097,7 @@ static int op_bisect_forward_serialno(OggOpusFile *_of, ...@@ -1095,6 +1097,7 @@ static int op_bisect_forward_serialno(OggOpusFile *_of,
} }
else{ else{
_searched=_of->offset; _searched=_of->offset;
next_bias=OP_CHUNK_SIZE;
if(_sr[nsr].serialno==links[nlinks-1].serialno){ if(_sr[nsr].serialno==links[nlinks-1].serialno){
/*This page was from the stream we want, remember it. /*This page was from the stream we want, remember it.
If it's the last such page in the link, we won't have to go back If it's the last such page in the link, we won't have to go back
...@@ -1103,7 +1106,7 @@ static int op_bisect_forward_serialno(OggOpusFile *_of, ...@@ -1103,7 +1106,7 @@ static int op_bisect_forward_serialno(OggOpusFile *_of,
end_offset=last; end_offset=last;
} }
} }
bisect=op_predict_link_start(_sr,nsr,_searched,end_searched); bisect=op_predict_link_start(_sr,nsr,_searched,end_searched,next_bias);
} }
/*Bisection point found. /*Bisection point found.
Get the final granule position of the previous link, assuming Get the final granule position of the previous link, assuming
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment