/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NIOCACHE__ #define __NIOCACHE__ #include "filesystem/data_store.h" #include "filesystem/io_handle.h" #include "memory/nauto_ptr.h" #include "container/nlist.h" #include "nstring/nstring.h" #include "time/ntime.h" #include "unit/nunit.h" namespace GS { namespace IO { // class CacheHandle : public Handle { friend class Cache; protected: String path; AutoPtr handle; public: CacheHandle(Base *io, const char *p, Handle *h) : Handle(io), path(p), handle(h) {} ~CacheHandle(); }; /*! @short Cached I/O filesystem wrapper. Implements a transparent file cache on top of another filesystem. @author Emmanuel Julien (ejulien@nworks.fr) */ class Cache : public Base { SharedPtr io; DataStore store; public: struct Entry { String path, id; String hash; uint refc; size_t size; Time last_use; Entry() : refc(0), size(0) {} }; private: Threading::Mutex mutex; size_t cache_size; AutoList entries; int ComputeEntryRecyclingScore(const Entry *) const; String ReserveOnStore(size_t size); Entry *GetCacheEntry(const char *path) const; Entry *CreateCacheEntry(const char *path); bool UpdateCacheEntry(Entry *entry, Array *preloaded_data = 0); bool DeleteCacheEntry(Entry *entry); public: virtual uint GetCaps() const; virtual Handle *Open(const char *, Mode = ModeRead); virtual void Close(Handle *); virtual bool Delete(const char *); virtual size_t Tell(Handle *); virtual size_t Seek(Handle *, ptrdiff_t offset, SeekRef = SeekCurrent); virtual size_t Read(Handle *, void *, size_t); virtual size_t Write(Handle *, const void *, size_t); virtual bool MkDir(const char *); /// Test if a given path is in cache. bool IsInCache(const char *path) const { return asbool(GetCacheEntry(path)); } /// Reload cache state from its store. bool SynchronizeWithStore(const char *store_path = "store.db"); Cache(Base *base, Base *store, size_t cache_size = Units::MB(32)); }; } // IO } // GS #endif // __NIOCACHE__