mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
xbmc: add PR4234
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
3bc6af38d5
commit
61981b6cd2
392
packages/mediacenter/xbmc/patches/xbmc-999.80.005-PR4234.patch
Normal file
392
packages/mediacenter/xbmc/patches/xbmc-999.80.005-PR4234.patch
Normal file
@ -0,0 +1,392 @@
|
||||
From b039984e34db62d1b0d9ac2f673b4658fe0f64a5 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Avison <bavison@riscosopen.org>
|
||||
Date: Wed, 12 Feb 2014 18:43:14 +0000
|
||||
Subject: [PATCH] Improved file buffering in CArchive.
|
||||
|
||||
CArchive already did some file buffering, but only on writes. Added the
|
||||
equivalent code for reads. Also improved the write buffer case so that it
|
||||
only ever issues sector-aligned writes (the read code does this from the
|
||||
start). Shuffled various bits of code into the header file to squeeze a bit
|
||||
more performance out of it.
|
||||
|
||||
Profiled the effect on CFileItemList::Archive(), which is one of the slow
|
||||
parts of the process of reopening a media library, on a non-overclocked
|
||||
Raspberry Pi. Times are in seconds:
|
||||
|
||||
TV shows (253 items)
|
||||
|
||||
Before After
|
||||
Mean StdDev Mean StdDev Confidence Change
|
||||
0.394 0.005 0.151 0.005 100.0% +159.8%
|
||||
|
||||
Songs (4115 items)
|
||||
|
||||
Before After
|
||||
Mean StdDev Mean StdDev Confidence Change
|
||||
2.931 0.045 0.690 0.019 100.0% +324.4%
|
||||
---
|
||||
xbmc/utils/Archive.cpp | 158 ++++++++++++++++++-------------------------------
|
||||
xbmc/utils/Archive.h | 130 ++++++++++++++++++++++++++++++++++------
|
||||
2 files changed, 172 insertions(+), 116 deletions(-)
|
||||
|
||||
diff --git a/xbmc/utils/Archive.cpp b/xbmc/utils/Archive.cpp
|
||||
index 4519e19..b2ad273 100644
|
||||
--- a/xbmc/utils/Archive.cpp
|
||||
+++ b/xbmc/utils/Archive.cpp
|
||||
@@ -30,24 +30,29 @@
|
||||
|
||||
using namespace XFILE;
|
||||
|
||||
-#define BUFFER_MAX 4096
|
||||
-
|
||||
CArchive::CArchive(CFile* pFile, int mode)
|
||||
{
|
||||
m_pFile = pFile;
|
||||
m_iMode = mode;
|
||||
|
||||
- m_pBuffer = new uint8_t[BUFFER_MAX];
|
||||
- memset(m_pBuffer, 0, BUFFER_MAX);
|
||||
-
|
||||
- m_BufferPos = 0;
|
||||
+ m_pBuffer = new uint8_t[CARCHIVE_BUFFER_MAX];
|
||||
+ memset(m_pBuffer, 0, CARCHIVE_BUFFER_MAX);
|
||||
+ if (mode == load)
|
||||
+ {
|
||||
+ m_BufferPos = m_pBuffer + CARCHIVE_BUFFER_MAX;
|
||||
+ m_BufferRemain = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ m_BufferPos = m_pBuffer;
|
||||
+ m_BufferRemain = CARCHIVE_BUFFER_MAX;
|
||||
+ }
|
||||
}
|
||||
|
||||
CArchive::~CArchive()
|
||||
{
|
||||
FlushBuffer();
|
||||
delete[] m_pBuffer;
|
||||
- m_BufferPos = 0;
|
||||
}
|
||||
|
||||
void CArchive::Close()
|
||||
@@ -214,89 +219,6 @@ bool CArchive::IsStoring()
|
||||
return *this;
|
||||
}
|
||||
|
||||
-inline CArchive& CArchive::streamout(const void* dataPtr, size_t size)
|
||||
-{
|
||||
- const uint8_t* ptr = (const uint8_t*)dataPtr;
|
||||
-
|
||||
- if (size + m_BufferPos >= BUFFER_MAX)
|
||||
- {
|
||||
- FlushBuffer();
|
||||
- while (size >= BUFFER_MAX)
|
||||
- {
|
||||
- memcpy(m_pBuffer, ptr, BUFFER_MAX);
|
||||
- m_BufferPos = BUFFER_MAX;
|
||||
- ptr += BUFFER_MAX;
|
||||
- size -= BUFFER_MAX;
|
||||
- FlushBuffer();
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- memcpy(m_pBuffer + m_BufferPos, ptr, size);
|
||||
- m_BufferPos += size;
|
||||
-
|
||||
- return *this;
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(float& f)
|
||||
-{
|
||||
- return streamin(&f, sizeof(f));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(double& d)
|
||||
-{
|
||||
- return streamin(&d, sizeof(d));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(short int& s)
|
||||
-{
|
||||
- return streamin(&s, sizeof(s));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(unsigned short int& us)
|
||||
-{
|
||||
- return streamin(&us, sizeof(us));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(int& i)
|
||||
-{
|
||||
- return streamin(&i, sizeof(i));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(unsigned int& ui)
|
||||
-{
|
||||
- return streamin(&ui, sizeof(ui));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(long int& l)
|
||||
-{
|
||||
- return streamin(&l, sizeof(l));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(unsigned long int& ul)
|
||||
-{
|
||||
- return streamin(&ul, sizeof(ul));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(long long int& ll)
|
||||
-{
|
||||
- return streamin(&ll, sizeof(ll));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(unsigned long long int& ull)
|
||||
-{
|
||||
- return streamin(&ull, sizeof(ull));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(bool& b)
|
||||
-{
|
||||
- return streamin(&b, sizeof(b));
|
||||
-}
|
||||
-
|
||||
-CArchive& CArchive::operator>>(char& c)
|
||||
-{
|
||||
- return streamin(&c, sizeof(c));
|
||||
-}
|
||||
-
|
||||
CArchive& CArchive::operator>>(std::string& str)
|
||||
{
|
||||
size_t iLength = 0;
|
||||
@@ -450,23 +372,61 @@ bool CArchive::IsStoring()
|
||||
return *this;
|
||||
}
|
||||
|
||||
-inline CArchive& CArchive::streamin(void* dataPtr, const size_t size)
|
||||
+void CArchive::FlushBuffer()
|
||||
{
|
||||
- size_t read = m_pFile->Read(dataPtr, size);
|
||||
- if (read < size)
|
||||
+ if (m_iMode == store && m_BufferPos != m_pBuffer)
|
||||
{
|
||||
- CLog::Log(LOGERROR, "%s: can't stream out: requested %lu bytes, was read %lu bytes", __FUNCTION__, (unsigned long)size, (unsigned long)read);
|
||||
- memset(dataPtr, 0, size);
|
||||
+ m_pFile->Write(m_pBuffer, m_BufferPos - m_pBuffer);
|
||||
+ m_BufferPos = m_pBuffer;
|
||||
+ m_BufferRemain = CARCHIVE_BUFFER_MAX;
|
||||
}
|
||||
+}
|
||||
|
||||
+CArchive &CArchive::streamout_bufferwrap(const uint8_t *ptr, size_t size)
|
||||
+{
|
||||
+ do
|
||||
+ {
|
||||
+ size_t chunkSize = std::min(size, m_BufferRemain);
|
||||
+ m_BufferPos = std::copy(ptr, ptr + chunkSize, m_BufferPos);
|
||||
+ ptr += chunkSize;
|
||||
+ size -= chunkSize;
|
||||
+ m_BufferRemain -= chunkSize;
|
||||
+ if (m_BufferRemain == 0)
|
||||
+ FlushBuffer();
|
||||
+ } while (size > 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
-void CArchive::FlushBuffer()
|
||||
+void CArchive::FillBuffer()
|
||||
{
|
||||
- if (m_BufferPos > 0)
|
||||
+ if (m_iMode == load && m_BufferRemain == 0)
|
||||
{
|
||||
- m_pFile->Write(m_pBuffer, m_BufferPos);
|
||||
- m_BufferPos = 0;
|
||||
+ m_BufferRemain = m_pFile->Read(m_pBuffer, CARCHIVE_BUFFER_MAX);
|
||||
+ m_BufferPos = m_pBuffer;
|
||||
}
|
||||
}
|
||||
+
|
||||
+CArchive &CArchive::streamin_bufferwrap(uint8_t *ptr, size_t size)
|
||||
+{
|
||||
+ uint8_t *orig_ptr = ptr;
|
||||
+ size_t orig_size = size;
|
||||
+ do
|
||||
+ {
|
||||
+ if (m_BufferRemain == 0)
|
||||
+ {
|
||||
+ FillBuffer();
|
||||
+ if (m_BufferRemain < CARCHIVE_BUFFER_MAX && m_BufferRemain < size)
|
||||
+ {
|
||||
+ CLog::Log(LOGERROR, "%s: can't stream in: requested %lu bytes, was read %lu bytes", __FUNCTION__, (unsigned long) orig_size, (unsigned long) (ptr - orig_ptr + m_BufferRemain));
|
||||
+ memset(orig_ptr, 0, orig_size);
|
||||
+ return *this;
|
||||
+ }
|
||||
+ }
|
||||
+ size_t chunkSize = std::min(size, m_BufferRemain);
|
||||
+ ptr = std::copy(m_BufferPos, m_BufferPos + chunkSize, ptr);
|
||||
+ m_BufferPos += chunkSize;
|
||||
+ m_BufferRemain -= chunkSize;
|
||||
+ size -= chunkSize;
|
||||
+ } while (size > 0);
|
||||
+ return *this;
|
||||
+}
|
||||
diff --git a/xbmc/utils/Archive.h b/xbmc/utils/Archive.h
|
||||
index 0148fcb..5b25be5 100644
|
||||
--- a/xbmc/utils/Archive.h
|
||||
+++ b/xbmc/utils/Archive.h
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <vector>
|
||||
#include "PlatformDefs.h" // for SYSTEMTIME
|
||||
|
||||
+#define CARCHIVE_BUFFER_MAX 4096
|
||||
+
|
||||
namespace XFILE
|
||||
{
|
||||
class CFile;
|
||||
@@ -77,18 +79,66 @@ class CArchive
|
||||
CArchive& operator<<(const std::vector<int>& iArray);
|
||||
|
||||
// loading
|
||||
- CArchive& operator>>(float& f);
|
||||
- CArchive& operator>>(double& d);
|
||||
- CArchive& operator>>(short int& s);
|
||||
- CArchive& operator>>(unsigned short int& us);
|
||||
- CArchive& operator>>(int& i);
|
||||
- CArchive& operator>>(unsigned int& ui);
|
||||
- CArchive& operator>>(long int& l);
|
||||
- CArchive& operator>>(unsigned long int& ul);
|
||||
- CArchive& operator>>(long long int& ll);
|
||||
- CArchive& operator>>(unsigned long long int& ull);
|
||||
- CArchive& operator>>(bool& b);
|
||||
- CArchive& operator>>(char& c);
|
||||
+ inline CArchive& operator>>(float& f)
|
||||
+ {
|
||||
+ return streamin(&f, sizeof(f));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(double& d)
|
||||
+ {
|
||||
+ return streamin(&d, sizeof(d));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(short int& s)
|
||||
+ {
|
||||
+ return streamin(&s, sizeof(s));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(unsigned short int& us)
|
||||
+ {
|
||||
+ return streamin(&us, sizeof(us));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(int& i)
|
||||
+ {
|
||||
+ return streamin(&i, sizeof(i));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(unsigned int& ui)
|
||||
+ {
|
||||
+ return streamin(&ui, sizeof(ui));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(long int& l)
|
||||
+ {
|
||||
+ return streamin(&l, sizeof(l));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(unsigned long int& ul)
|
||||
+ {
|
||||
+ return streamin(&ul, sizeof(ul));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(long long int& ll)
|
||||
+ {
|
||||
+ return streamin(&ll, sizeof(ll));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(unsigned long long int& ull)
|
||||
+ {
|
||||
+ return streamin(&ull, sizeof(ull));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(bool& b)
|
||||
+ {
|
||||
+ return streamin(&b, sizeof(b));
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive& operator>>(char& c)
|
||||
+ {
|
||||
+ return streamin(&c, sizeof(c));
|
||||
+ }
|
||||
+
|
||||
CArchive& operator>>(std::string &str);
|
||||
CArchive& operator>>(std::wstring& wstr);
|
||||
CArchive& operator>>(SYSTEMTIME& time);
|
||||
@@ -105,12 +155,58 @@ class CArchive
|
||||
enum Mode {load = 0, store};
|
||||
|
||||
protected:
|
||||
- CArchive& streamout(const void* dataPtr, size_t size);
|
||||
- CArchive& streamin(void* dataPtr, const size_t size);
|
||||
- void FlushBuffer();
|
||||
+ inline CArchive &streamout(const void *dataPtr, size_t size)
|
||||
+ {
|
||||
+ const uint8_t *ptr = (const uint8_t *) dataPtr;
|
||||
+ /* Note, the buffer is flushed as soon as it is full (m_BufferRemain == size) rather
|
||||
+ * than waiting until we attempt to put more data into an already full buffer */
|
||||
+ if (m_BufferRemain > size)
|
||||
+ {
|
||||
+ switch (size)
|
||||
+ {
|
||||
+ case 1: *m_BufferPos++ = *ptr; m_BufferRemain--; break;
|
||||
+ case 2: *(uint16_t *) m_BufferPos = *(const uint16_t *) ptr; m_BufferPos += 2; m_BufferRemain -= 2; break;
|
||||
+ case 4: *(uint32_t *) m_BufferPos = *(const uint32_t *) ptr; m_BufferPos += 4; m_BufferRemain -= 4; break;
|
||||
+ default: m_BufferPos = std::copy(ptr, ptr + size, m_BufferPos); m_BufferRemain -= size; break;
|
||||
+ }
|
||||
+ return *this;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return streamout_bufferwrap(ptr, size);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ inline CArchive &streamin(void *dataPtr, size_t size)
|
||||
+ {
|
||||
+ uint8_t *ptr = (uint8_t *) dataPtr;
|
||||
+ /* Note, refilling the buffer is deferred until we know we need to read more from it */
|
||||
+ if (m_BufferRemain >= size)
|
||||
+ {
|
||||
+ switch (size)
|
||||
+ {
|
||||
+ case 1: *ptr = *m_BufferPos++; m_BufferRemain--; break;
|
||||
+ case 2: *(uint16_t *) ptr = *(const uint16_t *) m_BufferPos; m_BufferPos += 2; m_BufferRemain -= 2; break;
|
||||
+ case 4: *(uint32_t *) ptr = *(const uint32_t *) m_BufferPos; m_BufferPos += 4; m_BufferRemain -= 4; break;
|
||||
+ default: std::copy(m_BufferPos, m_BufferPos + size, ptr); m_BufferPos += size; m_BufferRemain -= size; break;
|
||||
+ }
|
||||
+ return *this;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return streamin_bufferwrap(ptr, size);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
XFILE::CFile* m_pFile;
|
||||
int m_iMode;
|
||||
uint8_t *m_pBuffer;
|
||||
- int m_BufferPos;
|
||||
-};
|
||||
+ uint8_t *m_BufferPos;
|
||||
+ size_t m_BufferRemain;
|
||||
|
||||
+private:
|
||||
+ void FlushBuffer();
|
||||
+ CArchive &streamout_bufferwrap(const uint8_t *ptr, size_t size);
|
||||
+ void FillBuffer();
|
||||
+ CArchive &streamin_bufferwrap(uint8_t *ptr, size_t size);
|
||||
+};
|
||||
--
|
||||
1.8.5.1
|
||||
|
Loading…
x
Reference in New Issue
Block a user