#ifndef HV_FILE_CACHE_H_ #define HV_FILE_CACHE_H_ #include #include #include #include #include "hbuf.h" #include "hstring.h" #define HTTP_HEADER_MAX_LENGTH 1024 // 1K #define FILE_CACHE_MAX_SIZE (1 << 22) // 4M typedef struct file_cache_s { std::string filepath; struct stat st; time_t open_time; time_t stat_time; uint32_t stat_cnt; HBuf buf; // http_header + file_content hbuf_t filebuf; hbuf_t httpbuf; char last_modified[64]; char etag[64]; std::string content_type; file_cache_s() { stat_cnt = 0; } bool is_modified() { time_t mtime = st.st_mtime; stat(filepath.c_str(), &st); return mtime != st.st_mtime; } bool is_complete() { return filebuf.len == st.st_size; } void resize_buf(int filesize) { buf.resize(HTTP_HEADER_MAX_LENGTH + filesize); filebuf.base = buf.base + HTTP_HEADER_MAX_LENGTH; filebuf.len = filesize; } void prepend_header(const char* header, int len) { if (len > HTTP_HEADER_MAX_LENGTH) return; httpbuf.base = filebuf.base - len; httpbuf.len = len + filebuf.len; memcpy(httpbuf.base, header, len); } } file_cache_t; typedef std::shared_ptr file_cache_ptr; // filepath => file_cache_ptr typedef std::map FileCacheMap; class FileCache { public: FileCacheMap cached_files; std::mutex mutex_; int stat_interval; int expired_time; FileCache(); struct OpenParam { bool need_read; int max_read; const char* path; size_t filesize; int error; OpenParam() { need_read = true; max_read = FILE_CACHE_MAX_SIZE; path = "/"; filesize = 0; error = 0; } }; file_cache_ptr Open(const char* filepath, OpenParam* param); bool Close(const char* filepath); bool Close(const file_cache_ptr& fc); void RemoveExpiredFileCache(); protected: file_cache_ptr Get(const char* filepath); }; #endif // HV_FILE_CACHE_H_