track/audioplaybackcache: re-did binary search algorithms

Fixes #1617
Fixes #1615
This commit is contained in:
itsmattkc
2021-05-10 10:42:07 +10:00
parent febb5b0d25
commit 8383929476
2 changed files with 28 additions and 36 deletions
+17 -21
View File
@@ -377,26 +377,6 @@ Block *Track::NearestBlockAfter(const rational &time) const
return nullptr;
}
Block* BlockAtTimeBinarySearch(const QVector<Block*>& blocks, int first, int last, const rational& time)
{
int middle;
if (last >= first) {
middle = (first + last) / 2;
Block* block = blocks.at(middle);
if (block->in() <= time && block->out() > time) {
return block;
} else if (block->out() < time) {
return BlockAtTimeBinarySearch(blocks, middle + 1, last, time);
} else {
return BlockAtTimeBinarySearch(blocks, first, middle - 1, time);
}
}
return nullptr;
}
Block *Track::BlockAtTime(const rational &time) const
{
if (IsMuted() || time > track_length() || blocks_.isEmpty()) {
@@ -404,7 +384,23 @@ Block *Track::BlockAtTime(const rational &time) const
}
// Use binary search to find block at time
Block* using_block = BlockAtTimeBinarySearch(blocks_, 0, blocks_.size(), time);
Block* using_block = nullptr;
int low = 0;
int high = blocks_.size() - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
Block* block = blocks_.at(mid);
if (block->in() <= time && block->out() > time) {
using_block = block;
break;
} else if (block->out() <= time) {
low = mid + 1;
} else {
high = mid - 1;
}
}
if (using_block && !using_block->is_enabled()) {
using_block = nullptr;
+11 -15
View File
@@ -508,27 +508,23 @@ int AudioPlaybackCache::Playlist::GetIndexOfPosition(qint64 pos)
return this->size() - 1;
}
int bottom = 0;
int top = this->size();
// Use a binary search to find the segment with the right offset
while (true) {
int mid = bottom + (top - bottom)/2;
int low = 0;
int high = this->size() - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
const Segment& mid_segment = this->at(mid);
if (mid_segment.offset() <= pos
&& mid_segment.offset() + mid_segment.size() > pos) {
if (mid_segment.offset() <= pos && mid_segment.offset() + mid_segment.size() > pos) {
return mid;
}
if (mid_segment.offset() > pos) {
// Segment we're looking for must be lower
top = mid;
} else if (mid_segment.offset() < pos) {
low = mid + 1;
} else {
// Segment we're looking for must be higher
bottom = mid;
high = mid - 1;
}
}
return -1;
}
qint64 AudioPlaybackCache::Playlist::GetLength() const