diff options
author | Anton Kudryavtsev <a.kudryavtsev@netris.ru> | 2016-03-04 10:51:12 +0300 |
---|---|---|
committer | Anton Kudryavtsev <a.kudryavtsev@netris.ru> | 2016-04-19 11:26:02 +0000 |
commit | 35b0ecf5da40feac0e7b43d928b60402d75d95d1 (patch) | |
tree | 8059de516bc86aa61f19fcd7ea7e78be054037b2 /src/network/kernel/qhostinfo.cpp | |
parent | 7094466f7d0c2176eb3080021a4ea5d220555df9 (diff) |
QtNetwork: replace Java-style iterators
... with STL-style iterators or with algorithms.
Java-style iterators have overhead.
Introduce local template separate_if algorithm from kleopatra
project to simplify current code.
http://api.kde.org/4.3-api/kdepim-apidocs/kleopatra/html
Done-with: Marc Mutz <marc.mutz@kdab.com>
Change-Id: Ib154f80f46f8041d9cafd81bed0e1982b21541cf
Reviewed-by: Edward Welbourne <edward.welbourne@theqtcompany.com>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Diffstat (limited to 'src/network/kernel/qhostinfo.cpp')
-rw-r--r-- | src/network/kernel/qhostinfo.cpp | 85 |
1 files changed, 46 insertions, 39 deletions
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 293633d6bc..88df65dbcb 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -79,6 +79,22 @@ bool any_of(InputIt first, InputIt last, UnaryPredicate p) { return std::find_if(first, last, p) != last; } + +template <typename InputIt, typename OutputIt1, typename OutputIt2, typename UnaryPredicate> +std::pair<OutputIt1, OutputIt2> separate_if(InputIt first, InputIt last, OutputIt1 dest1, OutputIt2 dest2, UnaryPredicate p) +{ + while (first != last) { + if (p(*first)) { + *dest1 = *first; + ++dest1; + } else { + *dest2 = *first; + ++dest2; + } + ++first; + } + return std::make_pair(dest1, dest2); +} } /*! @@ -587,46 +603,37 @@ void QHostInfoLookupManager::work() finishedLookups.clear(); } - if (!postponedLookups.isEmpty()) { - // try to start the postponed ones - - QMutableListIterator<QHostInfoRunnable*> iterator(postponedLookups); - while (iterator.hasNext()) { - QHostInfoRunnable* postponed = iterator.next(); - - // check if none of the postponed hostnames is currently running - const bool alreadyRunning = any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(postponed->toBeLookedUp)); - if (!alreadyRunning) { - iterator.remove(); - scheduledLookups.prepend(postponed); // prepend! we want to finish it ASAP - } + auto isAlreadyRunning = [this](QHostInfoRunnable *lookup) { + return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp)); + }; + + // Transfer any postponed lookups that aren't currently running to the scheduled list, keeping already-running lookups: + postponedLookups.erase(separate_if(postponedLookups.begin(), + postponedLookups.end(), + postponedLookups.begin(), + std::front_inserter(scheduledLookups), // prepend! we want to finish it ASAP + isAlreadyRunning).first, + postponedLookups.end()); + + // Unschedule and postpone any that are currently running: + scheduledLookups.erase(separate_if(scheduledLookups.begin(), + scheduledLookups.end(), + std::back_inserter(postponedLookups), + scheduledLookups.begin(), + isAlreadyRunning).second, + scheduledLookups.end()); + + const int availableThreads = threadPool.maxThreadCount() - currentLookups.size(); + if (availableThreads > 0) { + int readyToStartCount = qMin(availableThreads, scheduledLookups.size()); + auto it = scheduledLookups.begin(); + while (readyToStartCount--) { + // runnable now running in new thread, track this in currentLookups + threadPool.start(*it); + currentLookups.push_back(std::move(*it)); + ++it; } - } - - if (!scheduledLookups.isEmpty()) { - // try to start the new ones - QMutableListIterator<QHostInfoRunnable*> iterator(scheduledLookups); - while (iterator.hasNext()) { - QHostInfoRunnable *scheduled = iterator.next(); - - // check if a lookup for this host is already running, then postpone - const bool alreadyRunning = any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(scheduled->toBeLookedUp)); - if (alreadyRunning) { - iterator.remove(); - postponedLookups.append(scheduled); - scheduled = 0; - } - - if (scheduled && currentLookups.size() < threadPool.maxThreadCount()) { - // runnable now running in new thread, track this in currentLookups - threadPool.start(scheduled); - iterator.remove(); - currentLookups.append(scheduled); - } else { - // was postponed, continue iterating - continue; - } - }; + scheduledLookups.erase(scheduledLookups.begin(), it); } } |