Mercurial > hg > orthanc
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; |