From eb6847aea3e616cf0ebcc4f396564c528b14988d Mon Sep 17 00:00:00 2001 From: Cedric Caffy <cedric.caffy@cern.ch> Date: Fri, 11 Sep 2020 16:27:41 +0200 Subject: [PATCH] [lto_rao] Refactored the way the SLTFRAOAlgorithm is build --- .../castor/tape/tapeserver/RAO/CMakeLists.txt | 2 + .../RAO/ConfigurableRAOAlgorithmFactory.cpp | 19 ++------ .../RAO/ConfigurableRAOAlgorithmFactory.hpp | 4 +- .../tapeserver/RAO/CostHeuristicFactory.cpp | 46 +++++++++++++++++++ .../tapeserver/RAO/CostHeuristicFactory.hpp | 44 ++++++++++++++++++ .../RAO/FilePositionEstimatorFactory.cpp | 45 ++++++++++++++++++ .../RAO/FilePositionEstimatorFactory.hpp | 37 +++++++++++++++ .../tape/tapeserver/RAO/SLTFRAOAlgorithm.cpp | 46 ++++++++++--------- .../tape/tapeserver/RAO/SLTFRAOAlgorithm.hpp | 8 ++-- .../daemon/DataTransferSessionTest.cpp | 2 +- 10 files changed, 209 insertions(+), 44 deletions(-) create mode 100644 tapeserver/castor/tape/tapeserver/RAO/CostHeuristicFactory.cpp create mode 100644 tapeserver/castor/tape/tapeserver/RAO/CostHeuristicFactory.hpp create mode 100644 tapeserver/castor/tape/tapeserver/RAO/FilePositionEstimatorFactory.cpp create mode 100644 tapeserver/castor/tape/tapeserver/RAO/FilePositionEstimatorFactory.hpp diff --git a/tapeserver/castor/tape/tapeserver/RAO/CMakeLists.txt b/tapeserver/castor/tape/tapeserver/RAO/CMakeLists.txt index 31e24c82c3..4ec446390d 100644 --- a/tapeserver/castor/tape/tapeserver/RAO/CMakeLists.txt +++ b/tapeserver/castor/tape/tapeserver/RAO/CMakeLists.txt @@ -25,6 +25,8 @@ set(CTARAO_LIBRARY_SRCS RAOHelpers.cpp CTACostHeuristic.cpp RAOFile.cpp + CostHeuristicFactory.cpp + FilePositionEstimatorFactory.cpp ) add_library (ctarao SHARED diff --git a/tapeserver/castor/tape/tapeserver/RAO/ConfigurableRAOAlgorithmFactory.cpp b/tapeserver/castor/tape/tapeserver/RAO/ConfigurableRAOAlgorithmFactory.cpp index 5af58cb314..c45e01a985 100644 --- a/tapeserver/castor/tape/tapeserver/RAO/ConfigurableRAOAlgorithmFactory.cpp +++ b/tapeserver/castor/tape/tapeserver/RAO/ConfigurableRAOAlgorithmFactory.cpp @@ -31,9 +31,9 @@ std::unique_ptr<RAOAlgorithm> ConfigurableRAOAlgorithmFactory::createRAOAlgorith std::unique_ptr<RAOAlgorithm> ret; switch(m_raoParams.getAlgorithmType()){ case RAOParams::RAOAlgorithmType::sltf:{ - checkDriveInterfaceSet(); - checkCatalogueSet(); - SLTFRAOAlgorithm::Builder builder(m_raoParams,m_drive,m_catalogue); + SLTFRAOAlgorithm::Builder builder(m_raoParams); + builder.setCatalogue(m_catalogue); + builder.setDrive(m_drive); ret = builder.build(); break; } @@ -44,19 +44,6 @@ std::unique_ptr<RAOAlgorithm> ConfigurableRAOAlgorithmFactory::createRAOAlgorith return ret; } -void ConfigurableRAOAlgorithmFactory::checkDriveInterfaceSet() const { - if(m_drive == nullptr){ - throw cta::exception::Exception("In ConfigurableRAOAlgorithmFactory::checkDriveInterfaceSet(), the drive interface has not been set"); - } -} - -void ConfigurableRAOAlgorithmFactory::checkCatalogueSet() const { - if(m_catalogue == nullptr){ - throw cta::exception::Exception("In ConfigurableRAOAlgorithmFactory::checkCatalogueSet(), the catalogue has not been set."); - } -} - - ConfigurableRAOAlgorithmFactory::Builder::Builder(const RAOParams& raoParams){ m_configurableRAOAlgoFactory.reset(new ConfigurableRAOAlgorithmFactory(raoParams)); } diff --git a/tapeserver/castor/tape/tapeserver/RAO/ConfigurableRAOAlgorithmFactory.hpp b/tapeserver/castor/tape/tapeserver/RAO/ConfigurableRAOAlgorithmFactory.hpp index bb423be730..1d92e046f5 100644 --- a/tapeserver/castor/tape/tapeserver/RAO/ConfigurableRAOAlgorithmFactory.hpp +++ b/tapeserver/castor/tape/tapeserver/RAO/ConfigurableRAOAlgorithmFactory.hpp @@ -21,7 +21,7 @@ #include "RAOParams.hpp" #include "RAOAlgorithmFactory.hpp" #include "castor/tape/tapeserver/drive/DriveInterface.hpp" -#include "RAOManager.hpp" +#include "catalogue/Catalogue.hpp" namespace castor { namespace tape { namespace tapeserver { namespace rao { @@ -69,8 +69,6 @@ public: private: ConfigurableRAOAlgorithmFactory(const RAOParams & raoParams); - void checkDriveInterfaceSet() const; - void checkCatalogueSet() const; drive::DriveInterface * m_drive = nullptr; cta::catalogue::Catalogue * m_catalogue = nullptr; RAOParams m_raoParams; diff --git a/tapeserver/castor/tape/tapeserver/RAO/CostHeuristicFactory.cpp b/tapeserver/castor/tape/tapeserver/RAO/CostHeuristicFactory.cpp new file mode 100644 index 0000000000..ec83a2c16a --- /dev/null +++ b/tapeserver/castor/tape/tapeserver/RAO/CostHeuristicFactory.cpp @@ -0,0 +1,46 @@ +/* + * The CERN Tape Archive (CTA) project + * Copyright (C) 2019 CERN + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "CostHeuristicFactory.hpp" +#include "CTACostHeuristic.hpp" +#include "common/exception/Exception.hpp" + +namespace castor { namespace tape { namespace tapeserver { namespace rao { + +CostHeuristicFactory::CostHeuristicFactory() { +} + +std::unique_ptr<CostHeuristic> CostHeuristicFactory::createCostHeuristic(const RAOOptions::CostHeuristicType & costHeuristicType) { + std::unique_ptr<CostHeuristic> ret; + switch(costHeuristicType){ + case RAOOptions::CostHeuristicType::cta: { + ret.reset(new CTACostHeuristic()); + break; + } + default: + std::string errorMsg = "In CostHeuristicFactory::createCostHeuristic() unable to instanciate a cost heuristic" + " because the cost heuristic type given in parameter (" + std::to_string(costHeuristicType) + ") is unknown."; + throw cta::exception::Exception(errorMsg); + } + return ret; +} + +CostHeuristicFactory::~CostHeuristicFactory() { +} + +}}}} \ No newline at end of file diff --git a/tapeserver/castor/tape/tapeserver/RAO/CostHeuristicFactory.hpp b/tapeserver/castor/tape/tapeserver/RAO/CostHeuristicFactory.hpp new file mode 100644 index 0000000000..12f1a267dd --- /dev/null +++ b/tapeserver/castor/tape/tapeserver/RAO/CostHeuristicFactory.hpp @@ -0,0 +1,44 @@ +/* + * The CERN Tape Archive (CTA) project + * Copyright (C) 2019 CERN + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once +#include <memory> + +#include "CostHeuristic.hpp" +#include "RAOOptions.hpp" + +namespace castor { namespace tape { namespace tapeserver { namespace rao { + +/** + * Factory of concrete CostHeuristic objects + */ +class CostHeuristicFactory { +public: + CostHeuristicFactory(); + /** + * Returns the unique_ptr to the instance of the CostHeuristic instance according to the type given in parameter + * @param costHeuristicType the type of CostHeuristic to instanciate + * @return the unique_ptr to the instance of the CostHeuristic instance according to the type given in parameter + */ + std::unique_ptr<CostHeuristic> createCostHeuristic(const RAOOptions::CostHeuristicType & costHeuristicType); + virtual ~CostHeuristicFactory(); +private: + +}; + +}}}} diff --git a/tapeserver/castor/tape/tapeserver/RAO/FilePositionEstimatorFactory.cpp b/tapeserver/castor/tape/tapeserver/RAO/FilePositionEstimatorFactory.cpp new file mode 100644 index 0000000000..3163bb44c7 --- /dev/null +++ b/tapeserver/castor/tape/tapeserver/RAO/FilePositionEstimatorFactory.cpp @@ -0,0 +1,45 @@ +/* + * The CERN Tape Archive (CTA) project + * Copyright (C) 2019 CERN + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "FilePositionEstimatorFactory.hpp" +#include "common/Timer.hpp" +#include "RAOHelpers.hpp" +#include "InterpolationFilePositionEstimator.hpp" + +namespace castor { namespace tape { namespace tapeserver { namespace rao { + + std::unique_ptr<FilePositionEstimator> FilePositionEstimatorFactory::createInterpolationFilePositionEstimator(const std::string & vid, cta::catalogue::Catalogue *catalogue, drive::DriveInterface *drive, cta::log::TimingList &tl){ + std::unique_ptr<FilePositionEstimator> ret; + cta::utils::Timer t; + cta::catalogue::MediaType tapeMediaType = catalogue->getMediaTypeByVid(vid); + tl.insertAndReset("catalogueGetMediaTypeByVidTime",t); + std::vector<drive::endOfWrapPosition> endOfWrapPositions = drive->getEndOfWrapPositions(); + tl.insertAndReset("getEndOfWrapPositionsTime",t); + RAOHelpers::improveEndOfLastWrapPositionIfPossible(endOfWrapPositions); + tl.insertAndReset("improveEndOfWrapPositionsIfPossibleTime",t); + ret.reset(new InterpolationFilePositionEstimator(endOfWrapPositions,tapeMediaType)); + return ret; + } + + std::unique_ptr<FilePositionEstimator> FilePositionEstimatorFactory::createInterpolationFilePositionEstimator(const std::vector<drive::endOfWrapPosition> & endOfWrapPositions, cta::catalogue::MediaType & mediaType){ + std::unique_ptr<FilePositionEstimator> ret; + ret.reset(new InterpolationFilePositionEstimator(endOfWrapPositions,mediaType)); + return ret; + } + +}}}} \ No newline at end of file diff --git a/tapeserver/castor/tape/tapeserver/RAO/FilePositionEstimatorFactory.hpp b/tapeserver/castor/tape/tapeserver/RAO/FilePositionEstimatorFactory.hpp new file mode 100644 index 0000000000..9491b9ba6b --- /dev/null +++ b/tapeserver/castor/tape/tapeserver/RAO/FilePositionEstimatorFactory.hpp @@ -0,0 +1,37 @@ +/* + * The CERN Tape Archive (CTA) project + * Copyright (C) 2019 CERN + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "catalogue/Catalogue.hpp" +#include "castor/tape/tapeserver/drive/DriveInterface.hpp" +#include "FilePositionEstimator.hpp" +#include "common/log/TimingList.hpp" + +namespace castor { namespace tape { namespace tapeserver { namespace rao { + +/** + * This class gathen static factory method to instanciate FilePositionEstimator + */ +class FilePositionEstimatorFactory { +public: + static std::unique_ptr<FilePositionEstimator> createInterpolationFilePositionEstimator(const std::string & vid, cta::catalogue::Catalogue *catalogue, drive::DriveInterface *drive, cta::log::TimingList &tl); + static std::unique_ptr<FilePositionEstimator> createInterpolationFilePositionEstimator(const std::vector<drive::endOfWrapPosition> & eowp, cta::catalogue::MediaType & mediaType); +}; + +}}}} diff --git a/tapeserver/castor/tape/tapeserver/RAO/SLTFRAOAlgorithm.cpp b/tapeserver/castor/tape/tapeserver/RAO/SLTFRAOAlgorithm.cpp index 0266a376d7..137482e7fb 100644 --- a/tapeserver/castor/tape/tapeserver/RAO/SLTFRAOAlgorithm.cpp +++ b/tapeserver/castor/tape/tapeserver/RAO/SLTFRAOAlgorithm.cpp @@ -21,6 +21,8 @@ #include "RAOHelpers.hpp" #include "CTACostHeuristic.hpp" #include "common/Timer.hpp" +#include "CostHeuristicFactory.hpp" +#include "FilePositionEstimatorFactory.hpp" namespace castor { namespace tape { namespace tapeserver { namespace rao { @@ -47,10 +49,18 @@ SLTFRAOAlgorithm::~SLTFRAOAlgorithm() { } -SLTFRAOAlgorithm::Builder::Builder(const RAOParams& data, drive::DriveInterface * drive, cta::catalogue::Catalogue * catalogue):m_raoParams(data),m_drive(drive),m_catalogue(catalogue){ +SLTFRAOAlgorithm::Builder::Builder(const RAOParams& data):m_raoParams(data){ m_algorithm.reset(new SLTFRAOAlgorithm()); } +void SLTFRAOAlgorithm::Builder::setCatalogue(cta::catalogue::Catalogue* catalogue){ + m_catalogue = catalogue; +} + +void SLTFRAOAlgorithm::Builder::setDrive(drive::DriveInterface* drive) { + m_drive = drive; +} + std::unique_ptr<SLTFRAOAlgorithm> SLTFRAOAlgorithm::Builder::build() { initializeFilePositionEstimator(); initializeCostHeuristic(); @@ -58,35 +68,29 @@ std::unique_ptr<SLTFRAOAlgorithm> SLTFRAOAlgorithm::Builder::build() { } void SLTFRAOAlgorithm::Builder::initializeFilePositionEstimator() { - switch(m_raoParams.getRAOAlgorithmOptions().getFilePositionEstimatorType()){ + RAOOptions::FilePositionEstimatorType filePositionType = m_raoParams.getRAOAlgorithmOptions().getFilePositionEstimatorType(); + switch(filePositionType){ case RAOOptions::FilePositionEstimatorType::interpolation: { - std::string vid = m_raoParams.getMountedVid(); - cta::utils::Timer t; - cta::catalogue::MediaType tapeMediaType = m_catalogue->getMediaTypeByVid(vid); - m_algorithm->m_raoTimings.insertAndReset("catalogueGetMediaTypeByVidTime",t); - std::vector<drive::endOfWrapPosition> endOfWrapPositions = m_drive->getEndOfWrapPositions(); - m_algorithm->m_raoTimings.insertAndReset("getEndOfWrapPositionsTime",t); - RAOHelpers::improveEndOfLastWrapPositionIfPossible(endOfWrapPositions); - m_algorithm->m_raoTimings.insertAndReset("improveEndOfWrapPositionsIfPossibleTime",t); - m_algorithm->m_filePositionEstimator.reset(new InterpolationFilePositionEstimator(endOfWrapPositions,tapeMediaType)); + if(m_catalogue != nullptr && m_drive != nullptr) { + m_algorithm->m_filePositionEstimator = FilePositionEstimatorFactory::createInterpolationFilePositionEstimator(m_raoParams.getMountedVid(),m_catalogue,m_drive,m_algorithm->m_raoTimings); + } else { + //If the catalogue or the drive is not set, we don't have any way to give the InterpolationFilePositionEstimator the end of wrap position + //infos and the media type. Throw an exception + throw cta::exception::Exception("In SLTFRAOAlgorithm::Builder::initializeFilePositionEstimator(), the drive and the catalogue are needed to build the InterpolationFilePositionEstimator."); + } break; } default: - throw cta::exception::Exception("In SLTFRAOAlgorithm::Builder::initializeFilePositionEstimator() unable to instanciate an estimator to estimate the position of the files on tape."); + std::string errorMsg = "In SLTFRAOAlgorithm::Builder::initializeFilePositionEstimator() unable to instanciate an estimator to estimate the position of the files on tape " + "because the type given in parameter is unknown ("+std::to_string(filePositionType)+")."; + throw cta::exception::Exception(errorMsg); break; } } void SLTFRAOAlgorithm::Builder::initializeCostHeuristic() { - switch(m_raoParams.getRAOAlgorithmOptions().getCostHeuristicType()){ - case RAOOptions::CostHeuristicType::cta: - { - m_algorithm->m_costHeuristic.reset(new CTACostHeuristic()); - break; - } - default: - throw cta::exception::Exception("In SLTFRAOAlgorithm::Builder::initializeCostHeuristic() unknown type of cost heuristic."); - } + CostHeuristicFactory factory; + m_algorithm->m_costHeuristic = factory.createCostHeuristic(m_raoParams.getRAOAlgorithmOptions().getCostHeuristicType()); } SLTFRAOAlgorithm::RAOFilesContainer SLTFRAOAlgorithm::computeAllFilesPosition(const std::vector<std::unique_ptr<cta::RetrieveJob> >& jobs) const { diff --git a/tapeserver/castor/tape/tapeserver/RAO/SLTFRAOAlgorithm.hpp b/tapeserver/castor/tape/tapeserver/RAO/SLTFRAOAlgorithm.hpp index e01c40cb75..79c89297a3 100644 --- a/tapeserver/castor/tape/tapeserver/RAO/SLTFRAOAlgorithm.hpp +++ b/tapeserver/castor/tape/tapeserver/RAO/SLTFRAOAlgorithm.hpp @@ -55,15 +55,17 @@ public: */ class Builder { public: - Builder(const RAOParams & data, drive::DriveInterface * drive, cta::catalogue::Catalogue * catalogue); + Builder(const RAOParams & data); + void setCatalogue(cta::catalogue::Catalogue * catalogue); + void setDrive(drive::DriveInterface * drive); std::unique_ptr<SLTFRAOAlgorithm> build(); private: void initializeFilePositionEstimator(); void initializeCostHeuristic(); std::unique_ptr<SLTFRAOAlgorithm> m_algorithm; RAOParams m_raoParams; - drive::DriveInterface * m_drive; - cta::catalogue::Catalogue * m_catalogue; + drive::DriveInterface * m_drive = nullptr; + cta::catalogue::Catalogue * m_catalogue = nullptr; }; private: diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp index c86a8ca446..5fa9f2165b 100644 --- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp +++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp @@ -1561,7 +1561,7 @@ TEST_P(DataTransferSessionTest, DataTransferSessionRAORecallSLTFRAOAlgorithm) { // 10) Check logs std::string logToCheck = logger.getLog(); - + ASSERT_NE(std::string::npos, logToCheck.find("firmwareVersion=\"123A\" serialNumber=\"123456\" " "mountTotalCorrectedReadErrors=\"5\" mountTotalReadBytesProcessed=\"4096\" " "mountTotalUncorrectedReadErrors=\"1\" mountTotalNonMediumErrorCounts=\"2\"")); -- GitLab