Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #ifndef __UTIL_CACHE_H__ 00020 #define __UTIL_CACHE_H__ 00021 00022 /* Disk Cache based on Hashing 00023 * 00024 * To be used to cache expensive computations. The hash key is created from an 00025 * arbitrary number of bytes, by hashing the bytes using MD5, which then gives 00026 * the file name containing the data. This data then is read from the file 00027 * again into the appropriate data structures. 00028 * 00029 * This way we do not need to accurately track changes, compare dates and 00030 * invalidate cache entries, at the cost of exta computation. If everything 00031 * is stored in a global cache, computations can perhaps even be shared between 00032 * different scenes where it may be hard to detect duplicate work. 00033 */ 00034 00035 #include "util_set.h" 00036 #include "util_string.h" 00037 #include "util_vector.h" 00038 00039 CCL_NAMESPACE_BEGIN 00040 00041 class CacheBuffer { 00042 public: 00043 const void *data; 00044 size_t size; 00045 00046 CacheBuffer(const void *data_, size_t size_) 00047 { data = data_; size = size_; } 00048 }; 00049 00050 class CacheData { 00051 public: 00052 vector<CacheBuffer> buffers; 00053 string name; 00054 string filename; 00055 bool have_filename; 00056 FILE *f; 00057 00058 CacheData(const string& name = ""); 00059 ~CacheData(); 00060 00061 const string& get_filename(); 00062 00063 template<typename T> void add(const vector<T>& data) 00064 { 00065 CacheBuffer buffer(data.size()? &data[0]: NULL, data.size()*sizeof(T)); 00066 buffers.push_back(buffer); 00067 } 00068 00069 template<typename T> void add(const array<T>& data) 00070 { 00071 CacheBuffer buffer(data.size()? &data[0]: NULL, data.size()*sizeof(T)); 00072 buffers.push_back(buffer); 00073 } 00074 00075 void add(void *data, size_t size) 00076 { 00077 if(size) { 00078 CacheBuffer buffer(data, size); 00079 buffers.push_back(buffer); 00080 } 00081 } 00082 00083 void add(int& data) 00084 { 00085 CacheBuffer buffer(&data, sizeof(int)); 00086 buffers.push_back(buffer); 00087 } 00088 00089 void add(float& data) 00090 { 00091 CacheBuffer buffer(&data, sizeof(float)); 00092 buffers.push_back(buffer); 00093 } 00094 00095 void add(size_t& data) 00096 { 00097 CacheBuffer buffer(&data, sizeof(size_t)); 00098 buffers.push_back(buffer); 00099 } 00100 00101 template<typename T> void read(array<T>& data) 00102 { 00103 size_t size; 00104 00105 if(!fread(&size, sizeof(size), 1, f)) { 00106 fprintf(stderr, "Failed to read vector size from cache.\n"); 00107 return; 00108 } 00109 00110 if(!size) 00111 return; 00112 00113 data.resize(size/sizeof(T)); 00114 00115 if(!fread(&data[0], size, 1, f)) { 00116 fprintf(stderr, "Failed to read vector data from cache (%lu).\n", (unsigned long)size); 00117 return; 00118 } 00119 } 00120 00121 void read(int& data) 00122 { 00123 size_t size; 00124 00125 if(!fread(&size, sizeof(size), 1, f)) 00126 fprintf(stderr, "Failed to read int size from cache.\n"); 00127 if(!fread(&data, sizeof(data), 1, f)) 00128 fprintf(stderr, "Failed to read int from cache.\n"); 00129 } 00130 00131 void read(float& data) 00132 { 00133 size_t size; 00134 00135 if(!fread(&size, sizeof(size), 1, f)) 00136 fprintf(stderr, "Failed to read float size from cache.\n"); 00137 if(!fread(&data, sizeof(data), 1, f)) 00138 fprintf(stderr, "Failed to read float from cache.\n"); 00139 } 00140 00141 void read(size_t& data) 00142 { 00143 size_t size; 00144 00145 if(!fread(&size, sizeof(size), 1, f)) 00146 fprintf(stderr, "Failed to read size_t size from cache.\n"); 00147 if(!fread(&data, sizeof(data), 1, f)) 00148 fprintf(stderr, "Failed to read size_t from cache.\n"); 00149 } 00150 }; 00151 00152 class Cache { 00153 public: 00154 static Cache global; 00155 00156 void insert(CacheData& key, CacheData& value); 00157 bool lookup(CacheData& key, CacheData& value); 00158 00159 void clear_except(const string& name, const set<string>& except); 00160 00161 protected: 00162 string data_filename(CacheData& key); 00163 }; 00164 00165 CCL_NAMESPACE_END 00166 00167 #endif /* __UTIL_CACHE_H__ */ 00168