comparison OrthancFramework/Sources/FileStorage/StorageAccessor.cpp @ 4900:ea5f1c6ed07e

fix cache of storage area
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sun, 20 Feb 2022 16:29:33 +0100
parents 43e613a7756b
children 0bb73ef7cf07
comparison
equal deleted inserted replaced
4898:181e67f9d129 4900:ea5f1c6ed07e
131 { 131 {
132 area_.Create(uuid, NULL, 0, type); 132 area_.Create(uuid, NULL, 0, type);
133 } 133 }
134 } 134 }
135 135
136 cache_.Add(uuid, type, data, size); 136 cache_.Add(uuid, type, compressed);
137 return FileInfo(uuid, type, size, md5, 137 return FileInfo(uuid, type, size, md5,
138 CompressionType_ZlibWithSize, compressed.size(), compressedMD5); 138 CompressionType_ZlibWithSize, compressed.size(), compressedMD5);
139 } 139 }
140 140
141 default: 141 default:
154 154
155 155
156 void StorageAccessor::Read(std::string& content, 156 void StorageAccessor::Read(std::string& content,
157 const FileInfo& info) 157 const FileInfo& info)
158 { 158 {
159 if (cache_.Fetch(content, info.GetUuid(), info.GetContentType()))
160 {
161 LOG(INFO) << "Read attachment \"" << info.GetUuid() << "\" "
162 << "content type from cache";
163 return;
164 }
165
166 switch (info.GetCompressionType()) 159 switch (info.GetCompressionType())
167 { 160 {
168 case CompressionType_None: 161 case CompressionType_None:
169 { 162 {
170 MetricsTimer timer(*this, METRICS_READ); 163 if (!cache_.Fetch(content, info.GetUuid(), info.GetContentType()))
171 164 {
172 std::unique_ptr<IMemoryBuffer> buffer(area_.Read(info.GetUuid(), info.GetContentType())); 165 MetricsTimer timer(*this, METRICS_READ);
173 buffer->MoveToString(content); 166 std::unique_ptr<IMemoryBuffer> buffer(area_.Read(info.GetUuid(), info.GetContentType()));
174 167 buffer->MoveToString(content);
175 cache_.Add(info.GetUuid(), info.GetContentType(), content); 168 }
169
176 break; 170 break;
177 } 171 }
178 172
179 case CompressionType_ZlibWithSize: 173 case CompressionType_ZlibWithSize:
180 { 174 {
181 ZlibCompressor zlib; 175 ZlibCompressor zlib;
182 176
183 std::unique_ptr<IMemoryBuffer> compressed; 177 std::string cached;
184 178 if (cache_.Fetch(cached, info.GetUuid(), info.GetContentType()))
185 { 179 {
186 MetricsTimer timer(*this, METRICS_READ); 180 zlib.Uncompress(content, cached.empty() ? NULL : cached.c_str(), cached.size());
187 compressed.reset(area_.Read(info.GetUuid(), info.GetContentType())); 181 }
188 } 182 else
189 183 {
190 zlib.Uncompress(content, compressed->GetData(), compressed->GetSize()); 184 std::unique_ptr<IMemoryBuffer> compressed;
191 185
192 cache_.Add(info.GetUuid(), info.GetContentType(), content); 186 {
187 MetricsTimer timer(*this, METRICS_READ);
188 compressed.reset(area_.Read(info.GetUuid(), info.GetContentType()));
189 }
190
191 zlib.Uncompress(content, compressed->GetData(), compressed->GetSize());
192 }
193
193 break; 194 break;
194 } 195 }
195 196
196 default: 197 default:
197 { 198 {
204 205
205 206
206 void StorageAccessor::ReadRaw(std::string& content, 207 void StorageAccessor::ReadRaw(std::string& content,
207 const FileInfo& info) 208 const FileInfo& info)
208 { 209 {
209 MetricsTimer timer(*this, METRICS_READ); 210 if (!cache_.Fetch(content, info.GetUuid(), info.GetContentType()))
210 211 {
211 std::unique_ptr<IMemoryBuffer> buffer(area_.Read(info.GetUuid(), info.GetContentType())); 212 MetricsTimer timer(*this, METRICS_READ);
212 buffer->MoveToString(content); 213 std::unique_ptr<IMemoryBuffer> buffer(area_.Read(info.GetUuid(), info.GetContentType()));
214 buffer->MoveToString(content);
215 }
213 } 216 }
214 217
215 218
216 void StorageAccessor::Remove(const std::string& fileUuid, 219 void StorageAccessor::Remove(const std::string& fileUuid,
217 FileContentType type) 220 FileContentType type)
218 { 221 {
219 MetricsTimer timer(*this, METRICS_REMOVE);
220 area_.Remove(fileUuid, type);
221
222 cache_.Invalidate(fileUuid, type); 222 cache_.Invalidate(fileUuid, type);
223 223
224 // in ReadStartRange, we might have cached only the start of the file -> try to remove it 224 {
225 if (type == FileContentType_Dicom) 225 MetricsTimer timer(*this, METRICS_REMOVE);
226 { 226 area_.Remove(fileUuid, type);
227 cache_.Invalidate(fileUuid, FileContentType_DicomUntilPixelData); 227 }
228 } 228 }
229 } 229
230 230
231 void StorageAccessor::Remove(const FileInfo &info) 231 void StorageAccessor::Remove(const FileInfo &info)
232 { 232 {
233 Remove(info.GetUuid(), info.GetContentType()); 233 Remove(info.GetUuid(), info.GetContentType());
234 } 234 }
235 235
236 IMemoryBuffer* StorageAccessor::ReadStartRange(const std::string& fileUuid, 236
237 FileContentType contentType, 237 void StorageAccessor::ReadStartRange(std::string& target,
238 uint64_t end /* exclusive */, 238 const std::string& fileUuid,
239 FileContentType startFileContentType) 239 FileContentType contentType,
240 { 240 uint64_t end /* exclusive */)
241 std::string content; 241 {
242 if (cache_.Fetch(content, fileUuid, contentType)) 242 if (cache_.Fetch(target, fileUuid, contentType))
243 { 243 {
244 LOG(INFO) << "Read attachment \"" << fileUuid << "\" " 244 if (target.size() < end)
245 << "(range from " << 0 << " to " << end << ") from cache"; 245 {
246 246 throw OrthancException(ErrorCode_CorruptedFile);
247 return StringMemoryBuffer::CreateFromCopy(content, 0, end); 247 }
248 } 248 else
249 249 {
250 if (cache_.Fetch(content, fileUuid, startFileContentType)) 250 target.resize(end);
251 { 251 }
252 LOG(INFO) << "Read attachment \"" << fileUuid << "\" " 252 }
253 << "(range from " << 0 << " to " << end << ") from cache"; 253 else
254 254 {
255 assert(content.size() == end); 255 MetricsTimer timer(*this, METRICS_READ);
256 return StringMemoryBuffer::CreateFromCopy(content); 256 std::unique_ptr<IMemoryBuffer> buffer(area_.ReadRange(fileUuid, contentType, 0, end));
257 } 257 assert(buffer->GetSize() == end);
258 258 buffer->MoveToString(target);
259 std::unique_ptr<IMemoryBuffer> buffer(area_.ReadRange(fileUuid, contentType, 0, end)); 259 }
260
261 // we've read only the first part of the file -> add an entry in the cache
262 // note the uuid is still the uuid of the full file but the type is the type of the start of the file !
263 assert(buffer->GetSize() == end);
264 cache_.Add(fileUuid, startFileContentType, buffer->GetData(), buffer->GetSize());
265 return buffer.release();
266 } 260 }
267 261
268 262
269 #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1 263 #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
270 void StorageAccessor::SetupSender(BufferHttpSender& sender, 264 void StorageAccessor::SetupSender(BufferHttpSender& sender,
271 const FileInfo& info, 265 const FileInfo& info,
272 const std::string& mime) 266 const std::string& mime)
273 { 267 {
274 if (cache_.Fetch(sender.GetBuffer(), info.GetUuid(), info.GetContentType()))
275 {
276 LOG(INFO) << "Read attachment \"" << info.GetUuid() << "\" "
277 << "content type from cache";
278 }
279 else
280 { 268 {
281 MetricsTimer timer(*this, METRICS_READ); 269 MetricsTimer timer(*this, METRICS_READ);
282 std::unique_ptr<IMemoryBuffer> buffer(area_.Read(info.GetUuid(), info.GetContentType())); 270 std::unique_ptr<IMemoryBuffer> buffer(area_.Read(info.GetUuid(), info.GetContentType()));
283 buffer->MoveToString(sender.GetBuffer()); 271 buffer->MoveToString(sender.GetBuffer());
284
285 cache_.Add(info.GetUuid(), info.GetContentType(), sender.GetBuffer());
286 } 272 }
287 273
288 sender.SetContentType(mime); 274 sender.SetContentType(mime);
289 275
290 const char* extension; 276 const char* extension;