int QueueBundleUtils::compareBundles(const BundlePtr& a, const BundlePtr& b, int aPropertyName) noexcept {
		switch (aPropertyName) {
		case PROP_NAME: {
			COMPARE_TYPE(a, b);

			return Util::stricmp(a->getName(), b->getName());
		}
		case PROP_TYPE: {
			COMPARE_TYPE(a, b);
			
			if (!a->isFileBundle() && !b->isFileBundle()) {
				// Directory bundles
				RLock l(QueueManager::getInstance()->getCS());
				auto dirsA = QueueManager::getInstance()->bundleQueue.getDirectoryCount(a);
				auto dirsB = QueueManager::getInstance()->bundleQueue.getDirectoryCount(b);

				if (dirsA != dirsB) {
					return compare(dirsA, dirsB);
				}

				auto filesA = a->getQueueItems().size() + a->getFinishedFiles().size();
				auto filesB = b->getQueueItems().size() + b->getFinishedFiles().size();

				return compare(filesA, filesB);
			}

			return Util::stricmp(Util::getFileExt(a->getTarget()), Util::getFileExt(b->getTarget()));
		}
		case PROP_PRIORITY: {
			COMPARE_FINISHED(a, b);
			if (a->isFinished() != b->isFinished()) {
				return a->isFinished() ? 1 : -1;
			}

			return compare(static_cast<int>(a->getPriority()), static_cast<int>(b->getPriority()));
		}
		case PROP_STATUS: {
			if (a->getStatus() != b->getStatus()) {
				return compare(a->getStatus(),  b->getStatus());
			}

			return compare(
				a->getPercentage(a->getDownloadedBytes()), 
				b->getPercentage(b->getDownloadedBytes())
			);
		}
		case PROP_SOURCES: {
			COMPARE_FINISHED(a, b);

			auto countsA = QueueManager::getInstance()->getSourceCount(a);
			auto countsB = QueueManager::getInstance()->getSourceCount(b);

			return QueueItemBase::SourceCount::compare(countsA, countsB);
		}
		default:
			dcassert(0);
		}

		return 0;
	}
Example #2
0
QueueItemList BundleQueue::getSearchItems(const BundlePtr& aBundle) const noexcept {
	if (aBundle->getQueueItems().size() <= 1) {
		return aBundle->getQueueItems();
	}

	// File bundles shouldn't come here
	QueueItemList searchItems;
	auto pathInfos = getPathInfos(aBundle->getTarget());
	if (!pathInfos) {
		return searchItems;
	}

	{
		// Get the main directories inside this bundle
		// We'll choose a single search item from each main directory later
		// This helps with getting best coverage for complex bundles that aren't
		// shared with same structure by most users

		StringSet mainBundlePaths;
		for (const auto& pathInfo : *pathInfos) {
			if (pathInfo->queuedFiles == 0) {
				continue;
			}

			mainBundlePaths.insert(AirUtil::getReleaseDirLocal(pathInfo->path, false));
		}


		auto searchPaths = pickRandomItems(mainBundlePaths, 5);

		for (const auto& path : searchPaths) {
			QueueItemList ql;

			// Get all queued files inside this directory
			// This doesn't scale so well for large bundles but shouldn't cause issues with maximum of 5 paths
			aBundle->getDirQIs(path, ql);

			auto searchItem = QueueItem::pickSearchItem(ql);

			// We'll also get search items for parent directories that have no files directly inside them
			// so we need to filter duplicate items as well
			if (searchItem && find_if(searchItems, QueueItem::HashComp(searchItem->getTTH())) == searchItems.end()) {
				searchItems.push_back(searchItem);
			}
		}
	}

#if 0
	StringList targets;
	for (const auto& qi : searchItems) {
		targets.push_back(qi->getTarget());
	}

	LogManager::getInstance()->message("Search items from bundle " + aBundle->getName() + ": " + Util::listToString(targets), LogMessage::SEV_INFO);
#endif

	return searchItems;
}
Example #3
0
	std::string QueueUtils::getStringInfo(const BundlePtr& b, int aPropertyName) noexcept {
		switch (aPropertyName) {
		case QueueApi::PROP_NAME: return b->getName();
		case QueueApi::PROP_TARGET: return b->getTarget();
		case QueueApi::PROP_TYPE: return formatBundleType(b);
		case QueueApi::PROP_STATUS: return formatBundleStatus(b);
		case QueueApi::PROP_PRIORITY: return AirUtil::getPrioText(b->getPriority());
		case QueueApi::PROP_SOURCES: return formatBundleSources(b);
		default: dcassert(0); return Util::emptyString;
		}
	}
Example #4
0
	int QueueUtils::compareBundles(const BundlePtr& a, const BundlePtr& b, int aPropertyName) noexcept {
		switch (aPropertyName) {
		case QueueApi::PROP_NAME: {
			if (a->isFileBundle() && !b->isFileBundle()) return 1;
			if (!a->isFileBundle() && b->isFileBundle()) return -1;

			return Util::stricmp(a->getName(), b->getName());
		}
		case QueueApi::PROP_TYPE: {
			if (a->isFileBundle() != b->isFileBundle()) {
				// Directories go first
				return a->isFileBundle() ? 1 : -1;
			} 
			
			if (!a->isFileBundle() && !b->isFileBundle()) {
				// Directory bundles
				RLock l(QueueManager::getInstance()->getCS());
				auto dirsA = a->getDirectories().size();
				auto dirsB = a->getDirectories().size();
				if (dirsA != dirsB) {
					return compare(dirsA, dirsB);
				}

				auto filesA = a->getQueueItems().size() + a->getFinishedFiles().size();
				auto filesB = b->getQueueItems().size() + b->getFinishedFiles().size();

				return compare(filesA, filesB);
			}

			return Util::stricmp(Util::getFileExt(a->getTarget()), Util::getFileExt(b->getTarget()));
		}
		case QueueApi::PROP_PRIORITY: {
			if (a->isFinished() != b->isFinished()) {
				return a->isFinished() ? 1 : -1;
			}

			return compare(static_cast<int>(a->getPriority()), static_cast<int>(b->getPriority()));
		}
		case QueueApi::PROP_STATUS: {
			if (a->getStatus() != b->getStatus()) {
				return compare(a->getStatus(),  b->getStatus());
			}

			return compare(a->getDownloadedBytes(), b->getDownloadedBytes());
		}
		case QueueApi::PROP_SOURCES: {
			if (a->isFinished() != b->isFinished()) {
				return a->isFinished() ? 1 : -1;
			}

			int onlineA = 0, totalA = 0, onlineB = 0, totalB = 0;
			std::string str;
			getBundleSourceInfo(a, onlineA, totalA, str);
			getBundleSourceInfo(b, onlineB, totalB, str);

			if (onlineA != onlineB) {
				return compare(onlineA, onlineB);
			}

			return compare(totalA, totalB);
		}
		default:
			dcassert(0);
		}

		return 0;
	}