97 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef HV_FILE_CACHE_H_
 | |
| #define HV_FILE_CACHE_H_
 | |
| 
 | |
| #include <memory>
 | |
| #include <map>
 | |
| #include <string>
 | |
| #include <mutex>
 | |
| 
 | |
| #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_t>           file_cache_ptr;
 | |
| // filepath => file_cache_ptr
 | |
| typedef std::map<std::string, file_cache_ptr>   FileCacheMap;
 | |
| 
 | |
| class FileCache {
 | |
| public:
 | |
|     FileCacheMap    cached_files;
 | |
|     std::mutex      mutex_;
 | |
|     int             stat_interval;
 | |
|     int             expired_time;
 | |
| 
 | |
|     FileCache() {
 | |
|         stat_interval = 10; // s
 | |
|         expired_time  = 60; // s
 | |
|     }
 | |
| 
 | |
|     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_
 | 
