Enable customizing the save statistics time interval
[qBittorrent.git] / src / base / bittorrent / torrentcreationmanager.cpp
blob283a99780389b52cf638f25632788e1844e6c714
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
4 * Copyright (C) 2024 Radu Carpa <radu.carpa@cern.ch>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * In addition, as a special exception, the copyright holders give permission to
21 * link this program with the OpenSSL project's "OpenSSL" library (or with
22 * modified versions of it that use the same license as the "OpenSSL" library),
23 * and distribute the linked executables. You must obey the GNU General Public
24 * License in all respects for all of the code used other than "OpenSSL". If you
25 * modify file(s), you may extend this exception to your version of the file(s),
26 * but you are not obligated to do so. If you do not wish to do so, delete this
27 * exception statement from your version.
30 #include "torrentcreationmanager.h"
32 #include <utility>
34 #include <boost/multi_index_container.hpp>
35 #include <boost/multi_index/composite_key.hpp>
36 #include <boost/multi_index/indexed_by.hpp>
37 #include <boost/multi_index/mem_fun.hpp>
38 #include <boost/multi_index/ordered_index.hpp>
40 #include <QUuid>
42 #define SETTINGS_KEY(name) u"TorrentCreator/Manager/" name
44 namespace BitTorrent
46 using namespace boost::multi_index;
48 class TorrentCreationManager::TaskSet final : public boost::multi_index_container<
49 std::shared_ptr<TorrentCreationTask>,
50 indexed_by<
51 ordered_unique<tag<struct ByID>, const_mem_fun<TorrentCreationTask, QString, &TorrentCreationTask::id>>,
52 ordered_non_unique<tag<struct ByCompletion>, composite_key<
53 TorrentCreationTask,
54 const_mem_fun<TorrentCreationTask, bool, &TorrentCreationTask::isFinished>,
55 const_mem_fun<TorrentCreationTask, QDateTime, &TorrentCreationTask::timeAdded>>>>>
60 BitTorrent::TorrentCreationManager::TorrentCreationManager(IApplication *app, QObject *parent)
61 : ApplicationComponent(app, parent)
62 , m_maxTasks {SETTINGS_KEY(u"MaxTasks"_s), 256}
63 , m_numThreads {SETTINGS_KEY(u"NumThreads"_s), 1}
64 , m_tasks {std::make_unique<TaskSet>()}
66 if (m_numThreads > 0)
67 m_threadPool.setMaxThreadCount(m_numThreads);
70 BitTorrent::TorrentCreationManager::~TorrentCreationManager() = default;
72 std::shared_ptr<BitTorrent::TorrentCreationTask> BitTorrent::TorrentCreationManager::createTask(const TorrentCreatorParams &params, bool startSeeding)
74 if (std::cmp_greater_equal(m_tasks->size(), m_maxTasks.get()))
76 // Try to delete old finished tasks to stay under target
77 auto &tasksByCompletion = m_tasks->get<ByCompletion>();
78 auto [iter, endIter] = tasksByCompletion.equal_range(std::make_tuple(true));
79 while ((iter != endIter) && std::cmp_greater_equal(m_tasks->size(), m_maxTasks.get()))
81 iter = tasksByCompletion.erase(iter);
84 if (std::cmp_greater_equal(m_tasks->size(), m_maxTasks.get()))
85 return {};
87 const QString taskID = generateTaskID();
89 auto *torrentCreator = new TorrentCreator(params, this);
90 auto creationTask = std::make_shared<TorrentCreationTask>(app(), taskID, torrentCreator, startSeeding);
91 connect(creationTask.get(), &QObject::destroyed, torrentCreator, &BitTorrent::TorrentCreator::requestInterruption);
93 m_tasks->get<ByID>().insert(creationTask);
94 m_threadPool.start(torrentCreator);
96 return creationTask;
99 QString BitTorrent::TorrentCreationManager::generateTaskID() const
101 const auto &tasksByID = m_tasks->get<ByID>();
102 QString taskID = QUuid::createUuid().toString(QUuid::WithoutBraces);
103 while (tasksByID.find(taskID) != tasksByID.end())
104 taskID = QUuid::createUuid().toString(QUuid::WithoutBraces);
106 return taskID;
109 std::shared_ptr<BitTorrent::TorrentCreationTask> BitTorrent::TorrentCreationManager::getTask(const QString &id) const
111 const auto &tasksByID = m_tasks->get<ByID>();
112 const auto iter = tasksByID.find(id);
113 if (iter == tasksByID.end())
114 return nullptr;
116 return *iter;
119 QList<std::shared_ptr<BitTorrent::TorrentCreationTask>> BitTorrent::TorrentCreationManager::tasks() const
121 const auto &tasksByCompletion = m_tasks->get<ByCompletion>();
122 return {tasksByCompletion.cbegin(), tasksByCompletion.cend()};
125 bool BitTorrent::TorrentCreationManager::deleteTask(const QString &id)
127 auto &tasksByID = m_tasks->get<ByID>();
128 const auto iter = tasksByID.find(id);
129 if (iter == tasksByID.end())
130 return false;
132 tasksByID.erase(iter);
133 return true;