mirror of
https://github.com/telegramdesktop/tdesktop
synced 2024-12-26 16:43:33 +00:00
Improve working with cache in streaming.
This commit is contained in:
parent
b6a757842a
commit
44df10d6cb
@ -137,6 +137,7 @@ void Player::trackReceivedTill(
|
||||
}
|
||||
}
|
||||
|
||||
static auto wakes = 0;
|
||||
template <typename Track>
|
||||
void Player::trackPlayedTill(
|
||||
const Track &track,
|
||||
@ -152,6 +153,7 @@ void Player::trackPlayedTill(
|
||||
if (_pauseReading && !bothReceivedEnough(kLoadInAdvanceFor)) {
|
||||
_pauseReading = false;
|
||||
_file->wake();
|
||||
++wakes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,7 +419,8 @@ bool Player::trackReceivedEnough(
|
||||
const TrackState &state,
|
||||
crl::time amount) const {
|
||||
return FullTrackReceived(state)
|
||||
|| (state.position + amount <= state.receivedTill);
|
||||
|| (state.position != kTimeUnknown
|
||||
&& state.position + amount <= state.receivedTill);
|
||||
}
|
||||
|
||||
bool Player::bothReceivedEnough(crl::time amount) const {
|
||||
@ -569,6 +572,7 @@ Player::~Player() {
|
||||
//
|
||||
// So instead of maintaining it in the class definition as well we
|
||||
// simply call stop() here, after that the destruction is trivial.
|
||||
LOG(("WAKES: %1").arg(wakes));
|
||||
stop();
|
||||
}
|
||||
|
||||
|
@ -357,19 +357,15 @@ auto Reader::Slices::fill(int offset, bytes::span buffer) -> FillResult {
|
||||
&& (fromSlice + 1 == tillSlice || fromSlice + 2 == tillSlice)
|
||||
&& tillSlice <= _data.size());
|
||||
|
||||
const auto cacheNotLoaded = [&](int sliceIndex) {
|
||||
return (_headerMode != HeaderMode::NoCache)
|
||||
&& (_headerMode != HeaderMode::Unknown)
|
||||
&& !(_data[sliceIndex].flags & Flag::LoadedFromCache);
|
||||
};
|
||||
const auto handlePrepareResult = [&](
|
||||
int sliceIndex,
|
||||
const Slice::PrepareFillResult &prepared) {
|
||||
if (sliceIndex == _data.size()) {
|
||||
return;
|
||||
}
|
||||
if (!(_data[sliceIndex].flags & Flag::LoadedFromCache)
|
||||
&& _headerMode != HeaderMode::NoCache
|
||||
&& _headerMode != HeaderMode::Unknown) {
|
||||
if (!(_data[sliceIndex].flags & Flag::LoadingFromCache)) {
|
||||
_data[sliceIndex].flags |= Flag::LoadingFromCache;
|
||||
result.sliceNumbersFromCache.add(sliceIndex + 1);
|
||||
}
|
||||
if (cacheNotLoaded(sliceIndex)) {
|
||||
return;
|
||||
}
|
||||
for (const auto offset : prepared.offsetsFromLoader.values()) {
|
||||
@ -379,7 +375,16 @@ auto Reader::Slices::fill(int offset, bytes::span buffer) -> FillResult {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const auto handleReadFromCache = [&](int sliceIndex) {
|
||||
if (cacheNotLoaded(sliceIndex)
|
||||
&& !(_data[sliceIndex].flags & Flag::LoadingFromCache)) {
|
||||
_data[sliceIndex].flags |= Flag::LoadingFromCache;
|
||||
if (sliceIndex == 23) {
|
||||
int a = 0;
|
||||
}
|
||||
result.sliceNumbersFromCache.add(sliceIndex + 1);
|
||||
}
|
||||
};
|
||||
const auto firstFrom = offset - fromSlice * kInSlice;
|
||||
const auto firstTill = std::min(kInSlice, till - fromSlice * kInSlice);
|
||||
const auto secondFrom = 0;
|
||||
@ -389,7 +394,9 @@ auto Reader::Slices::fill(int offset, bytes::span buffer) -> FillResult {
|
||||
? _data[fromSlice + 1].prepareFill(secondFrom, secondTill)
|
||||
: Slice::PrepareFillResult();
|
||||
handlePrepareResult(fromSlice, first);
|
||||
handlePrepareResult(fromSlice + 1, second);
|
||||
if (fromSlice + 1 < tillSlice) {
|
||||
handlePrepareResult(fromSlice + 1, second);
|
||||
}
|
||||
if (first.ready && second.ready) {
|
||||
markSliceUsed(fromSlice);
|
||||
CopyLoaded(
|
||||
@ -405,18 +412,13 @@ auto Reader::Slices::fill(int offset, bytes::span buffer) -> FillResult {
|
||||
secondFrom,
|
||||
secondTill);
|
||||
}
|
||||
if (_usedSlices.size() > kSlicesInMemory
|
||||
&& _headerMode != HeaderMode::Unknown) {
|
||||
const auto purgeSlice = _usedSlices.front();
|
||||
_usedSlices.pop_front();
|
||||
if (_headerMode == HeaderMode::NoCache
|
||||
|| !(_data[purgeSlice].flags & Flag::ChangedSinceCache)) {
|
||||
_data[purgeSlice] = Slice();
|
||||
} else {
|
||||
result.toCache = serializeAndUnloadSlice(purgeSlice + 1);
|
||||
}
|
||||
}
|
||||
result.toCache = serializeAndUnloadUnused();
|
||||
result.filled = true;
|
||||
} else {
|
||||
handleReadFromCache(fromSlice);
|
||||
if (fromSlice + 1 < tillSlice) {
|
||||
handleReadFromCache(fromSlice + 1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -442,6 +444,24 @@ int Reader::Slices::maxSliceSize(int sliceNumber) const {
|
||||
: _size;
|
||||
}
|
||||
|
||||
Reader::SerializedSlice Reader::Slices::serializeAndUnloadUnused() {
|
||||
if (_headerMode == HeaderMode::Unknown
|
||||
|| _usedSlices.size() <= kSlicesInMemory) {
|
||||
return {};
|
||||
}
|
||||
const auto purgeSlice = _usedSlices.front();
|
||||
_usedSlices.pop_front();
|
||||
if (!(_data[purgeSlice].flags & Slice::Flag::LoadedFromCache)) {
|
||||
// If the only data in this slice was from _header, just leave it.
|
||||
return {};
|
||||
} else if (_headerMode == HeaderMode::NoCache
|
||||
|| !(_data[purgeSlice].flags & Slice::Flag::ChangedSinceCache)) {
|
||||
_data[purgeSlice] = Slice();
|
||||
return {};
|
||||
}
|
||||
return serializeAndUnloadSlice(purgeSlice + 1);
|
||||
}
|
||||
|
||||
Reader::SerializedSlice Reader::Slices::serializeAndUnloadSlice(
|
||||
int sliceNumber) {
|
||||
Expects(sliceNumber >= 0 && sliceNumber <= _data.size());
|
||||
|
@ -127,6 +127,7 @@ private:
|
||||
void applyHeaderCacheData();
|
||||
int maxSliceSize(int sliceNumber) const;
|
||||
SerializedSlice serializeAndUnloadSlice(int sliceNumber);
|
||||
SerializedSlice serializeAndUnloadUnused();
|
||||
void markSliceUsed(int sliceIndex);
|
||||
|
||||
std::vector<Slice> _data;
|
||||
|
Loading…
Reference in New Issue
Block a user