linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #04253
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2557: Fix double add of queue items, make it possible to remove bundles
------------------------------------------------------------
revno: 2557
committer: Jacek Sieka <arnetheduck@xxxxxxxxx>
branch nick: dcplusplus
timestamp: Sat 2011-06-18 14:49:10 +0200
message:
Fix double add of queue items, make it possible to remove bundles
modified:
dcpp/DirectoryListing.cpp
dcpp/DirectoryListing.h
dcpp/QueueManager.cpp
dcpp/QueueManager.h
win32/QueueFrame.cpp
win32/QueueFrame.h
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dcpp/DirectoryListing.cpp'
--- dcpp/DirectoryListing.cpp 2011-05-07 21:20:08 +0000
+++ dcpp/DirectoryListing.cpp 2011-06-18 12:49:10 +0000
@@ -31,12 +31,16 @@
#include "SimpleXMLReader.h"
#include "File.h"
+#include <boost/range/algorithm/for_each.hpp>
+
#ifdef ff
#undef ff
#endif
namespace dcpp {
+using boost::for_each;
+
DirectoryListing::DirectoryListing(const HintedUser& aUser) :
user(aUser),
root(new Directory(NULL, Util::emptyString, false, false))
@@ -276,33 +280,20 @@
void DirectoryListing::download(Directory* aDir, const string& aTarget, bool highPrio) {
auto bundle = BundlePtr(new Bundle);
bundle->name = aDir->getName();
- download(aDir, aTarget, highPrio, "", *bundle);
- QueueManager::getInstance()->add(aTarget, bundle, getUser(), 0);
+ makeBundle(aDir, "", *bundle);
+ QueueManager::getInstance()->add(aTarget + bundle->name + PATH_SEPARATOR, bundle, getUser(), 0);
}
-void DirectoryListing::download(Directory* aDir, const string& aTarget, bool highPrio, const string& path, Bundle &bundle) {
- string tmp;
- string target = (aDir == getRoot()) ? aTarget : aTarget + aDir->getName() + PATH_SEPARATOR;
+void DirectoryListing::makeBundle(const Directory* aDir, const string& path, Bundle &bundle) {
// First, recurse over the directories
- Directory::List& lst = aDir->directories;
- sort(lst.begin(), lst.end(), Directory::DirSort());
- for(Directory::Iter j = lst.begin(); j != lst.end(); ++j) {
- download(*j, target, highPrio, path + (*j)->getName() + PATH_SEPARATOR, bundle);
- }
+ for_each(aDir->directories, [&](const Directory* child) {
+ makeBundle(child, path + child->getName() + PATH_SEPARATOR, bundle);
+ });
+
// Then add the files
- File::List& l = aDir->files;
- sort(l.begin(), l.end(), File::FileSort());
- for(File::Iter i = aDir->files.begin(); i != aDir->files.end(); ++i) {
- File* file = *i;
- try {
- download(file, target + file->getName(), false, highPrio);
- bundle.entries.insert(Bundle::Entry(path + file->getName(), file->getSize(), file->getTTH(), true));
- } catch(const QueueException&) {
- // Catch it here to allow parts of directories to be added...
- } catch(const FileException&) {
- //..
- }
- }
+ for_each(aDir->files, [&](const File* file) {
+ bundle.entries.insert(Bundle::Entry(path + file->getName(), file->getSize(), file->getTTH(), true));
+ });
}
void DirectoryListing::download(const string& aDir, const string& aTarget, bool highPrio) {
=== modified file 'dcpp/DirectoryListing.h'
--- dcpp/DirectoryListing.h 2011-05-07 21:20:08 +0000
+++ dcpp/DirectoryListing.h 2011-06-18 12:49:10 +0000
@@ -157,7 +157,7 @@
Directory* find(const string& aName, Directory* current);
- void download(Directory* aDir, const string& aTarget, bool highPrio, const string& path, Bundle& bundle);
+ void makeBundle(const Directory* aDir, const string& path, Bundle& bundle);
};
inline bool operator==(DirectoryListing::Directory::Ptr a, const string& b) { return Util::stricmp(a->getName(), b) == 0; }
=== modified file 'dcpp/QueueManager.cpp'
--- dcpp/QueueManager.cpp 2011-05-08 16:12:13 +0000
+++ dcpp/QueueManager.cpp 2011-06-18 12:49:10 +0000
@@ -658,7 +658,14 @@
}
void QueueManager::add(const string& aRoot, const BundlePtr& bundle, const HintedUser& aUser, int aFlags) {
- for_each(bundle->entries, [&](const Bundle::Entry& e) { add(aRoot + e.name, e.size, e.tth, aUser, aFlags, true, bundle); });
+ for_each(bundle->entries, [&](const Bundle::Entry& e) {
+ try {
+ add(aRoot + e.name, e.size, e.tth, aUser, aFlags, true, bundle);
+ } catch(...) {
+ // TODO Report exceptions?
+ }
+ });
+
Lock l(cs);
auto i = bundles.insert(make_pair(bundle->getHash(), BundleItem(aRoot, bundle)));
@@ -1181,18 +1188,35 @@
fire(QueueManagerListener::Finished(), q, dir, aDownload->getAverageSpeed());
- auto bi = getBundle(q);
- if(bi && isFinished(*bi)) {
- fire(QueueManagerListener::Finished(), *bi);
- }
-
userQueue.remove(q);
- if(!BOOLSETTING(KEEP_FINISHED_FILES) || aDownload->getType() == Transfer::TYPE_FULL_LIST) {
- fire(QueueManagerListener::Removed(), q);
- fileQueue.remove(q);
+ if(aDownload->getType() == Transfer::TYPE_FILE) {
+ auto bi = getBundle(q);
+ if(bi) {
+ if(isFinished(*bi)) {
+ if(!BOOLSETTING(KEEP_FINISHED_FILES)) {
+ auto &b = bi->getBundle();
+ for_each(b->entries, [&](const Bundle::Entry& entry) {
+ auto bqi = fileQueue.find(bi->getRoot() + entry.name);
+ if(bqi) {
+ fileQueue.remove(bqi);
+ }
+ });
+
+ removeBundle(bi);
+ } else {
+ fire(QueueManagerListener::StatusUpdated(), q);
+ }
+
+ fire(QueueManagerListener::Finished(), *bi);
+ } else {
+ fire(QueueManagerListener::StatusUpdated(), q);
+ }
+ } else {
+ remove(q, aDownload->getType() == Transfer::TYPE_FULL_LIST);
+ }
} else {
- fire(QueueManagerListener::StatusUpdated(), q);
+ remove(q, aDownload->getType() == Transfer::TYPE_FULL_LIST);
}
} else {
userQueue.removeDownload(q, aDownload->getUser());
@@ -1246,6 +1270,15 @@
}
}
+void QueueManager::remove(QueueItem* qi, bool isList) {
+ if(!BOOLSETTING(KEEP_FINISHED_FILES) || isList) {
+ fire(QueueManagerListener::Removed(), qi);
+ fileQueue.remove(qi);
+ } else {
+ fire(QueueManagerListener::StatusUpdated(), qi);
+ }
+}
+
void QueueManager::processList(const string& name, const HintedUser& user, int flags) {
DirectoryListing dirList(user);
try {
@@ -1924,6 +1957,12 @@
return 0;
}
+void QueueManager::removeBundle(BundleItem *bi) noexcept {
+ fire(QueueManagerListener::Removed(), *bi);
+ bundles.erase(bi->getBundle()->getHash());
+ delete bi;
+}
+
bool QueueManager::isFinished(const BundleItem &bi) noexcept {
return find_if(bi.getBundle()->entries, [&](const Bundle::Entry &e) -> bool {
auto qi = fileQueue.find(bi.getRoot() + e.name);
=== modified file 'dcpp/QueueManager.h'
--- dcpp/QueueManager.h 2011-05-07 21:20:08 +0000
+++ dcpp/QueueManager.h 2011-06-18 12:49:10 +0000
@@ -228,6 +228,7 @@
uint64_t nextSearch;
/** File lists not to delete */
StringList protectedFileLists;
+
/** Sanity check for the target filename */
static string checkTarget(const string& aTarget, bool checkExsistence);
/** Add a source to an existing queue item */
@@ -240,9 +241,11 @@
static void moveFile_(const string& source, const string& target);
void moveStuckFile(QueueItem* qi);
void rechecked(QueueItem* qi);
+ void remove(QueueItem* qi, bool isList);
BundleItem* getBundle(QueueItem* qi) noexcept;
bool isFinished(const BundleItem &bi) noexcept;
+ void removeBundle(BundleItem* bi) noexcept;
void setDirty();
=== modified file 'win32/QueueFrame.cpp'
--- win32/QueueFrame.cpp 2011-05-07 21:20:08 +0000
+++ win32/QueueFrame.cpp 2011-06-18 12:49:10 +0000
@@ -433,8 +433,9 @@
return Text::toT(name.substr(0, name.length() - 1));
}
-QueueFrame::DirItemInfo::DirItemInfo(const string& dir_) : dir(dir_), text(getDisplayName(dir_)) {
-
+QueueFrame::DirItemInfo::DirItemInfo(const string& dir_, bool isBundle) :
+ dir(dir_), text(getDisplayName(dir_)), isBundle(isBundle)
+{
}
int QueueFrame::DirItemInfo::getImage(int col) {
@@ -469,7 +470,7 @@
next = dirs->getRoot();
while(next != NULL) {
- if(next != fileLists) {
+ if(next != fileLists && next != bundles) {
if(Util::strnicmp(getDir(next), dir, 3) == 0)
break;
}
@@ -480,10 +481,10 @@
// First addition, set commonStart to the dir minus the last part...
i = dir.rfind('\\', dir.length()-2);
if(i != string::npos) {
- next = dirs->insert(NULL, new DirItemInfo(dir.substr(0, i+1)), true);
+ next = dirs->insert(NULL, new DirItemInfo(dir.substr(0, i+1), false), true);
} else {
dcassert(dir.length() == 3);
- next = dirs->insert(NULL, new DirItemInfo(dir, Text::toT(dir)), true);
+ next = dirs->insert(NULL, new DirItemInfo(dir, Text::toT(dir), false), true);
}
}
@@ -507,7 +508,7 @@
HTREEITEM oldRoot = next;
// Create a new root
- HTREEITEM newRoot = dirs->insert(NULL, new DirItemInfo(rootStr.substr(0, i)), true);
+ HTREEITEM newRoot = dirs->insert(NULL, new DirItemInfo(rootStr.substr(0, i), false), true);
parent = addDirectory(rootStr, false, newRoot);
@@ -533,7 +534,7 @@
while( i < dir.length() ) {
while(next != NULL) {
- if(next != fileLists) {
+ if(next != fileLists && next != bundles) {
const string& n = getDir(next);
if(Util::strnicmp(n.c_str()+i, dir.c_str()+i, n.length()-i) == 0) {
// Found a part, we assume it's the best one we can find...
@@ -551,7 +552,7 @@
// We didn't find it, add...
j = dir.find('\\', i);
dcassert(j != string::npos);
- parent = dirs->insert(parent, new DirItemInfo(dir.substr(0, j+1), Text::toT(dir.substr(i, j-i))), true);
+ parent = dirs->insert(parent, new DirItemInfo(dir.substr(0, j+1), Text::toT(dir.substr(i, j-i)), false), true);
i = j + 1;
}
}
@@ -575,7 +576,7 @@
} else {
while(i < dir.length()) {
while(next != NULL) {
- if(next != fileLists) {
+ if(!isSpecial(next)) {
const string& n = getDir(next);
if(Util::strnicmp(n.c_str()+i, dir.c_str()+i, n.length()-i) == 0) {
// Match!
@@ -605,14 +606,8 @@
}
}
-void QueueFrame::removeDirectories(HTREEITEM ht) {
- HTREEITEM next = dirs->getChild(ht);
- while(next != NULL) {
- removeDirectories(next);
- next = dirs->getNextSibling(ht);
- }
- delete dirs->getData(ht);
- dirs->erase(ht);
+bool QueueFrame::isSpecial(HTREEITEM item) {
+ return item == bundles || item == fileLists;
}
void QueueFrame::removeSelected() {
@@ -766,10 +761,14 @@
removeDir(child);
child = dirs->getNextSibling(child);
}
- const string& name = getDir(ht);
- auto dp = directories.equal_range(name);
- for(auto i = dp.first; i != dp.second; ++i) {
- QueueManager::getInstance()->remove(i->second->getTarget());
+ auto dii = dirs->getData(ht);
+ if(dii->getIsBundle()) {
+ QueueManager::getInstance()->removeBundle(TTHValue(dii->getDir()));
+ } else {
+ auto dp = directories.equal_range(dii->getDir());
+ for(auto i = dp.first; i != dp.second; ++i) {
+ QueueManager::getInstance()->remove(i->second->getTarget());
+ }
}
}
@@ -1011,9 +1010,9 @@
void QueueFrame::addBundle(const BundleItem& bi) {
bundleInfos[bi.getBundle()->getHash()] = new BundleItemInfo(bi);
if(!bundles) {
- bundles = dirs->insert(NULL, new DirItemInfo("", BUNDLE_INFO_NAME), true);
+ bundles = dirs->insert(NULL, new DirItemInfo("", BUNDLE_INFO_NAME, false), true);
}
- dirs->insert(bundles, new DirItemInfo(bi.getBundle()->getHash().toBase32(), Text::toT(bi.getBundle()->name)));
+ dirs->insert(bundles, new DirItemInfo(bi.getBundle()->getHash().toBase32(), Text::toT(bi.getBundle()->name), true));
}
void QueueFrame::removeBundle(const TTHValue& tth) {
@@ -1022,8 +1021,8 @@
return;
}
- auto hash = tth.toBase32();
if(bundles != NULL) {
+ auto hash = tth.toBase32();
for(auto h = dirs->getChild(bundles); h; h = dirs->getNextSibling(h)) {
auto di = dirs->getData(h);
if(di->getDir() == hash) {
@@ -1034,6 +1033,12 @@
}
bundleInfos.erase(tth);
+
+ if(bundleInfos.empty()) {
+ delete dirs->getData(bundles);
+ dirs->erase(bundles);
+ bundles = NULL;
+ }
}
void QueueFrame::onAdded(QueueItemInfo* ii) {
=== modified file 'win32/QueueFrame.h'
--- win32/QueueFrame.h 2011-05-07 21:20:08 +0000
+++ win32/QueueFrame.h 2011-06-18 12:49:10 +0000
@@ -74,15 +74,17 @@
class DirItemInfo : public FastAlloc<DirItemInfo> {
public:
- DirItemInfo(const string& dir);
- DirItemInfo(const string& dir_, const tstring& text_) : dir(dir_), text(text_) { }
+ DirItemInfo(const string& dir, bool isBundle);
+ DirItemInfo(const string& dir_, const tstring& text_, bool isBundle) : dir(dir_), text(text_), isBundle(isBundle) { }
const tstring& getText() const { return text; }
int getImage(int col = 0);
int getSelectedImage();
const string& getDir() const { return dir; }
+ bool getIsBundle() const { return isBundle; }
private:
string dir;
tstring text;
+ bool isBundle;
};
class QueueItemInfo;
@@ -236,13 +238,14 @@
void removeBundle(const TTHValue& tth);
HTREEITEM addDirectory(const string& dir, bool isFileList = false, HTREEITEM startAt = NULL);
- void removeDirectories(HTREEITEM ht);
void removeDirectory(const string& dir, bool isFileList = false);
bool isCurDir(const string& aDir) const;
QueueItemInfo* getItemInfo(const string& target);
+ bool isSpecial(HTREEITEM item);
+ bool isBundle(HTREEITEM item);
void clearTree(HTREEITEM item);
void moveSelected();