Permalink
Browse files

changed: upgrade memory based cache to filebased after having been fu…

…ll for 2 seconds without anything reading out of it

By starting out with a memory based cache, then replacing that with a file based one on need we avoid the rather large overhead a file based cache introduces. However it can currently not discern the difference between paused playback on a really fast network, and on a slow one. So if you play over http from local network for example and pause playback. The whole file will be downloaded to local disk at maximum network speed.
  • Loading branch information...
elupus committed Mar 28, 2011
1 parent 2d20fbd commit d633aea81d9ee5045594b2eaeed866d093584907
@@ -43,6 +43,7 @@ class CCacheCircular : public CCacheStrategy
virtual int64_t Seek(int64_t pos) ;
virtual void Reset(int64_t pos) ;
virtual int64_t GetCacheStart() { return m_beg; }
protected:
uint64_t m_beg; /**< index in file (not buffer) of beginning of valid data */
@@ -47,6 +47,7 @@ class CacheMemBuffer : public CCacheStrategy
virtual int64_t Seek(int64_t iFilePosition) ;
virtual void Reset(int64_t iSourcePosition) ;
virtual int64_t GetCacheStart() { return m_nStartPosition; }
protected:
int64_t m_nStartPosition;
@@ -57,6 +57,7 @@ class CCacheStrategy{
virtual void EndOfInput(); // mark the end of the input stream so that Read will know when to return EOF
virtual bool IsEndOfInput();
virtual void ClearEndOfInput();
virtual int64_t GetCacheStart() = 0;
CEvent m_space;
protected:
@@ -81,6 +82,8 @@ class CSimpleFileCache : public CCacheStrategy {
virtual void Reset(int64_t iSourcePosition);
virtual void EndOfInput();
virtual int64_t GetCacheStart() { return m_nStartPosition; }
int64_t GetAvailableRead();
protected:
@@ -29,11 +29,13 @@
#include "threads/SingleLock.h"
#include "utils/log.h"
#include "settings/AdvancedSettings.h"
#include "utils/TimeUtils.h"
using namespace AUTOPTR;
using namespace XFILE;
#define READ_CACHE_CHUNK_SIZE (64*1024)
#define WRITE_CACHE_UPGRADE_TIMEOUT 2000
CFileCache::CFileCache()
{
@@ -122,6 +124,37 @@ bool CFileCache::Open(const CURL& url)
return true;
}
static bool CopyCacheStrategy(CCacheStrategy *dst, CCacheStrategy *src)
{
if(dst->Open() != CACHE_RC_OK)
return false;
dst->Reset(src->GetCacheStart());
if(src->Seek(src->GetCacheStart()) < 0)
return false;
const size_t data_size = 32 * 1024;
auto_aptr<char> data(new char[data_size]);
while(1)
{
int res_r = src->ReadFromCache(data.get(), data_size);
if(res_r == 0 || res_r == CACHE_RC_WOULD_BLOCK)
break;
if(res_r < 0)
return false;
for(int pos = 0, res_w = 0; pos < res_r; pos += res_w)
{
res_w = dst->WriteToCache(data.get()+pos, res_r - pos);
if(res_w <= 0)
return false;
}
}
return true;
}
void CFileCache::Process()
{
if (!m_pCache) {
@@ -181,6 +214,7 @@ void CFileCache::Process()
m_bStop = true;
int iTotalWrite=0;
unsigned iTimeBlocked = 0;
while (!m_bStop && (iTotalWrite < iRead))
{
int iWrite = 0;
@@ -195,9 +229,40 @@ void CFileCache::Process()
break;
}
else if (iWrite == 0)
m_pCache->m_space.WaitMSec(5);
iTotalWrite += iWrite;
{
if(!m_pCache->m_space.WaitMSec(5))
{
if(iTimeBlocked == 0)
iTimeBlocked = CTimeUtils::GetTimeMS();
if(iTimeBlocked + WRITE_CACHE_UPGRADE_TIMEOUT < CTimeUtils::GetTimeMS() && typeid(*m_pCache) != typeid(CSimpleFileCache) )
{
iTimeBlocked = 0;
CSingleLock lock(m_sync);
CCacheStrategy *cache = new CSimpleFileCache();
if(CopyCacheStrategy(cache, m_pCache))
{
CLog::Log(LOGDEBUG, "CFileCache::Process - dumped memory cache to file");
delete m_pCache;
m_pCache = cache;
}
else
{
CLog::Log(LOGERROR, "CFileCache::Process - failed to dump memory cache to file");
delete cache;
}
/* restore correct position */
if(m_pCache->Seek(m_readPos) < 0)
CLog::Log(LOGERROR, "CFileCache::Process - failed to restore file position");
}
}
}
else
{
iTimeBlocked = 0;
iTotalWrite += iWrite;
}
// check if seek was asked. otherwise if cache is full we'll freeze.
if (m_seekEvent.WaitMSec(0))

0 comments on commit d633aea

Please sign in to comment.