← Back to team overview

linuxdcpp-team team mailing list archive

[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();