fix quicksort to avoid stack overflow and extreme runtimes

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@14288 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
reimar 2004-12-31 16:02:47 +00:00
parent efa1ae2274
commit a7908eba1b
1 changed files with 22 additions and 6 deletions

View File

@ -44,15 +44,25 @@ static int odml_get_vstream_id(int id, unsigned char res[])
return 0; return 0;
} }
/* /**
* Simple quicksort for AVIINDEXENTRYs * Simple quicksort for AVIINDEXENTRYs
* To avoid too deep recursion, the bigger part is handled iteratively,
* thus limiting recursion to log2(n) levels.
* The pivot element is randomized to "even out" otherwise extreme cases.
*/ */
static void avi_idx_quicksort(AVIINDEXENTRY *idx, int from, int to) static void avi_idx_quicksort(AVIINDEXENTRY *idx, int from, int to)
{ {
AVIINDEXENTRY temp; AVIINDEXENTRY temp;
int lo = to; int lo;
int hi = from; int hi;
off_t pivot_ofs = AVI_IDX_OFFSET(&idx[(from + to) / 2]); off_t pivot_ofs;
int pivot_idx;
while (from < to) {
pivot_idx = from;
pivot_idx += rand() % (to - from + 1);
pivot_ofs = AVI_IDX_OFFSET(&idx[pivot_idx]);
lo = to;
hi = from;
do { do {
while(pivot_ofs < AVI_IDX_OFFSET(&idx[lo])) lo--; while(pivot_ofs < AVI_IDX_OFFSET(&idx[lo])) lo--;
while(pivot_ofs > AVI_IDX_OFFSET(&idx[hi])) hi++; while(pivot_ofs > AVI_IDX_OFFSET(&idx[hi])) hi++;
@ -65,8 +75,14 @@ static void avi_idx_quicksort(AVIINDEXENTRY *idx, int from, int to)
lo--; hi++; lo--; hi++;
} }
} while (lo >= hi); } while (lo >= hi);
if (from < lo) avi_idx_quicksort(idx, from, lo); if ((lo - from) < (to - hi)) {
if (to > hi) avi_idx_quicksort(idx, hi, to); avi_idx_quicksort(idx, from, lo);
from = hi;
} else {
avi_idx_quicksort(idx, hi, to);
to = lo;
}
}
} }
void read_avi_header(demuxer_t *demuxer,int index_mode){ void read_avi_header(demuxer_t *demuxer,int index_mode){