More bug fixes to complete basic operations of the application. Additionally implemented simple dump
option in application.
Change-Id: I3a47580af916482b0d901456455a9395d89048c7
diff --git a/src/torrent-manager.cpp b/src/torrent-manager.cpp
index c976cb1..8e525e0 100644
--- a/src/torrent-manager.cpp
+++ b/src/torrent-manager.cpp
@@ -175,6 +175,7 @@
torrentName = m_torrentFileName.getSubName(1, m_torrentFileName.size() - 3);
}
+ // TODO(spyros) Get update manager working
// m_updateHandler = make_shared<UpdateHandler>(torrentName, m_keyChain,
// make_shared<StatsTable>(m_statsTable), m_face);
@@ -243,51 +244,147 @@
}
}
-std::vector<Name>
-TorrentManager::downloadTorrentFile(const std::string& path)
+shared_ptr<Name>
+TorrentManager::findTorrentFileSegmentToDownload() const
{
- // check whether we should send out an "ALIVE" Interest
- // if (m_updateHandler->needsUpdate()) {
- // m_updateHandler->sendAliveInterest(m_stats_table_iter);
- // }
- shared_ptr<Name> searchRes = this->findTorrentFileSegmentToDownload();
- auto manifestNames = make_shared<std::vector<Name>>();
- if (searchRes == nullptr) {
- this->findFileManifestsToDownload(*manifestNames);
- if (manifestNames->empty()) {
- auto packetNames = make_shared<std::vector<Name>>();
- this->findAllMissingDataPackets(*packetNames);
- return *packetNames;
- }
- else {
- return *manifestNames;
+ // if we have no segments
+ if (m_torrentSegments.empty()) {
+ return make_shared<Name>(m_torrentFileName);
+ }
+ // otherwise just return the next segment ptr of the last segment we have
+ return m_torrentSegments.back().getTorrentFilePtr();
+}
+
+shared_ptr<Name>
+TorrentManager::findManifestSegmentToDownload(const Name& manifestName) const
+{
+ //sequentially find whether we have downloaded any segments of this manifest file
+ Name manifestPrefix = manifestName.getSubName(0, manifestName.size() - 2);
+ auto it = std::find_if(m_fileManifests.rbegin(), m_fileManifests.rend(),
+ [&manifestPrefix] (const FileManifest& f) {
+ return manifestPrefix.isPrefixOf(f.getName());
+ });
+
+ // if we do not have any segments of the file manifest
+ if (it == m_fileManifests.rend()) {
+ return make_shared<Name>(manifestName);
+ }
+
+ // if we already have the requested segment of the file manifest
+ if (it->submanifest_number() >= manifestName.get(manifestName.size() - 2).toSequenceNumber()) {
+ return it->submanifest_ptr();
+ }
+ // if we do not have the requested segment
+ else {
+ return make_shared<Name>(manifestName);
+ }
+}
+
+void
+TorrentManager::findFileManifestsToDownload(std::vector<Name>& manifestNames) const
+{
+ std::vector<Name> manifests;
+ // insert the first segment name of all the file manifests to the vector
+ for (auto i = m_torrentSegments.begin(); i != m_torrentSegments.end(); i++) {
+ manifests.insert(manifests.end(), i->getCatalog().begin(), i->getCatalog().end());
+ }
+ // for each file
+ for (const auto& manifestName : manifests) {
+ // find the first (if any) segment we are missing
+ shared_ptr<Name> manifestSegmentName = findManifestSegmentToDownload(manifestName);
+ if (nullptr != manifestSegmentName) {
+ manifestNames.push_back(*manifestSegmentName);
}
}
- this->downloadTorrentFileSegment(m_torrentFileName, path, manifestNames,
- false, {}, {});
- return *manifestNames;
+}
+
+bool
+TorrentManager::hasDataPacket(const Name& dataName) const
+{
+
+ auto manifest_it = std::find_if(m_fileManifests.begin(), m_fileManifests.end(),
+ [&dataName](const FileManifest& m) {
+ return m.getName().isPrefixOf(dataName);
+ });
+
+ // if we do not have the file manifest, just return false
+ if (manifest_it == m_fileManifests.end()) {
+ return false;
+ }
+
+ // find the pair of (std::shared_ptr<fs::fstream>, std::vector<bool>)
+ // that corresponds to the specific submanifest
+ auto fileState_it = m_fileStates.find(manifest_it->getFullName());
+ if (m_fileStates.end() != fileState_it) {
+ const auto& fileState = fileState_it->second;
+ auto dataNum = dataName.get(dataName.size() - 2).toSequenceNumber();
+ // find whether we have the requested packet from the bitmap
+ return fileState.second[dataNum];
+ }
+ return false;
+}
+
+void
+TorrentManager::findDataPacketsToDownload(const Name& manifestName, std::vector<Name>& packetNames) const
+{
+ auto manifest_it = std::find_if(m_fileManifests.begin(), m_fileManifests.end(),
+ [&manifestName](const FileManifest& m) {
+ return m.name().getSubName(0, m.name().size()
+ - 1).isPrefixOf(manifestName);
+ });
+
+ for (auto j = manifest_it; j != m_fileManifests.end(); j++) {
+ auto& fileState = m_fileStates[j->getFullName()];
+ for (size_t dataNum = 0; dataNum < j->catalog().size(); ++dataNum) {
+ if (!fileState.second[dataNum]) {
+ packetNames.push_back(j->catalog()[dataNum]);
+ }
+ }
+
+ // check that the next manifest in the vector refers to the next segment of the same file
+ if ((j + 1) != m_fileManifests.end() && (j+1)->file_name() != manifest_it->file_name()) {
+ break;
+ }
+ }
+}
+
+void
+TorrentManager::findAllMissingDataPackets(std::vector<Name>& packetNames) const
+{
+ for (auto j = m_fileManifests.begin(); j != m_fileManifests.end(); ++j) {
+ auto fileState_it = m_fileStates.find(j->getFullName());
+ // if we have no packets from this file
+ if (m_fileStates.end() == fileState_it) {
+ packetNames.reserve(packetNames.size() + j->catalog().size());
+ packetNames.insert(packetNames.end(), j->catalog().begin(), j->catalog().end());
+ }
+ // find the packets that we are missing
+ else {
+ const auto &fileState = fileState_it->second;
+ for (auto i = j->catalog().begin(); i != j->catalog().end(); i++) {
+ auto dataNum = i->get(i->size() - 2).toSequenceNumber();
+ if (!fileState.second[dataNum]) {
+ packetNames.push_back(*i);
+ }
+ }
+ }
+ }
}
void
TorrentManager::downloadTorrentFileSegment(const ndn::Name& name,
const std::string& path,
- std::shared_ptr<std::vector<Name>> manifestNames,
- bool async,
TorrentFileReceivedCallback onSuccess,
FailedCallback onFailed)
{
shared_ptr<Interest> interest = createInterest(name);
- auto dataReceived = [manifestNames, path, async, onSuccess, onFailed, this]
+ auto dataReceived = [path, onSuccess, onFailed, this]
(const Interest& interest, const Data& data) {
// Stats Table update here...
m_stats_table_iter->incrementReceivedData();
m_retries = 0;
-
- if (async) {
- manifestNames->clear();
- }
-
+ std::vector<Name> manifestNames;
TorrentFile file(data.wireEncode());
// Write the torrent file segment to disk...
@@ -295,22 +392,19 @@
// if successfully written, seed this data
seed(file);
}
-
const std::vector<Name>& manifestCatalog = file.getCatalog();
- manifestNames->insert(manifestNames->end(), manifestCatalog.begin(), manifestCatalog.end());
+ manifestNames.insert(manifestNames.end(), manifestCatalog.begin(), manifestCatalog.end());
shared_ptr<Name> nextSegmentPtr = file.getTorrentFilePtr();
-
- if (async) {
- onSuccess(*manifestNames);
+ if (onSuccess) {
+ onSuccess(manifestNames);
}
if (nextSegmentPtr != nullptr) {
- this->downloadTorrentFileSegment(*nextSegmentPtr, path, manifestNames,
- async, onSuccess, onFailed);
+ this->downloadTorrentFileSegment(*nextSegmentPtr, path, onSuccess, onFailed);
}
};
- auto dataFailed = [manifestNames, path, name, async, onSuccess, onFailed, this]
+ auto dataFailed = [path, name, onSuccess, onFailed, this]
(const Interest& interest) {
++m_retries;
if (m_retries >= MAX_NUM_OF_RETRIES) {
@@ -319,17 +413,13 @@
m_stats_table_iter = m_statsTable.begin();
}
}
- if (async) {
+ if (onFailed) {
onFailed(interest.getName(), "Unknown error");
}
- this->downloadTorrentFileSegment(name, path, manifestNames, async, onSuccess, onFailed);
+ this->downloadTorrentFileSegment(name, path, onSuccess, onFailed);
};
-
+ LOG_TRACE << "Sending: " << *interest << std::endl;
m_face->expressInterest(*interest, dataReceived, dataFailed);
-
- if (!async) {
- m_face->processEvents();
- }
}
void
@@ -339,21 +429,16 @@
{
shared_ptr<Name> searchRes = this->findTorrentFileSegmentToDownload();
auto manifestNames = make_shared<std::vector<Name>>();
- if (searchRes == nullptr) {
- this->findFileManifestsToDownload(*manifestNames);
- if (manifestNames->empty()) {
- auto packetNames = make_shared<std::vector<Name>>();
- this->findAllMissingDataPackets(*packetNames);
- onSuccess(*packetNames);
- return;
- }
- else {
- onSuccess(*manifestNames);
- return;
+ if (searchRes != nullptr) {
+ this->downloadTorrentFileSegment(*searchRes, path, onSuccess, onFailed);
+ }
+ else {
+ std::vector<Name> manifests;
+ findFileManifestsToDownload(manifests);
+ if (onSuccess) {
+ onSuccess(manifests);
}
}
- this->downloadTorrentFileSegment(*searchRes, path, manifestNames,
- true, onSuccess, onFailed);
}
void
@@ -377,7 +462,7 @@
DataReceivedCallback onSuccess,
FailedCallback onFailed)
{
- if (this->dataAlreadyDownloaded(packetName)) {
+ if (this->hasDataPacket(packetName)) {
onSuccess(packetName);
return;
}
@@ -390,7 +475,6 @@
if(writeData(data)) {
seed(data);
}
-
// Stats Table update here...
m_stats_table_iter->incrementReceivedData();
m_retries = 0;
@@ -401,12 +485,13 @@
m_retries++;
if (m_retries >= MAX_NUM_OF_RETRIES) {
m_stats_table_iter++;
- if (m_stats_table_iter == m_statsTable.end())
+ if (m_stats_table_iter == m_statsTable.end()) {
m_stats_table_iter = m_statsTable.begin();
+ }
}
onFailed(interest.getName(), "Unknown failure");
};
-
+ LOG_TRACE << "Sending: " << *interest << std::endl;
m_face->expressInterest(*interest, dataReceived, dataFailed);
}
@@ -454,6 +539,7 @@
// TODO(msweatt) Fix this once code is merged
auto subManifestSize = m_subManifestSizes[manifest_it->file_name()];
if (IoUtil::writeData(packet, *manifest_it, subManifestSize, *fileState.first)) {
+ fileState.first->flush();
// update bitmap
fileState.second[packetNum] = true;
return true;
@@ -554,7 +640,7 @@
}
onFailed(interest.getName(), "Unknown failure");
};
-
+ LOG_TRACE << "Sending: " << *interest << std::endl;
m_face->expressInterest(*interest, dataReceived, dataFailed);
}
@@ -562,6 +648,7 @@
TorrentManager::onInterestReceived(const InterestFilter& filter, const Interest& interest)
{
// handle if it is a torrent-file
+ LOG_TRACE << "Interest Recevied: " << interest << std::endl;
const auto& interestName = interest.getName();
std::shared_ptr<Data> data = nullptr;
auto cmp = [&interestName](const Data& t){return t.getFullName() == interestName;};
@@ -628,144 +715,17 @@
m_face->shutdown();
}
-shared_ptr<Name>
-TorrentManager::findTorrentFileSegmentToDownload()
-{
- // if we have no segments
- if (m_torrentSegments.empty()) {
- return make_shared<Name>(m_torrentFileName);
- }
- // otherwise just return the next segment ptr of the last segment we have
- return m_torrentSegments.back().getTorrentFilePtr();
-}
-
-shared_ptr<Name>
-TorrentManager::findManifestSegmentToDownload(const Name& manifestName)
-{
- //sequentially find whether we have downloaded any segments of this manifest file
- Name manifestPrefix = manifestName.getSubName(0, manifestName.size() - 2);
- auto it = std::find_if(m_fileManifests.rbegin(), m_fileManifests.rend(),
- [&manifestPrefix] (const FileManifest& f) {
- return manifestPrefix.isPrefixOf(f.getName());
- });
-
- // if we do not have any segments of the file manifest
- if (it == m_fileManifests.rend()) {
- return make_shared<Name>(manifestName);
- }
-
- // if we already have the requested segment of the file manifest
- if (it->submanifest_number() >= manifestName.get(manifestName.size() - 2).toSequenceNumber()) {
- return it->submanifest_ptr();
- }
- // if we do not have the requested segment
- else {
- return make_shared<Name>(manifestName);
- }
-}
-
-void
-TorrentManager::findFileManifestsToDownload(std::vector<Name>& manifestNames)
-{
- std::vector<Name> manifests;
- // insert the first segment name of all the file manifests to the vector
- for (auto i = m_torrentSegments.begin(); i != m_torrentSegments.end(); i++) {
- manifests.insert(manifests.end(), i->getCatalog().begin(), i->getCatalog().end());
- }
- // for each file
- for (const auto& manifestName : manifests) {
- // find the first (if any) segment we are missing
- shared_ptr<Name> manifestSegmentName = findManifestSegmentToDownload(manifestName);
- if (nullptr != manifestSegmentName) {
- manifestNames.push_back(*manifestSegmentName);
- }
- }
-}
-
-bool
-TorrentManager::dataAlreadyDownloaded(const Name& dataName)
-{
-
- auto manifest_it = std::find_if(m_fileManifests.begin(), m_fileManifests.end(),
- [&dataName](const FileManifest& m) {
- return m.getName().isPrefixOf(dataName);
- });
-
- // if we do not have the file manifest, just return false
- if (manifest_it == m_fileManifests.end()) {
- return false;
- }
-
- // find the pair of (std::shared_ptr<fs::fstream>, std::vector<bool>)
- // that corresponds to the specific submanifest
- auto fileState_it = m_fileStates.find(manifest_it->getFullName());
- if (m_fileStates.end() != fileState_it) {
- const auto& fileState = fileState_it->second;
- auto dataNum = dataName.get(dataName.size() - 2).toSequenceNumber();
- // find whether we have the requested packet from the bitmap
- return fileState.second[dataNum];
- }
- return false;
-}
-
-void
-TorrentManager::findDataPacketsToDownload(const Name& manifestName, std::vector<Name>& packetNames)
-{
- auto manifest_it = std::find_if(m_fileManifests.begin(), m_fileManifests.end(),
- [&manifestName](const FileManifest& m) {
- return m.name().getSubName(0, m.name().size()
- - 1).isPrefixOf(manifestName);
- });
-
- for (auto j = manifest_it; j != m_fileManifests.end(); j++) {
- auto& fileState = m_fileStates[j->getFullName()];
- for (size_t dataNum = 0; dataNum < j->catalog().size(); ++dataNum) {
- if (!fileState.second[dataNum]) {
- packetNames.push_back(j->catalog()[dataNum]);
- }
- }
-
- // check that the next manifest in the vector refers to the next segment of the same file
- if ((j + 1) != m_fileManifests.end() && (j+1)->file_name() != manifest_it->file_name()) {
- break;
- }
- }
-}
-
-void
-TorrentManager::findAllMissingDataPackets(std::vector<Name>& packetNames)
-{
- for (auto j = m_fileManifests.begin(); j != m_fileManifests.end(); ++j) {
- auto fileState_it = m_fileStates.find(j->getFullName());
- // if we have no packets from this file
- if (m_fileStates.end() == fileState_it) {
- packetNames.reserve(packetNames.size() + j->catalog().size());
- packetNames.insert(packetNames.end(), j->catalog().begin(), j->catalog().end());
- }
- // find the packets that we are missing
- else {
- const auto &fileState = fileState_it->second;
- for (auto i = j->catalog().begin(); i != j->catalog().end(); i++) {
- auto dataNum = i->get(i->size() - 2).toSequenceNumber();
- if (!fileState.second[dataNum]) {
- packetNames.push_back(*i);
- }
- }
- }
- }
-}
-
shared_ptr<Interest>
TorrentManager::createInterest(Name name)
{
shared_ptr<Interest> interest = make_shared<Interest>(name);
interest->setInterestLifetime(time::milliseconds(2000));
- interest->setMustBeFresh(true);
// Select routable prefix
- Link link(name, { {1, m_stats_table_iter->getRecordName()} });
- m_keyChain->sign(link, signingWithSha256());
- Block linkWire = link.wireEncode();
+ // TODO(spyros) Fix links
+ // Link link(name, { {1, m_stats_table_iter->getRecordName()} });
+ // m_keyChain->sign(link, signingWithSha256());
+ // Block linkWire = link.wireEncode();
// Stats Table update here...
m_stats_table_iter->incrementSentInterests();
@@ -784,7 +744,7 @@
m_retries = 0;
}
- interest->setLink(linkWire);
+ // interest->setLink(linkWire);
return interest;
}