# HG changeset patch # User Sebastien Jodogne # Date 1645435700 -3600 # Node ID 1cd1b8f58e56d327c8febc60e675c97ad4aec040 # Parent f4a41cc17ac6b448de5b1d5f24f9762b1782af8e# Parent d17a81fa7350a1a0f4bc2e8afb8b6c36f8411f8a merge diff -r f4a41cc17ac6 -r 1cd1b8f58e56 OrthancFramework/Sources/FileStorage/StorageAccessor.cpp --- a/OrthancFramework/Sources/FileStorage/StorageAccessor.cpp Mon Feb 21 10:28:08 2022 +0100 +++ b/OrthancFramework/Sources/FileStorage/StorageAccessor.cpp Mon Feb 21 10:28:20 2022 +0100 @@ -239,16 +239,9 @@ FileContentType contentType, uint64_t end /* exclusive */) { - if (cache_.Fetch(target, fileUuid, contentType)) + if (cache_.FetchStartRange(target, fileUuid, contentType, end)) { - if (target.size() < end) - { - throw OrthancException(ErrorCode_CorruptedFile); - } - else - { - target.resize(end); - } + return; } else { @@ -256,6 +249,8 @@ std::unique_ptr buffer(area_.ReadRange(fileUuid, contentType, 0, end)); assert(buffer->GetSize() == end); buffer->MoveToString(target); + + cache_.AddStartRange(fileUuid, contentType, target); } } @@ -270,6 +265,8 @@ MetricsTimer timer(*this, METRICS_READ); std::unique_ptr buffer(area_.Read(info.GetUuid(), info.GetContentType())); buffer->MoveToString(sender.GetBuffer()); + + cache_.Add(info.GetUuid(), info.GetContentType(), sender.GetBuffer()); } sender.SetContentType(mime); diff -r f4a41cc17ac6 -r 1cd1b8f58e56 OrthancFramework/Sources/FileStorage/StorageCache.cpp --- a/OrthancFramework/Sources/FileStorage/StorageCache.cpp Mon Feb 21 10:28:08 2022 +0100 +++ b/OrthancFramework/Sources/FileStorage/StorageCache.cpp Mon Feb 21 10:28:20 2022 +0100 @@ -33,12 +33,17 @@ namespace Orthanc { - static std::string GetCacheKey(const std::string& uuid, - FileContentType contentType) + static std::string GetCacheKeyFullFile(const std::string& uuid, + FileContentType contentType) { - return uuid + ":" + boost::lexical_cast(contentType); + return uuid + ":" + boost::lexical_cast(contentType) + ":1"; } + static std::string GetCacheKeyStartRange(const std::string& uuid, + FileContentType contentType) + { + return uuid + ":" + boost::lexical_cast(contentType) + ":0"; + } void StorageCache::SetMaximumSize(size_t size) { @@ -50,7 +55,7 @@ FileContentType contentType, const std::string& value) { - const std::string key = GetCacheKey(uuid, contentType); + const std::string key = GetCacheKeyFullFile(uuid, contentType); cache_.Add(key, value); } @@ -60,16 +65,29 @@ const void* buffer, size_t size) { - const std::string key = GetCacheKey(uuid, contentType); + const std::string key = GetCacheKeyFullFile(uuid, contentType); cache_.Add(key, buffer, size); } - + + + void StorageCache::AddStartRange(const std::string& uuid, + FileContentType contentType, + const std::string& value) + { + const std::string key = GetCacheKeyStartRange(uuid, contentType); + cache_.Add(key, value); + } + void StorageCache::Invalidate(const std::string& uuid, FileContentType contentType) { - const std::string key = GetCacheKey(uuid, contentType); - cache_.Invalidate(key); + // invalidate both full file + start range file + const std::string keyFullFile = GetCacheKeyFullFile(uuid, contentType); + cache_.Invalidate(keyFullFile); + + const std::string keyPartialFile = GetCacheKeyStartRange(uuid, contentType); + cache_.Invalidate(keyPartialFile); } @@ -77,7 +95,7 @@ const std::string& uuid, FileContentType contentType) { - const std::string key = GetCacheKey(uuid, contentType); + const std::string key = GetCacheKeyFullFile(uuid, contentType); if (cache_.Fetch(value, key)) { LOG(INFO) << "Read attachment \"" << uuid << "\" with content type " @@ -89,4 +107,42 @@ return false; } } + + bool StorageCache::FetchStartRange(std::string& value, + const std::string& uuid, + FileContentType contentType, + uint64_t end) + { + // first try to get the start of file only from cache + const std::string keyPartialFile = GetCacheKeyStartRange(uuid, contentType); + if (cache_.Fetch(value, keyPartialFile) && value.size() >= end) + { + if (value.size() > end) // the start range that has been cached is larger than the requested value + { + value.resize(end); + } + + LOG(INFO) << "Read start of attachment \"" << uuid << "\" with content type " + << boost::lexical_cast(contentType) << " from cache"; + return true; + } + else + { + // try to get the full file from cache + if (Fetch(value, uuid, contentType)) + { + if (value.size() < end) + { + throw OrthancException(ErrorCode_CorruptedFile); + } + + value.resize(end); + return true; + } + else + { + return false; + } + } + } } diff -r f4a41cc17ac6 -r 1cd1b8f58e56 OrthancFramework/Sources/FileStorage/StorageCache.h --- a/OrthancFramework/Sources/FileStorage/StorageCache.h Mon Feb 21 10:28:08 2022 +0100 +++ b/OrthancFramework/Sources/FileStorage/StorageCache.h Mon Feb 21 10:28:20 2022 +0100 @@ -47,6 +47,10 @@ FileContentType contentType, const std::string& value); + void AddStartRange(const std::string& uuid, + FileContentType contentType, + const std::string& value); + void Add(const std::string& uuid, FileContentType contentType, const void* buffer, @@ -59,5 +63,10 @@ const std::string& uuid, FileContentType contentType); + bool FetchStartRange(std::string& value, + const std::string& uuid, + FileContentType contentType, + uint64_t end /* exclusive */); + }; }