Mercurial > hg > orthanc-stone
changeset 708:51976977d2d3
reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 20 May 2019 11:20:01 +0200 |
parents | d1feb89ea742 |
children | 7457b4ee1f29 |
files | Framework/Loaders/BasicFetchingItemsSorter.cpp Framework/Loaders/BasicFetchingItemsSorter.h Framework/Loaders/BasicFetchingStrategy.cpp Framework/Loaders/BasicFetchingStrategy.h Framework/Loaders/IFetchingItemsSorter.h Framework/Loaders/IFetchingStrategy.h Resources/CMake/OrthancStoneConfiguration.cmake UnitTestsSources/TestStrategy.cpp |
diffstat | 8 files changed, 455 insertions(+), 269 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Loaders/BasicFetchingItemsSorter.cpp Mon May 20 11:20:01 2019 +0200 @@ -0,0 +1,74 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "BasicFetchingItemsSorter.h" + +#include <Core/OrthancException.h> + +namespace OrthancStone +{ + BasicFetchingItemsSorter::BasicFetchingItemsSorter(unsigned int itemsCount) : + itemsCount_(itemsCount) + { + if (itemsCount == 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + + void BasicFetchingItemsSorter::Sort(std::vector<unsigned int>& target, + unsigned int current) + { + if (current >= itemsCount_) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + target.clear(); + target.reserve(itemsCount_); + target.push_back(current); + + const unsigned int countBelow = current; + const unsigned int countAbove = (itemsCount_ - 1) - current; + const unsigned int n = std::min(countBelow, countAbove); + + for (unsigned int i = 1; i <= n; i++) + { + assert(current + i < itemsCount_ && + current >= i); + target.push_back(current + i); + target.push_back(current - i); + } + + for (unsigned int i = current - n; i > 0; i--) + { + target.push_back(i - 1); + } + + for (unsigned int i = current + n + 1; i < itemsCount_; i++) + { + target.push_back(i); + } + + assert(target.size() == itemsCount_); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Loaders/BasicFetchingItemsSorter.h Mon May 20 11:20:01 2019 +0200 @@ -0,0 +1,44 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "IFetchingItemsSorter.h" + +namespace OrthancStone +{ + class BasicFetchingItemsSorter : public IFetchingItemsSorter + { + private: + unsigned int itemsCount_; + + public: + BasicFetchingItemsSorter(unsigned int itemsCount); + + virtual unsigned int GetItemsCount() const + { + return itemsCount_; + } + + virtual void Sort(std::vector<unsigned int>& target, + unsigned int current); + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Loaders/BasicFetchingStrategy.cpp Mon May 20 11:20:01 2019 +0200 @@ -0,0 +1,146 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "BasicFetchingStrategy.h" + +#include <Core/OrthancException.h> + +namespace OrthancStone +{ + void BasicFetchingStrategy::Schedule(unsigned int item, + unsigned int quality) + { + assert(item < GetItemsCount() && + quality <= maxQuality_); + + if (nextQuality_[item] <= quality) + { + content_.push_back(ContentItem(item, quality)); + } + } + + + BasicFetchingStrategy::BasicFetchingStrategy(IFetchingItemsSorter* sorter, // Takes ownership + unsigned int maxQuality) : + sorter_(sorter), + maxQuality_(maxQuality), + position_(0), + blockSize_(2) + { + if (sorter == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); + } + + nextQuality_.resize(sorter_->GetItemsCount(), 0), // Does not change along calls to "SetCurrent()" + + SetCurrent(0); + } + + + // WARNING - This parameters is only considered during the next call to SetCurrent(). + void BasicFetchingStrategy::SetBlockSize(unsigned int size) + { + if (size <= 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + blockSize_ = size; + } + + + bool BasicFetchingStrategy::GetNext(unsigned int& item, + unsigned int& quality) + { + if (position_ >= content_.size()) + { + return false; + } + else + { + item = content_[position_].GetItem(); + quality = content_[position_].GetQuality(); + + assert(nextQuality_[item] <= quality); + nextQuality_[item] = quality + 1; + + position_ ++; + return true; + } + } + + + void BasicFetchingStrategy::SetCurrent(unsigned int item) + { + // TODO - This function is O(N) complexity where "N" is the + // number of items times the max quality. Could use a LRU index. + + position_ = 0; + + std::vector<unsigned int> v; + sorter_->Sort(v, item); + + assert(v.size() == GetItemsCount()); + + if (v.size() == 0) + { + return; + } + + content_.clear(); + content_.reserve(v.size() * maxQuality_); + + Schedule(v.front(), maxQuality_); + + for (unsigned int q = 0; q <= maxQuality_; q++) + { + unsigned int start = 1 + q * blockSize_; + unsigned int end = start + blockSize_; + + if (q == maxQuality_ || + end > v.size()) + { + end = v.size(); + } + + unsigned int a = 0; + if (maxQuality_ >= q + 1) + { + a = maxQuality_ - q - 1; + } + + for (unsigned int j = a; j <= maxQuality_; j++) + { + for (unsigned int i = start; i < end; i++) + { + Schedule(v[i], j); + } + } + } + } + + + void BasicFetchingStrategy::RecycleFurthest(unsigned int& item) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Loaders/BasicFetchingStrategy.h Mon May 20 11:20:01 2019 +0200 @@ -0,0 +1,94 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "IFetchingItemsSorter.h" +#include "IFetchingStrategy.h" + +#include <memory> + +namespace OrthancStone +{ + class BasicFetchingStrategy : public IFetchingStrategy + { + private: + class ContentItem + { + private: + unsigned int item_; + unsigned int quality_; + + public: + ContentItem(unsigned int item, + unsigned int quality) : + item_(item), + quality_(quality) + { + } + + unsigned int GetItem() const + { + return item_; + } + + unsigned int GetQuality() const + { + return quality_; + } + }; + + std::auto_ptr<IFetchingItemsSorter> sorter_; + std::vector<unsigned int> nextQuality_; + unsigned int maxQuality_; + std::vector<ContentItem> content_; + size_t position_; + unsigned int blockSize_; + + void Schedule(unsigned int item, + unsigned int quality); + + public: + BasicFetchingStrategy(IFetchingItemsSorter* sorter, // Takes ownership + unsigned int maxQuality); + + virtual unsigned int GetItemsCount() const + { + return sorter_->GetItemsCount(); + } + + virtual unsigned int GetMaxQuality() const + { + return maxQuality_; + } + + // WARNING - This parameters is only considered during the next + // call to SetCurrent(). + void SetBlockSize(unsigned int size); + + virtual bool GetNext(unsigned int& item, + unsigned int& quality); + + virtual void SetCurrent(unsigned int item); + + virtual void RecycleFurthest(unsigned int& item); + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Loaders/IFetchingItemsSorter.h Mon May 20 11:20:01 2019 +0200 @@ -0,0 +1,42 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <boost/noncopyable.hpp> +#include <vector> + +namespace OrthancStone +{ + class IFetchingItemsSorter : public boost::noncopyable + { + public: + virtual ~IFetchingItemsSorter() + { + } + + virtual unsigned int GetItemsCount() const = 0; + + // Sort a set of items given the current item + virtual void Sort(std::vector<unsigned int>& target, + unsigned int current) = 0; + }; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Loaders/IFetchingStrategy.h Mon May 20 11:20:01 2019 +0200 @@ -0,0 +1,49 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <boost/noncopyable.hpp> + +namespace OrthancStone +{ + class IFetchingStrategy : public boost::noncopyable + { + public: + virtual ~IFetchingStrategy() + { + } + + virtual unsigned int GetItemsCount() const = 0; + + virtual unsigned int GetMaxQuality() const = 0; + + virtual bool GetNext(unsigned int& item, + unsigned int& quality) = 0; + + virtual void SetCurrent(unsigned int item) = 0; + + // Ask the strategy to re-schedule the item with the lowest + // priority in the fetching order. This allows to know which item + // should be dropped from a cache. + virtual void RecycleFurthest(unsigned int& item) = 0; + }; +};
--- a/Resources/CMake/OrthancStoneConfiguration.cmake Mon May 20 11:03:50 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Mon May 20 11:20:01 2019 +0200 @@ -362,7 +362,7 @@ ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/PointerTypes.h ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/ViewportController.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/ViewportController.h - + ${ORTHANC_STONE_ROOT}/Framework/Fonts/FontRenderer.cpp ${ORTHANC_STONE_ROOT}/Framework/Fonts/Glyph.cpp ${ORTHANC_STONE_ROOT}/Framework/Fonts/GlyphAlphabet.cpp @@ -380,6 +380,8 @@ ${ORTHANC_STONE_ROOT}/Framework/Layers/LineMeasureTracker.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/RenderStyle.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/SliceOutlineRenderer.cpp + ${ORTHANC_STONE_ROOT}/Framework/Loaders/BasicFetchingItemsSorter.cpp + ${ORTHANC_STONE_ROOT}/Framework/Loaders/BasicFetchingStrategy.cpp ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyAlphaLayer.cpp ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyDicomLayer.cpp ${ORTHANC_STONE_ROOT}/Framework/Radiography/RadiographyLayer.cpp
--- a/UnitTestsSources/TestStrategy.cpp Mon May 20 11:03:50 2019 +0200 +++ b/UnitTestsSources/TestStrategy.cpp Mon May 20 11:20:01 2019 +0200 @@ -21,275 +21,10 @@ #include "gtest/gtest.h" -#include <Core/OrthancException.h> - -#include <boost/noncopyable.hpp> -#include <vector> - -namespace OrthancStone -{ - class IFetchingStrategy : public boost::noncopyable - { - public: - virtual ~IFetchingStrategy() - { - } - - virtual unsigned int GetItemsCount() const = 0; - - virtual unsigned int GetMaxQuality() const = 0; - - virtual bool GetNext(unsigned int& item, - unsigned int& quality) = 0; - - virtual void SetCurrent(unsigned int item) = 0; - - // Ask the strategy to re-schedule the item with the lowest - // priority in the fetching order. This allows to know which item - // should be dropped from a cache. - virtual void RecycleFurthest(unsigned int& item) = 0; - }; - - - class IFetchingItemsSorter : public boost::noncopyable - { - public: - virtual ~IFetchingItemsSorter() - { - } - - virtual unsigned int GetItemsCount() const = 0; - - // Sort a set of items given the current item - virtual void Sort(std::vector<unsigned int>& target, - unsigned int current) = 0; - }; - - - - class BasicFetchingItemsSorter : public IFetchingItemsSorter - { - private: - unsigned int itemsCount_; - - public: - BasicFetchingItemsSorter(unsigned int itemsCount) : - itemsCount_(itemsCount) - { - if (itemsCount == 0) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - } - - virtual unsigned int GetItemsCount() const - { - return itemsCount_; - } - - virtual void Sort(std::vector<unsigned int>& target, - unsigned int current) - { - if (current >= itemsCount_) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - - target.clear(); - target.reserve(itemsCount_); - target.push_back(current); - - const unsigned int countBelow = current; - const unsigned int countAbove = (itemsCount_ - 1) - current; - const unsigned int n = std::min(countBelow, countAbove); - - for (unsigned int i = 1; i <= n; i++) - { - assert(current + i < itemsCount_ && - current >= i); - target.push_back(current + i); - target.push_back(current - i); - } - - for (unsigned int i = current - n; i > 0; i--) - { - target.push_back(i - 1); - } - - for (unsigned int i = current + n + 1; i < itemsCount_; i++) - { - target.push_back(i); - } - - assert(target.size() == itemsCount_); - } - }; - - - class BasicFetchingStrategy : public IFetchingStrategy - { - private: - class ContentItem - { - private: - unsigned int item_; - unsigned int quality_; - - public: - ContentItem(unsigned int item, - unsigned int quality) : - item_(item), - quality_(quality) - { - } - - unsigned int GetItem() const - { - return item_; - } - - unsigned int GetQuality() const - { - return quality_; - } - }; +#include "../Framework/Loaders/BasicFetchingStrategy.h" +#include "../Framework/Loaders/BasicFetchingItemsSorter.h" - std::auto_ptr<IFetchingItemsSorter> sorter_; - std::vector<unsigned int> nextQuality_; - unsigned int maxQuality_; - std::vector<ContentItem> content_; - size_t position_; - unsigned int blockSize_; - - void Schedule(unsigned int item, - unsigned int quality) - { - assert(item < GetItemsCount() && - quality <= maxQuality_); - - if (nextQuality_[item] <= quality) - { - content_.push_back(ContentItem(item, quality)); - } - } - - public: - BasicFetchingStrategy(IFetchingItemsSorter* sorter, // Takes ownership - unsigned int maxQuality) : - sorter_(sorter), - maxQuality_(maxQuality), - position_(0), - blockSize_(2) - { - if (sorter == NULL) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); - } - - nextQuality_.resize(sorter_->GetItemsCount(), 0), // Does not change along calls to "SetCurrent()" - - SetCurrent(0); - } - - virtual unsigned int GetItemsCount() const - { - return sorter_->GetItemsCount(); - } - - virtual unsigned int GetMaxQuality() const - { - return maxQuality_; - } - - void SetBlockSize(unsigned int size) - { - if (size <= 0) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - - blockSize_ = size; - } - - virtual bool GetNext(unsigned int& item, - unsigned int& quality) - { - if (position_ >= content_.size()) - { - return false; - } - else - { - item = content_[position_].GetItem(); - quality = content_[position_].GetQuality(); - - assert(nextQuality_[item] <= quality); - nextQuality_[item] = quality + 1; - - position_ ++; - return true; - } - } - - virtual void SetCurrent(unsigned int item) - { - // TODO - This function is O(N) complexity where "N" is the - // number of items times the max quality. Could use a LRU index. - - position_ = 0; - - std::vector<unsigned int> v; - sorter_->Sort(v, item); - - assert(v.size() == GetItemsCount()); - - if (v.size() == 0) - { - return; - } - - content_.clear(); - content_.reserve(v.size() * maxQuality_); - - Schedule(v.front(), maxQuality_); - - for (unsigned int q = 0; q <= maxQuality_; q++) - { - unsigned int start = 1 + q * blockSize_; - unsigned int end = start + blockSize_; - - if (q == maxQuality_ || - end > v.size()) - { - end = v.size(); - } - - unsigned int a = 0; - if (maxQuality_ >= q + 1) - { - a = maxQuality_ - q - 1; - } - - for (unsigned int j = a; j <= maxQuality_; j++) - { - for (unsigned int i = start; i < end; i++) - { - Schedule(v[i], j); - } - } - } - } - - // Ask the strategy to re-schedule the item with the lowest - // priority in the fetching order. This allows to know which item - // should be dropped from a cache. - virtual void RecycleFurthest(unsigned int& item) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); - } - }; -} - +#include <Core/OrthancException.h> namespace