Skip to content

Commit 8d153c5

Browse files
author
Timothy B. Terriberry
committed
Avoid rescanning invalid regions during file open.
If there is a large region of invalid data in the middle of the file, avoid scanning it repeatedly during chain boundary enumeration. Because of the bisection, doing that would only be O(n*log(n)), not quadratic like op_get_last_page(), but still good to avoid.
1 parent ec63ede commit 8d153c5

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

src/opusfile.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,7 @@ static int op_bisect_forward_serialno(OggOpusFile *_of,
11891189
/*We guard against garbage separating the last and first pages of two
11901190
links below.*/
11911191
while(_searched<end_searched){
1192+
opus_int64 boundary;
11921193
opus_int32 next_bias;
11931194
/*If we don't have a better estimate, use simple bisection.*/
11941195
if(bisect==-1)bisect=_searched+(end_searched-_searched>>1);
@@ -1199,7 +1200,14 @@ static int op_bisect_forward_serialno(OggOpusFile *_of,
11991200
else end_gp=-1;
12001201
ret=op_seek_helper(_of,bisect);
12011202
if(OP_UNLIKELY(ret<0))return ret;
1202-
last=op_get_next_page(_of,&og,_sr[nsr-1].offset);
1203+
/*If there is a large region of invalid data in the middle of the file,
1204+
avoid scanning it repeatedly.
1205+
Because of the bisection, doing that would only be O(n*log(n)), not
1206+
quadratic like op_get_last_page(), but still good to avoid.*/
1207+
OP_ASSERT(end_searched<=_sr[nsr-1].search_start);
1208+
boundary=OP_MIN(_sr[nsr-1].offset,
1209+
OP_ADV_OFFSET(end_searched,OP_PAGE_SIZE_MAX-1));
1210+
last=op_get_next_page(_of,&og,boundary);
12031211
if(OP_UNLIKELY(last<OP_FALSE))return (int)last;
12041212
next_bias=0;
12051213
if(last==OP_FALSE)end_searched=bisect;

0 commit comments

Comments
 (0)