diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index c5c01bee8d07dbfd5a0ff021f03460f15e5b7d52..9cd421bdac5684878f3001c6cddef6afa231d343 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -4821,6 +4821,7 @@ void RdbmsCatalogue::createMountPolicy( m_groupMountPolicyCache.invalidate(); m_userMountPolicyCache.invalidate(); + m_allMountPoliciesCache.invalidate(); } //------------------------------------------------------------------------------ @@ -5445,6 +5446,7 @@ void RdbmsCatalogue::deleteMountPolicy(const std::string &name) { m_groupMountPolicyCache.invalidate(); m_userMountPolicyCache.invalidate(); + m_allMountPoliciesCache.invalidate(); } //------------------------------------------------------------------------------ @@ -5584,6 +5586,7 @@ void RdbmsCatalogue::modifyMountPolicyArchivePriority(const common::dataStructur m_groupMountPolicyCache.invalidate(); m_userMountPolicyCache.invalidate(); + m_allMountPoliciesCache.invalidate(); } //------------------------------------------------------------------------------ @@ -5622,6 +5625,7 @@ void RdbmsCatalogue::modifyMountPolicyArchiveMinRequestAge(const common::dataStr m_groupMountPolicyCache.invalidate(); m_userMountPolicyCache.invalidate(); + m_allMountPoliciesCache.invalidate(); } //------------------------------------------------------------------------------ @@ -5660,6 +5664,7 @@ void RdbmsCatalogue::modifyMountPolicyRetrievePriority(const common::dataStructu m_groupMountPolicyCache.invalidate(); m_userMountPolicyCache.invalidate(); + m_allMountPoliciesCache.invalidate(); } //------------------------------------------------------------------------------ @@ -5698,6 +5703,7 @@ void RdbmsCatalogue::modifyMountPolicyRetrieveMinRequestAge(const common::dataSt m_groupMountPolicyCache.invalidate(); m_userMountPolicyCache.invalidate(); + m_allMountPoliciesCache.invalidate(); } //------------------------------------------------------------------------------ @@ -5736,6 +5742,7 @@ void RdbmsCatalogue::modifyMountPolicyMaxDrivesAllowed(const common::dataStructu m_groupMountPolicyCache.invalidate(); m_userMountPolicyCache.invalidate(); + m_allMountPoliciesCache.invalidate(); } //------------------------------------------------------------------------------ @@ -5774,6 +5781,7 @@ void RdbmsCatalogue::modifyMountPolicyComment(const common::dataStructures::Secu m_groupMountPolicyCache.invalidate(); m_userMountPolicyCache.invalidate(); + m_allMountPoliciesCache.invalidate(); } //------------------------------------------------------------------------------ diff --git a/scheduler/CMakeLists.txt b/scheduler/CMakeLists.txt index 5c07a3d40aa72022ec8b6aac0c667e587a741af4..d8758679767c607e97d2502d4dae331073db31c2 100644 --- a/scheduler/CMakeLists.txt +++ b/scheduler/CMakeLists.txt @@ -16,6 +16,7 @@ set (CTA_SCHEDULER_SRC_FILES Scheduler.cpp SchedulerDatabase.cpp SchedulerDatabaseFactory.cpp + SchedulingInfos.cpp MountType.cpp OStoreDB/QueueItor.cpp OStoreDB/MemQueues.cpp diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp index 941e00af33b461d3899d95354ad23b3d99c1d8ff..7e5dfc395a100b949220c3cd1a3a7ee689b0fb07 100644 --- a/scheduler/Scheduler.cpp +++ b/scheduler/Scheduler.cpp @@ -1550,6 +1550,54 @@ auto logicalLibrary = getLogicalLibrary(logicalLibraryName,getLogicalLibrariesTi return std::unique_ptr<TapeMount>(); } +//------------------------------------------------------------------------------ +// getSchedulingInformations +//------------------------------------------------------------------------------ +std::list<SchedulingInfos> Scheduler::getSchedulingInformations(log::LogContext& lc) { + + std::list<SchedulingInfos> ret; + + utils::Timer timer; + double getTapeInfoTime = 0; + double candidateSortingTime = 0; + double getTapeForWriteTime = 0; + + ExistingMountSummary existingMountsSummary; + std::set<std::string> tapesInUse; + std::list<catalogue::TapeForWriting> tapeList; + + //get all drive informations and sort them by logical library name + cta::common::dataStructures::SecurityIdentity admin; + std::list<cta::common::dataStructures::DriveState> drives = getDriveStates(admin,lc); + + std::map<std::string,std::list<std::string>> logicalLibraryDriveNamesMap; + for(auto & drive: drives){ + logicalLibraryDriveNamesMap[drive.logicalLibrary].push_back(drive.driveName); + } + + for(auto & kv: logicalLibraryDriveNamesMap){ + //get mount informations + std::unique_ptr<SchedulerDatabase::TapeMountDecisionInfo> mountInfo; + mountInfo = m_db.getMountInfoNoLock(cta::SchedulerDatabase::PurposeGetMountInfo::GET_NEXT_MOUNT,lc); + std::string logicalLibrary = kv.first; + cta::SchedulingInfos schedulingInfos(logicalLibrary); + for(auto & driveName: kv.second){ + sortAndGetTapesForMountInfo(mountInfo, logicalLibrary, driveName, timer, + existingMountsSummary, tapesInUse, tapeList, + getTapeInfoTime, candidateSortingTime, getTapeForWriteTime, lc); + //schedulingInfos.addDrivePotentialMount + std::vector<cta::SchedulerDatabase::PotentialMount> potentialMounts = mountInfo->potentialMounts; + for(auto & potentialMount: potentialMounts){ + schedulingInfos.addPotentialMount(potentialMount); + } + } + if(!schedulingInfos.getPotentialMounts().empty()){ + ret.push_back(schedulingInfos); + } + } + return ret; +} + //------------------------------------------------------------------------------ // getQueuesAndMountSummaries //------------------------------------------------------------------------------ diff --git a/scheduler/Scheduler.hpp b/scheduler/Scheduler.hpp index 60bb23cdcfdf6dae6666c46a8904ea98671f2329..5f6d3577ba4f255431a3256a68ed4f2deee9f40d 100644 --- a/scheduler/Scheduler.hpp +++ b/scheduler/Scheduler.hpp @@ -55,6 +55,7 @@ #include "disk/DiskFile.hpp" #include "disk/DiskReporter.hpp" #include "disk/DiskReporterFactory.hpp" +#include "SchedulingInfos.hpp" #include <list> #include <map> @@ -335,6 +336,14 @@ public: * @return unique pointer to the tape mount structure. Next step for the user will be find which type of mount this is. */ std::unique_ptr<TapeMount> getNextMount(const std::string &logicalLibraryName, const std::string &driveName, log::LogContext & lc); + + /** + * Returns scheduling informations for the cta-admin schedulinginfos ls command + * @param lc the log context + * @return the list of the scheduling informations for the cta-admin schedulinginfos ls command + */ + std::list<SchedulingInfos> getSchedulingInformations(log::LogContext & lc); + /** * A function returning * @param lc diff --git a/scheduler/SchedulerDatabase.hpp b/scheduler/SchedulerDatabase.hpp index 2b72253ada5ddfa8d1493f43a99b1160ec1ad96b..539249db41679cc51c932ca2a930a363038528d9 100644 --- a/scheduler/SchedulerDatabase.hpp +++ b/scheduler/SchedulerDatabase.hpp @@ -651,23 +651,23 @@ public: } //The smaller the oldest job start time is, the bigger the age is, hence the inverted comparison if(oldestJobStartTime > other.oldestJobStartTime) - return true; + return true; if(oldestJobStartTime < other.oldestJobStartTime) - return false; + return false; /** * For the tests, we try to have the priority by * alphabetical order : vid1 / tapepool1 should be treated before vid2/tapepool2, * so if this->vid < other.vid : then this > other.vid, so return false */ if(vid < other.vid) - return false; + return false; if(vid > other.vid) - return true; + return true; if(tapePool < other.tapePool) - return false; + return false; if(tapePool > other.tapePool) - return true; + return true; return false; } diff --git a/scheduler/SchedulerTest.cpp b/scheduler/SchedulerTest.cpp index 1830df7014007f005f0dd8929584707d73ca139c..fe15a9cdf241353c563435d1f260d00f4113ab0e 100644 --- a/scheduler/SchedulerTest.cpp +++ b/scheduler/SchedulerTest.cpp @@ -163,11 +163,11 @@ public: auto & catalogue=getCatalogue(); const std::string mountPolicyName = s_mountPolicyName; - const uint64_t archivePriority = 1; - const uint64_t minArchiveRequestAge = 2; - const uint64_t retrievePriority = 3; - const uint64_t minRetrieveRequestAge = 4; - const uint64_t maxDrivesAllowed = 50; + const uint64_t archivePriority = s_archivePriority; + const uint64_t minArchiveRequestAge = s_minArchiveRequestAge; + const uint64_t retrievePriority = s_retrievePriority; + const uint64_t minRetrieveRequestAge = s_minRetrieveRequestAge; + const uint64_t maxDrivesAllowed = s_maxDrivesAllowed; const std::string mountPolicyComment = "create mount group"; ASSERT_TRUE(catalogue.getMountPolicies().empty()); @@ -209,7 +209,7 @@ public: ASSERT_EQ(rule.creationLog, rule.lastModificationLog); cta::common::dataStructures::VirtualOrganization vo; - vo.name = "vo"; + vo.name = s_vo; vo.comment = "comment"; m_catalogue->createVirtualOrganization(s_adminOnAdminHost,vo); @@ -233,7 +233,7 @@ public: cta::catalogue::MediaType mediaType; mediaType.name = s_mediaType; - mediaType.capacityInBytes = 10; + mediaType.capacityInBytes = s_mediaTypeCapacityInBytes; mediaType.cartridge = "cartridge"; mediaType.comment = "comment"; catalogue.createMediaType(s_adminOnAdminHost,mediaType); @@ -269,6 +269,13 @@ protected: const bool s_defaultRepackNoRecall = false; const uint64_t s_minFilesToWarrantAMount = 5; const uint64_t s_minBytesToWarrantAMount = 2*1000*1000; + const uint64_t s_archivePriority = 1; + const uint64_t s_minArchiveRequestAge = 2; + const uint64_t s_retrievePriority = 3; + const uint64_t s_minRetrieveRequestAge = 4; + const uint64_t s_maxDrivesAllowed = 50; + const uint64_t s_mediaTypeCapacityInBytes = 10; + const std::string s_vo = "vo"; //TempFile m_tempSqliteFile; }; // class SchedulerTest @@ -4454,6 +4461,269 @@ TEST_P(SchedulerTest, repackRetrieveRequestsFailToFetchDiskSystem){ } } +TEST_P(SchedulerTest, getSchedulingInformations) { + //Queue 2 archive requests in two different logical libraries + using namespace cta; + + Scheduler &scheduler = getScheduler(); + auto &catalogue = getCatalogue(); + + setupDefaultCatalogue(); +#ifdef STDOUT_LOGGING + log::StdoutLogger dl("dummy", "unitTest"); +#else + log::DummyLogger dl("", ""); +#endif + log::LogContext lc(dl); + + // Create the environment for the migration to happen (library + tape) + const std::string libraryComment = "Library comment"; + const bool libraryIsDisabled = false; + catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName, + libraryIsDisabled, libraryComment); + { + auto libraries = catalogue.getLogicalLibraries(); + ASSERT_EQ(1, libraries.size()); + ASSERT_EQ(s_libraryName, libraries.front().name); + ASSERT_EQ(libraryComment, libraries.front().comment); + } + const std::string tapeComment = "Tape comment"; + bool notDisabled = false; + bool notFull = false; + bool notReadOnly = false; + + { + catalogue::CreateTapeAttributes tape; + tape.vid = s_vid; + tape.mediaType = s_mediaType; + tape.vendor = s_vendor; + tape.logicalLibraryName = s_libraryName; + tape.tapePoolName = s_tapePoolName; + tape.full = notFull; + tape.disabled = notDisabled; + tape.readOnly = notReadOnly; + tape.comment = tapeComment; + catalogue.createTape(s_adminOnAdminHost, tape); + } + + const std::string driveName = "tape_drive"; + + catalogue.tapeLabelled(s_vid, driveName); + + { + // This first initialization is normally done by the dataSession function. + cta::common::dataStructures::DriveInfo driveInfo = { driveName, "myHost", s_libraryName }; + scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Down, lc); + scheduler.reportDriveStatus(driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Up, lc); + } + + uint64_t archiveFileId; + + // Queue an archive request. + cta::common::dataStructures::EntryLog creationLog; + creationLog.host="host2"; + creationLog.time=0; + creationLog.username="admin1"; + cta::common::dataStructures::DiskFileInfo diskFileInfo; + diskFileInfo.gid=GROUP_2; + diskFileInfo.owner_uid=CMS_USER; + diskFileInfo.path="path/to/file"; + cta::common::dataStructures::ArchiveRequest request; + request.checksumBlob.insert(cta::checksum::ADLER32, 0x1234abcd); + request.creationLog=creationLog; + request.diskFileInfo=diskFileInfo; + request.diskFileID="diskFileID"; + request.fileSize=100*1000*1000; + cta::common::dataStructures::RequesterIdentity requester; + requester.name = s_userName; + requester.group = "userGroup"; + request.requester = requester; + request.srcURL="srcURL"; + request.storageClass=s_storageClassName; + archiveFileId = scheduler.checkAndGetNextArchiveFileId(s_diskInstance, request.storageClass, request.requester, lc); + scheduler.queueArchiveWithGivenId(archiveFileId, s_diskInstance, request, lc); + + scheduler.waitSchedulerDbSubthreadsComplete(); + + { + auto schedulerInformations = scheduler.getSchedulingInformations(lc); + ASSERT_FALSE(schedulerInformations.empty()); + + auto & schedulerInfo = schedulerInformations.front(); + ASSERT_EQ(s_libraryName,schedulerInfo.getLogicalLibraryName()); + const auto & potentialMounts = schedulerInfo.getPotentialMounts(); + + ASSERT_FALSE(potentialMounts.empty()); + const auto & potentialMount = potentialMounts.front(); + + ASSERT_EQ(request.fileSize,potentialMount.bytesQueued); + ASSERT_EQ(0,potentialMount.capacityInBytes); + ASSERT_EQ("",potentialMount.diskSystemSleptFor); + ASSERT_EQ(1,potentialMount.filesQueued); + ASSERT_EQ(s_maxDrivesAllowed,potentialMount.maxDrivesAllowed); + ASSERT_EQ(0,potentialMount.mountCount); + ASSERT_EQ(s_minArchiveRequestAge,potentialMount.minRequestAge); + ASSERT_EQ(s_archivePriority,potentialMount.priority); + ASSERT_EQ(0,potentialMount.ratioOfMountQuotaUsed); + ASSERT_EQ(0,potentialMount.sleepTime); + ASSERT_FALSE(potentialMount.sleepingMount); + ASSERT_EQ(s_tapePoolName,potentialMount.tapePool); + ASSERT_EQ(cta::common::dataStructures::MountType::ArchiveForUser,potentialMount.type); + } + + { + std::unique_ptr<cta::TapeMount> mount; + mount.reset(scheduler.getNextMount(s_libraryName, driveName, lc).release()); + ASSERT_NE(nullptr, mount.get()); + std::unique_ptr<cta::ArchiveMount> archiveMount; + archiveMount.reset(dynamic_cast<cta::ArchiveMount*>(mount.release())); + ASSERT_NE(nullptr, archiveMount.get()); + std::list<std::unique_ptr<cta::ArchiveJob>> archiveJobBatch = archiveMount->getNextJobBatch(1,1,lc); + ASSERT_NE(nullptr, archiveJobBatch.front().get()); + std::unique_ptr<ArchiveJob> archiveJob = std::move(archiveJobBatch.front()); + archiveJob->tapeFile.blockId = 1; + archiveJob->tapeFile.fSeq = 1; + archiveJob->tapeFile.checksumBlob.insert(cta::checksum::ADLER32, 0x1234abcd); + archiveJob->tapeFile.fileSize = archiveJob->archiveFile.fileSize; + archiveJob->tapeFile.copyNb = 1; + archiveJob->validate(); + std::queue<std::unique_ptr <cta::ArchiveJob >> sDBarchiveJobBatch; + std::queue<cta::catalogue::TapeItemWritten> sTapeItems; + std::queue<std::unique_ptr <cta::SchedulerDatabase::ArchiveJob >> failedToReportArchiveJobs; + sDBarchiveJobBatch.emplace(std::move(archiveJob)); + archiveMount->reportJobsBatchTransferred(sDBarchiveJobBatch, sTapeItems,failedToReportArchiveJobs, lc); + archiveJobBatch = archiveMount->getNextJobBatch(1,1,lc); + ASSERT_EQ(0, archiveJobBatch.size()); + archiveMount->complete(); + } + + ASSERT_TRUE(scheduler.getSchedulingInformations(lc).empty()); + + //Queue a retrieve request for the archived file + { + cta::common::dataStructures::EntryLog creationLog; + creationLog.host="host2"; + creationLog.time=0; + creationLog.username="admin1"; + cta::common::dataStructures::DiskFileInfo diskFileInfo; + diskFileInfo.gid=GROUP_2; + diskFileInfo.owner_uid=CMS_USER; + diskFileInfo.path="path/to/file"; + cta::common::dataStructures::RetrieveRequest request; + request.archiveFileID = archiveFileId; + request.creationLog = creationLog; + request.diskFileInfo = diskFileInfo; + request.dstURL = "dstURL"; + request.requester.name = s_userName; + request.requester.group = "userGroup"; + scheduler.queueRetrieve(s_diskInstance, request, lc); + scheduler.waitSchedulerDbSubthreadsComplete(); + } + + { + auto schedulerInformations = scheduler.getSchedulingInformations(lc); + ASSERT_FALSE(schedulerInformations.empty()); + + auto & schedulerInfo = schedulerInformations.front(); + ASSERT_EQ(s_libraryName,schedulerInfo.getLogicalLibraryName()); + const auto & potentialMounts = schedulerInfo.getPotentialMounts(); + + ASSERT_FALSE(potentialMounts.empty()); + const auto & potentialMount = potentialMounts.front(); + + ASSERT_EQ(request.fileSize,potentialMount.bytesQueued); + ASSERT_EQ(s_mediaTypeCapacityInBytes,potentialMount.capacityInBytes); + ASSERT_EQ("",potentialMount.diskSystemSleptFor); + ASSERT_EQ(1,potentialMount.filesQueued); + ASSERT_EQ(s_maxDrivesAllowed,potentialMount.maxDrivesAllowed); + ASSERT_EQ(0,potentialMount.mountCount); + ASSERT_EQ(s_minRetrieveRequestAge,potentialMount.minRequestAge); + ASSERT_EQ(s_retrievePriority,potentialMount.priority); + ASSERT_EQ(0,potentialMount.ratioOfMountQuotaUsed); + ASSERT_EQ(0,potentialMount.sleepTime); + ASSERT_FALSE(potentialMount.sleepingMount); + ASSERT_EQ(s_tapePoolName,potentialMount.tapePool); + ASSERT_EQ(cta::common::dataStructures::MountType::Retrieve,potentialMount.type); + ASSERT_EQ(s_libraryName,potentialMount.logicalLibrary); + ASSERT_EQ(s_vid,potentialMount.vid); + ASSERT_EQ(s_vo,potentialMount.vo); + } + //Now let's queue an Archive request with a high priority + //Modify the mount policy to have an equality between all values + catalogue.modifyMountPolicyArchiveMinRequestAge(s_adminOnAdminHost,s_mountPolicyName,1); + catalogue.modifyMountPolicyArchivePriority(s_adminOnAdminHost,s_mountPolicyName,1); + catalogue.modifyMountPolicyRetrieveMinRequestAge(s_adminOnAdminHost,s_mountPolicyName,1); + catalogue.modifyMountPolicyRetrievePriority(s_adminOnAdminHost,s_mountPolicyName,1); + + { + auto schedulerInformations = scheduler.getSchedulingInformations(lc); + ASSERT_FALSE(schedulerInformations.empty()); + + // Queue an archive request. + cta::common::dataStructures::EntryLog creationLog; + creationLog.host="host2"; + creationLog.time=0; + creationLog.username="admin1"; + cta::common::dataStructures::DiskFileInfo diskFileInfo; + diskFileInfo.gid=GROUP_2; + diskFileInfo.owner_uid=CMS_USER; + diskFileInfo.path="path/to/file2"; + cta::common::dataStructures::ArchiveRequest request; + request.checksumBlob.insert(cta::checksum::ADLER32, 0xabcd1234); + request.creationLog=creationLog; + request.diskFileInfo=diskFileInfo; + request.diskFileID="diskFileID"; + request.fileSize=200*1000*1000; + cta::common::dataStructures::RequesterIdentity requester; + requester.name = s_userName; + requester.group = "userGroup"; + request.requester = requester; + request.srcURL="srcURL2"; + request.storageClass=s_storageClassName; + uint64_t archiveFileId = scheduler.checkAndGetNextArchiveFileId(s_diskInstance, request.storageClass, request.requester, lc); + scheduler.queueArchiveWithGivenId(archiveFileId, s_diskInstance, request, lc); + + scheduler.waitSchedulerDbSubthreadsComplete(); + } + + { + auto schedulingInfos = scheduler.getSchedulingInformations(lc); + ASSERT_FALSE(schedulingInfos.empty()); + //We have only one logical library + ASSERT_EQ(1,schedulingInfos.size()); + const auto & schedulingInfo = schedulingInfos.front(); + //We have two potential mounts + auto potentialMounts = schedulingInfo.getPotentialMounts(); + ASSERT_EQ(2,potentialMounts.size()); + //The first mount should be an Archive and the second one a Retrieve as Archive is more prior than the Retrieve + auto & firstMount = potentialMounts.front(); + ASSERT_EQ(cta::common::dataStructures::MountType::ArchiveForUser,firstMount.type); + potentialMounts.pop_front(); + auto & secondMount = potentialMounts.front(); + ASSERT_EQ(cta::common::dataStructures::MountType::Retrieve,secondMount.type); + } + + //Change the mount policies to have a Retrieve priority higher than the Archive priority + catalogue.modifyMountPolicyRetrievePriority(s_adminOnAdminHost,s_mountPolicyName,10); + + { + auto schedulingInfos = scheduler.getSchedulingInformations(lc); + ASSERT_FALSE(schedulingInfos.empty()); + //We have only one logical library + ASSERT_EQ(1,schedulingInfos.size()); + const auto & schedulingInfo = schedulingInfos.front(); + //We have two potential mounts + auto potentialMounts = schedulingInfo.getPotentialMounts(); + ASSERT_EQ(2,potentialMounts.size()); + //The first mount should be an Archive and the second one a Retrieve as Archive is more prior than the Retrieve + auto & firstMount = potentialMounts.front(); + ASSERT_EQ(cta::common::dataStructures::MountType::Retrieve,firstMount.type); + potentialMounts.pop_front(); + auto & secondMount = potentialMounts.front(); + ASSERT_EQ(cta::common::dataStructures::MountType::ArchiveForUser,secondMount.type); + } +} + TEST_P(SchedulerTest, expandRepackRequestShouldThrowIfUseBufferNotRecallButNoDirectoryCreated){ using namespace cta; unitTests::TempDirectory tempDirectory; diff --git a/scheduler/SchedulingInfos.cpp b/scheduler/SchedulingInfos.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5547a56669bb44b8cd110acb04bd1d0ffec1919f --- /dev/null +++ b/scheduler/SchedulingInfos.cpp @@ -0,0 +1,52 @@ +/* + * 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 "SchedulingInfos.hpp" + +namespace cta { + +SchedulingInfos::SchedulingInfos(const std::string & logicalLibraryName):m_logicalLibraryName(logicalLibraryName) { +} + +SchedulingInfos::SchedulingInfos(const SchedulingInfos& other) { + m_logicalLibraryName = other.m_logicalLibraryName; + m_potentialMounts = other.m_potentialMounts; +} + +SchedulingInfos & SchedulingInfos::operator =(const SchedulingInfos& other){ + m_logicalLibraryName = other.m_logicalLibraryName; + m_potentialMounts = other.m_potentialMounts; + return *this; +} + +void SchedulingInfos::addPotentialMount(const cta::SchedulerDatabase::PotentialMount& potentialMount) { + m_potentialMounts.push_back(potentialMount); +} + +std::string SchedulingInfos::getLogicalLibraryName() const { + return m_logicalLibraryName; +} + +std::list<cta::SchedulerDatabase::PotentialMount> SchedulingInfos::getPotentialMounts() const { + return m_potentialMounts; +} + +SchedulingInfos::~SchedulingInfos() { +} + +} \ No newline at end of file diff --git a/scheduler/SchedulingInfos.hpp b/scheduler/SchedulingInfos.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fc9b864f13e9ae0f9c1d60e8bb964d7046bf139d --- /dev/null +++ b/scheduler/SchedulingInfos.hpp @@ -0,0 +1,74 @@ +/* + * 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 <string> + +#include "SchedulerDatabase.hpp" + + +namespace cta { + +/** + * This class represents a scheduling information for a logical library, it is basically + * a list of potential mounts (cta::SchedulerDatabase::PotentialMount object) for a given logical library. + */ +class SchedulingInfos { +public: + /** + * Constructor + * @param logicalLibraryName the logical library + */ + SchedulingInfos(const std::string & logicalLibraryName); + /** + * Copy constructor + */ + SchedulingInfos(const SchedulingInfos& other); + /** + * Assignment operator + */ + SchedulingInfos & operator=(const SchedulingInfos & other); + /** + * Add a potential mount to this logical library scheduling informations + * @param potentialMount the potential mount to add + */ + void addPotentialMount(const cta::SchedulerDatabase::PotentialMount & potentialMount); + + /** + * Returns the list of potential mounts for this logical library + * @return a list of potential mounts for this logical library + */ + std::list<cta::SchedulerDatabase::PotentialMount> getPotentialMounts() const; + + /** + * Returns the logical library name of this SchedulingInfos instance + * @return the logical library name of this SchedulingInfos instance + */ + std::string getLogicalLibraryName() const; + + /** + * Destructor + */ + virtual ~SchedulingInfos(); +private: + std::string m_logicalLibraryName; + std::list<cta::SchedulerDatabase::PotentialMount> m_potentialMounts; +}; + +} \ No newline at end of file