Merge pull request #4111 from MilhouseVH/le10_kodi19-fix-cache

kodi: fix caching issue accessing repositories
This commit is contained in:
CvH 2020-01-12 20:51:28 +01:00 committed by GitHub
commit fba2da9d7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -0,0 +1,197 @@
From a31feadb4ed74fadea8ea5628f2ff8775d8fe870 Mon Sep 17 00:00:00 2001
From: arnova <arnova@void.org>
Date: Fri, 27 Dec 2019 11:06:41 +0100
Subject: [PATCH 1/3] fixed: Caching of small files was broken
---
xbmc/filesystem/FileCache.cpp | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp
index 8541990b5f78..2ba184cdcde5 100644
--- a/xbmc/filesystem/FileCache.cpp
+++ b/xbmc/filesystem/FileCache.cpp
@@ -164,6 +164,10 @@ bool CFileCache::Open(const CURL& url)
cacheSize = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_cacheMemSize;
}
+ // Cap chunk size by cache size
+ if (m_chunkSize > cacheSize)
+ m_chunkSize = cacheSize;
+
size_t back = cacheSize / 4;
size_t front = cacheSize - back;
@@ -292,20 +296,25 @@ void CFileCache::Process()
}
}
- size_t maxWrite = m_pCache->GetMaxWriteSize(m_chunkSize);
+ const int64_t maxWrite = m_pCache->GetMaxWriteSize(m_chunkSize);
+ int64_t maxSourceRead = m_chunkSize;
+ // Cap source read size by space available between current write position and EOF
+ if (m_fileSize != 0)
+ maxSourceRead = std::min(maxSourceRead, m_fileSize - m_writePos);
/* Only read from source if there's enough write space in the cache
* else we may keep disposing data and seeking back on (slow) source
*/
- if (maxWrite < m_chunkSize && !cacheReachEOF)
+ if (maxWrite < maxSourceRead && !cacheReachEOF)
{
+ // Wait until sufficient cache write space is available
m_pCache->m_space.WaitMSec(5);
continue;
}
ssize_t iRead = 0;
if (!cacheReachEOF)
- iRead = m_source.Read(buffer.get(), m_chunkSize);
+ iRead = m_source.Read(buffer.get(), maxSourceRead);
if (iRead == 0)
{
// Check for actual EOF and retry as long as we still have data in our cache
From 431e10a5e4d9cf09e80adda8f66654cd83962ac4 Mon Sep 17 00:00:00 2001
From: arnova <arnova@void.org>
Date: Sat, 28 Dec 2019 10:01:34 +0100
Subject: [PATCH 2/3] fixed: Cache forward size wasn't updated when source EOF
was hit
---
xbmc/filesystem/FileCache.cpp | 13 +++++--------
xbmc/filesystem/FileCache.h | 1 -
2 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp
index 2ba184cdcde5..fae41d141399 100644
--- a/xbmc/filesystem/FileCache.cpp
+++ b/xbmc/filesystem/FileCache.cpp
@@ -90,7 +90,6 @@ CFileCache::CFileCache(const unsigned int flags)
, m_writeRate(0)
, m_writeRateActual(0)
, m_forwardCacheSize(0)
- , m_forward(0)
, m_bFilling(false)
, m_bLowSpeedDetected(false)
, m_fileSize(0)
@@ -200,7 +199,6 @@ bool CFileCache::Open(const CURL& url)
m_writePos = 0;
m_writeRate = 1024 * 1024;
m_writeRateActual = 0;
- m_forward = 0;
m_bFilling = true;
m_bLowSpeedDetected = false;
m_seekEvent.Reset();
@@ -268,7 +266,6 @@ void CFileCache::Process()
CLog::Log(LOGDEBUG,
"CFileCache::Process - Cache completely reset for seek to position %" PRId64,
m_seekPos);
- m_forward = 0;
m_bFilling = true;
m_bLowSpeedDetected = false;
}
@@ -400,11 +397,11 @@ void CFileCache::Process()
// avoid uncertainty at start of caching
m_writeRateActual = average.Rate(m_writePos, 1000);
- // Update forward cache size
- m_forward = m_pCache->WaitForData(0, 0);
-
// NOTE: Hysteresis (20-80%) for filling-logic
- const float level = (m_forwardCacheSize == 0) ? 0.0 : (float) m_forward / m_forwardCacheSize;
+ const int64_t forward = m_pCache->WaitForData(0, 0);
+ const float level =
+ (m_forwardCacheSize == 0) ? 0.0 : static_cast<float>(forward / m_forwardCacheSize);
+
if (level > 0.8f)
{
/* NOTE: We can only reliably test for low speed condition, when the cache is *really*
@@ -589,7 +586,7 @@ int CFileCache::IoControl(EIoControl request, void* param)
if (request == IOCTRL_CACHE_STATUS)
{
SCacheStatus* status = (SCacheStatus*)param;
- status->forward = m_forward;
+ status->forward = m_pCache->WaitForData(0, 0);
status->maxrate = m_writeRate;
status->currate = m_writeRateActual;
status->lowspeed = m_bLowSpeedDetected;
diff --git a/xbmc/filesystem/FileCache.h b/xbmc/filesystem/FileCache.h
index d6641fbed235..87cd92e9bc1b 100644
--- a/xbmc/filesystem/FileCache.h
+++ b/xbmc/filesystem/FileCache.h
@@ -69,7 +69,6 @@ namespace XFILE
unsigned m_writeRate;
unsigned m_writeRateActual;
int64_t m_forwardCacheSize;
- int64_t m_forward;
bool m_bFilling;
bool m_bLowSpeedDetected;
std::atomic<int64_t> m_fileSize;
From ffb01823b525b66cf7dcd22f70c8d0f3d26a166e Mon Sep 17 00:00:00 2001
From: arnova <arnova@void.org>
Date: Sun, 29 Dec 2019 11:17:56 +0100
Subject: [PATCH 3/3] changed: Improve logic for determining memory cache size
---
xbmc/filesystem/FileCache.cpp | 37 +++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/xbmc/filesystem/FileCache.cpp b/xbmc/filesystem/FileCache.cpp
index fae41d141399..1f8738568593 100644
--- a/xbmc/filesystem/FileCache.cpp
+++ b/xbmc/filesystem/FileCache.cpp
@@ -155,27 +155,40 @@ bool CFileCache::Open(const CURL& url)
size_t cacheSize;
if (m_fileSize > 0 && m_fileSize < CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_cacheMemSize && !(m_flags & READ_AUDIO_VIDEO))
{
- // NOTE: We don't need to take into account READ_MULTI_STREAM here as it's only used for audio/video
+ // Cap cache size by filesize, but not for audio/video files as those may grow.
+ // We don't need to take into account READ_MULTI_STREAM here as that's only used for audio/video
cacheSize = m_fileSize;
+
+ // Cap chunk size by cache size
+ if (m_chunkSize > cacheSize)
+ m_chunkSize = cacheSize;
}
else
{
cacheSize = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_cacheMemSize;
- }
- // Cap chunk size by cache size
- if (m_chunkSize > cacheSize)
- m_chunkSize = cacheSize;
+ // NOTE: READ_MULTI_STREAM is only used with READ_AUDIO_VIDEO
+ if (m_flags & READ_MULTI_STREAM)
+ {
+ // READ_MULTI_STREAM requires double buffering, so use half the amount of memory for each buffer
+ cacheSize /= 2;
+ }
- size_t back = cacheSize / 4;
- size_t front = cacheSize - back;
+ // Make sure cache can at least hold 2 chunks
+ if (cacheSize < m_chunkSize * 2)
+ cacheSize = m_chunkSize * 2;
+ }
if (m_flags & READ_MULTI_STREAM)
- {
- // READ_MULTI_STREAM requires double buffering, so use half the amount of memory for each buffer
- front /= 2;
- back /= 2;
- }
+ CLog::Log(LOGDEBUG, "CFileCache::Open - Using double memory cache each sized %i bytes",
+ cacheSize);
+ else
+ CLog::Log(LOGDEBUG, "CFileCache::Open - Using single memory cache sized %i bytes",
+ cacheSize);
+
+ const size_t back = cacheSize / 4;
+ const size_t front = cacheSize - back;
+
m_pCache = std::unique_ptr<CCircularCache>(new CCircularCache(front, back)); // C++14 - Replace with std::make_unique
m_forwardCacheSize = front;
}