Skip to content

Commit

Permalink
Refactor|libdoomsday|FS1|LumpCache: Moved LumpCache impl to lumpcache…
Browse files Browse the repository at this point in the history
….cpp plus cleanup

Its now a lot easier to see how this works...
  • Loading branch information
danij-deng committed Jun 17, 2014
1 parent b7552c9 commit 350da97
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 171 deletions.
8 changes: 3 additions & 5 deletions doomsday/libdoomsday/include/doomsday/filesys/fs_main.h
Expand Up @@ -241,7 +241,7 @@ class LIBDOOMSDAY_PUBLIC FS1
*/
bool mapPath(String &path) const;

#if _DEBUG
#ifdef DENG_DEBUG
void debugPrint() const;
#endif

Expand Down Expand Up @@ -320,8 +320,7 @@ class LIBDOOMSDAY_PUBLIC FS1
* Reset all the schemes, returning their indexes to an empty state and clearing
* any @ref ExtraPaths which have been registered since creation.
*/
inline void resetAllSchemes()
{
inline void resetAllSchemes() {
Schemes schemes = allSchemes();
DENG2_FOR_EACH(Schemes, i, schemes){ (*i)->reset(); }
}
Expand Down Expand Up @@ -596,8 +595,7 @@ LIBDOOMSDAY_PUBLIC de::File1 *F_FindFileForLumpNum(lumpnum_t lumpNum, int *lumpI

LIBDOOMSDAY_PUBLIC void F_Delete(de::FileHandle *hndl);

LIBDOOMSDAY_PUBLIC size_t F_ReadLumpSection(de::File1 *file, int lumpIdx, uint8_t *buffer,
size_t startOffset, size_t length);
LIBDOOMSDAY_PUBLIC size_t F_ReadLumpSection(de::File1 *file, int lumpIdx, uint8_t *buffer, size_t startOffset, size_t length);

LIBDOOMSDAY_PUBLIC uint8_t const *F_CacheLump(de::File1 *file, int lumpIdx);

Expand Down
207 changes: 41 additions & 166 deletions doomsday/libdoomsday/include/doomsday/filesys/lumpcache.h
@@ -1,10 +1,6 @@
/**
* @file lumpcache.h
* Provides a thread-safe data cache tailored to storing lumps (i.e., files).
*
* @ingroup fs
/** @file lumpcache.h Provides a data cache tailored to storing lumps (i.e., files).
*
* @author Copyright &copy; 2013 Daniel Swanson <danij@dengine.net>
* @author Copyright © 2013-2014 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
Expand All @@ -25,191 +21,70 @@
#define LIBDENG_FILESYS_LUMPCACHE_H

#include "../libdoomsday.h"
#include "dd_types.h"
#include <vector>
#include <de/Error>
#include <de/Log>
#include <de/memory.h>
#include <de/memoryzone.h>

/**
* @ingroup fs
*/
class LIBDOOMSDAY_PUBLIC LumpCache
{
private:
class CacheRecord
/**
* Data item. Represents a lump of data in the cache.
*/
class Data
{
public:
explicit CacheRecord(uint8_t* data = 0) : data_(data) {}
~CacheRecord()
{
clearData();
}

uint8_t* data() const
{
if(data_ && Z_GetTag(data_) == PU_PURGELEVEL)
{
// Reaquire the data.
Z_ChangeTag2(data_, PU_APPSTATIC);
Z_ChangeUser(data_, (void*)&data_);
}
return data_;
}

uint8_t const* replaceData(uint8_t* newData)
{
clearData();
data_ = newData;
if(data_)
{
Z_ChangeUser(data_, &data_);
}
return newData;
}

CacheRecord& clearData(bool* retCleared = 0)
{
bool hasData = !!data_;
if(hasData)
{
/// @todo Implement a proper thread-safe locking mechanism.

// Elevate the cached data to purge level so it will be explicitly
// free'd by the Zone the next time the rover passes it.
if(Z_GetTag(data_) != PU_PURGELEVEL)
{
Z_ChangeTag2(data_, PU_PURGELEVEL);
}
// Mark the data as unowned.
Z_ChangeUser(data_, (void*) 0x2);
}
if(retCleared) *retCleared = hasData;
return *this;
}

CacheRecord& lock()
{
/// @todo Implement a proper thread-safe locking mechanism.
return *this;
}

CacheRecord& unlock()
{
/// @todo Implement a proper thread-safe locking mechanism.
if(data_)
{
Z_ChangeTag2(data_, PU_PURGELEVEL);
}
return *this;
}
explicit Data(uint8_t *data = 0);

~Data();

uint8_t *data() const;

uint8_t const *replaceData(uint8_t *newData);

Data &clearData(bool *retCleared = 0);

Data &lock();

Data &unlock();

private:
uint8_t* data_;
uint8_t *data_;
};
typedef std::vector<CacheRecord> DataCache;
typedef std::vector<Data> DataCache;

public:
explicit LumpCache(uint size) : size_(size), dataCache(0)
{}
explicit LumpCache(uint size);
~LumpCache();

~LumpCache()
{
if(dataCache) delete dataCache;
}
uint size() const;

uint size() const { return size_; }
bool isValidIndex(uint idx) const;

bool isValidIndex(uint idx) const { return idx < size_; }
uint8_t const *data(uint lumpIdx) const;

uint8_t const* data(uint lumpIdx) const
{
LOG_AS("LumpCache::data");
CacheRecord const* record = cacheRecord(lumpIdx);
return record? record->data() : 0;
}
LumpCache &insert(uint lumpIdx, uint8_t *data);

LumpCache& insert(uint lumpIdx, uint8_t* data)
{
LOG_AS("LumpCache::insert");
if(!isValidIndex(lumpIdx)) throw de::Error("LumpCache::insert", QString("Invalid index %1").arg(lumpIdx));
LumpCache &insertAndLock(uint lumpIdx, uint8_t *data);

// Time to allocate the data cache?
if(!dataCache)
{
dataCache = new DataCache(size_);
}
LumpCache &lock(uint lumpIdx);

CacheRecord* record = cacheRecord(lumpIdx);
record->replaceData(data);
return *this;
}
LumpCache &unlock(uint lumpIdx);

LumpCache& insertAndLock(uint lumpIdx, uint8_t* data)
{
return insert(lumpIdx, data).lock(lumpIdx);
}
LumpCache &remove(uint lumpIdx, bool *retRemoved = 0);

LumpCache& lock(uint lumpIdx)
{
LOG_AS("LumpCache::lock");
if(!isValidIndex(lumpIdx)) throw de::Error("LumpCache::lock", QString("Invalid index %1").arg(lumpIdx));
CacheRecord* record = cacheRecord(lumpIdx);
record->lock();
return *this;
}

LumpCache& unlock(uint lumpIdx)
{
LOG_AS("LumpCache::unlock");
if(!isValidIndex(lumpIdx)) throw de::Error("LumpCache::unlock", QString("Invalid index %1").arg(lumpIdx));
CacheRecord* record = cacheRecord(lumpIdx);
record->unlock();
return *this;
}

LumpCache& remove(uint lumpIdx, bool* retRemoved = 0)
{
CacheRecord* record = cacheRecord(lumpIdx);
if(record)
{
record->clearData(retRemoved);
}
else if(retRemoved)
{
*retRemoved = false;
}
return *this;
}

LumpCache& clear()
{
if(dataCache)
{
DENG2_FOR_EACH(DataCache, i, *dataCache)
{
i->clearData();
}
}
return *this;
}
LumpCache &clear();

private:
CacheRecord* cacheRecord(uint lumpIdx)
{
if(!isValidIndex(lumpIdx)) return 0;
return dataCache? &(*dataCache)[lumpIdx] : 0;
}
protected:
Data *cacheRecord(uint lumpIdx);

CacheRecord const* cacheRecord(uint lumpIdx) const
{
if(!isValidIndex(lumpIdx)) return 0;
return dataCache? &(*dataCache)[lumpIdx] : 0;
}
Data const *cacheRecord(uint lumpIdx) const;

private:
/// Number of data lumps which can be stored in the cache.
uint size_;

/// The cached data.
DataCache* dataCache;
uint _size; ///< Number of data lumps which can be stored in the cache.
DataCache *_dataCache; ///< The cached data.
};

#endif /* LIBDENG_FILESYS_LUMPCACHE_H */
1 change: 1 addition & 0 deletions doomsday/libdoomsday/libdoomsday.pro
Expand Up @@ -117,6 +117,7 @@ SOURCES += \
src/filesys/fs_main.cpp \
src/filesys/fs_scheme.cpp \
src/filesys/fs_util.cpp \
src/filesys/lumpcache.cpp \
src/filesys/lumpindex.cpp \
src/filesys/searchpath.cpp \
src/filesys/sys_direc.cpp \
Expand Down

0 comments on commit 350da97

Please sign in to comment.