diff --git a/CMakeLists.txt b/CMakeLists.txt index c684ab4aa..39411f8a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1708,11 +1708,11 @@ endif () set (CPACK_DEBIAN_PACKAGE_DESCRIPTION "${PROJECT_DESCRIPTION}") set (CPACK_DEBIAN_PACKAGE_HOMEPAGE "${PROJECT_HOMEPAGE}") -set (CPACK_DEBIAN_PACKAGE_DEPENDS "libgfortran3 (>=4.8.2), libqt5serialport5 (>=5.2), libqt5multimedia5-plugins (>=5.2), libqt5widgets5 (>=5.2), libusb-1.0-0, libudev1, libc6 (>=2.19)") +set (CPACK_DEBIAN_PACKAGE_DEPENDS "libgfortran3 (>=4.8.2), libqt5serialport5 (>=5.5), libqt5multimedia5-plugins (>=5.5), libqt5widgets5 (>=5.5), libqt5sql5-sqlite (>=5.5), libusb-1.0-0, libudev1, libc6 (>=2.19)") set (CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set (CPACK_RPM_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR}) -set (CPACK_RPM_PACKAGE_REQUIRES "qt5-qtserialport >= 5.2, qt5-qtmultimedia >= 5.2, qt5-qtsvg, libusb, systemd-udev, glibc >= 2, libgfortran >= 4.8.2") +set (CPACK_RPM_PACKAGE_REQUIRES "qt5-qtserialport >= 5.5, qt5-qtmultimedia >= 5.5, qt5-qtsvg, libusb, systemd-udev, glibc >= 2, libgfortran >= 4.8.2") set (CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/share/pixmaps /usr/share/applications /usr/share/man /usr/share/man1) configure_file ("${PROJECT_SOURCE_DIR}/CMakeCPackOptions.cmake.in" diff --git a/Versions.cmake b/Versions.cmake index 6cb4d89c2..3ba5db895 100644 --- a/Versions.cmake +++ b/Versions.cmake @@ -1,6 +1,6 @@ # Version number components set (WSJTX_VERSION_MAJOR 2) set (WSJTX_VERSION_MINOR 0) -set (WSJTX_VERSION_PATCH 1) -#set (WSJTX_RC 1) # release candidate number, comment out or zero for development versions +set (WSJTX_VERSION_PATCH 0) +set (WSJTX_RC 5) # release candidate number, comment out or zero for development versions set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build diff --git a/lib/sync65.f90 b/lib/sync65.f90 index e0bc924a0..4a681a0a7 100644 --- a/lib/sync65.f90 +++ b/lib/sync65.f90 @@ -57,8 +57,9 @@ subroutine sync65(nfa,nfb,naggressive,ntol,nqsym,ca,ncand,nrobust, & freq=i*df itry=0 ! if(naggressive.gt.0 .and. ntol.lt.1000 .and. ccfmax.ge.thresh0) then - if(naggressive.gt.0 .and. ccfmax.ge.thresh0) then - if(i.ne.ipk) cycle +! if(naggressive.gt.0 .and. ccfmax.ge.thresh0) then + if(bVHF) then + if(i.ne.ipk .or. ccfmax.lt.thresh0) cycle itry=1 ncand=ncand+1 else diff --git a/logbook/WorkedBefore.cpp b/logbook/WorkedBefore.cpp index b6cd9eca8..41723e003 100644 --- a/logbook/WorkedBefore.cpp +++ b/logbook/WorkedBefore.cpp @@ -1,18 +1,34 @@ #include "WorkedBefore.hpp" +#include +#include #include +#include #include #include +#include +#include #include #include #include #include #include +#include +#include "qt_helpers.hpp" #include "pimpl_impl.hpp" using namespace boost::multi_index; +// hash function for QString members in hashed indexes +inline +std::size_t hash_value (QString const& s) +{ + return std::hash {} (s); +} + +// // worked before set element +// struct worked_entry { explicit worked_entry (QString const& call, QString const& grid, QString const& band @@ -39,7 +55,52 @@ struct worked_entry int ITU_zone_; }; -// less then predidate for the Continent enum class +bool operator == (worked_entry const& lhs, worked_entry const& rhs) +{ + return + lhs.continent_ == rhs.continent_ // check 1st as it is fast + && lhs.CQ_zone_ == rhs.CQ_zone_ // ditto + && lhs.ITU_zone_ == rhs.ITU_zone_ // ditto + && lhs.call_ == rhs.call_ // check the rest in decreasing + && lhs.grid_ == rhs.grid_ // domain size order to shortcut + && lhs.country_ == rhs.country_ // differences as quickly as possible + && lhs.band_ == rhs.band_ + && lhs.mode_ == rhs.mode_; +} + +std::size_t hash_value (worked_entry const& we) +{ + std::size_t seed {0}; + boost::hash_combine (seed, we.call_); + boost::hash_combine (seed, we.grid_); + boost::hash_combine (seed, we.band_); + boost::hash_combine (seed, we.mode_); + boost::hash_combine (seed, we.country_); + boost::hash_combine (seed, we.continent_); + boost::hash_combine (seed, we.CQ_zone_); + boost::hash_combine (seed, we.ITU_zone_); + return seed; +} + +#if !defined (QT_NO_DEBUG_STREAM) +QDebug operator << (QDebug dbg, worked_entry const& e) +{ + QDebugStateSaver saver {dbg}; + dbg.nospace () << "worked_entry(" + << e.call_ << ", " + << e.grid_ << ", " + << e.band_ << ", " + << e.mode_ << ", " + << e.country_ << ", " + << e.continent_ << ", " + << e.CQ_zone_ << ", " + << e.ITU_zone_ << ')'; + return dbg; +} +#endif + +// less then predidate for the Continent enum class, needed for +// ordered indexes struct Continent_less { bool operator () (AD1CCty::Continent lhs, AD1CCty::Continent rhs) const @@ -48,7 +109,7 @@ struct Continent_less } }; -// tags +// index tags struct call_mode_band {}; struct call_band {}; struct grid_mode_band {}; @@ -62,85 +123,92 @@ struct CQ_zone_band {}; struct ITU_zone_mode_band {}; struct ITU_zone_band {}; -// set with multiple ordered unique indexes that allow for efficient -// determination of various categories of worked before status +// set with multiple ordered unique indexes that allow for optimally +// efficient determination of various categories of worked before +// status typedef multi_index_container< worked_entry, indexed_by< + // basic unordered set constraint - we don't need duplicate worked entries + hashed_unique>, + + // + // The following indexes are used to discover worked before stuff. + // + // They are ordered so as to support partial lookups and + // non-unique because container inserts must be valid for all + // indexes. + // + // call+mode+band - ordered_unique, - composite_key, - member, - member > >, + ordered_non_unique, + composite_key, + member, + member > >, // call+band - ordered_unique, - composite_key, - member > >, + ordered_non_unique, + composite_key, + member > >, // grid+mode+band - ordered_unique, - composite_key, - member, - member > >, + ordered_non_unique, + composite_key, + member, + member > >, // grid+band - ordered_unique, - composite_key, - member > >, + ordered_non_unique, + composite_key, + member > >, // country+mode+band - ordered_unique, - composite_key, - member, - member > >, + ordered_non_unique, + composite_key, + member, + member > >, // country+band - ordered_unique, - composite_key, - member > >, + ordered_non_unique, + composite_key, + member > >, // continent+mode+band - ordered_unique, - composite_key, - member, - member >, - composite_key_compare< - Continent_less, - std::less, - std::less > >, + ordered_non_unique, + composite_key, + member, + member >, + composite_key_compare, std::less > >, // continent+band - ordered_unique, - composite_key, - member >, - composite_key_compare< - Continent_less, - std::less > >, + ordered_non_unique, + composite_key, + member >, + composite_key_compare > >, // CQ-zone+mode+band - ordered_unique, - composite_key, - member, - member > >, + ordered_non_unique, + composite_key, + member, + member > >, // CQ-zone+band - ordered_unique, - composite_key, - member > >, + ordered_non_unique, + composite_key, + member > >, // ITU-zone+mode+band - ordered_unique, - composite_key, - member, - member > >, + ordered_non_unique, + composite_key, + member, + member > >, // ITU-zone+band - ordered_unique, - composite_key, - member > > > - > worked_type; + ordered_non_unique, + composite_key, + member > > > + > worked_before_database_type; namespace { @@ -188,7 +256,7 @@ public: QString path_; AD1CCty prefixes_; - worked_type worked_; + worked_before_database_type worked_; }; WorkedBefore::WorkedBefore () @@ -196,7 +264,7 @@ WorkedBefore::WorkedBefore () QFile inputFile {m_->path_}; if (inputFile.open (QFile::ReadOnly)) { - QTextStream in(&inputFile); + QTextStream in {&inputFile}; QString buffer; bool pre_read {false}; int end_position {-1}; diff --git a/qt_helpers.hpp b/qt_helpers.hpp index 0e9439a8a..b2ec7a49f 100644 --- a/qt_helpers.hpp +++ b/qt_helpers.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -77,6 +78,26 @@ public: } }; +namespace std +{ + // std::hash<> specialization for QString based on the dbj2 + // algorithm http://www.cse.yorku.ca/~oz/hash.html because qHash() + // is poor on 64-bit platforms due to being a 32-bit hash value + template<> + struct hash + { + std::size_t operator () (QString const& s) const noexcept + { + std::size_t hash {5381}; + for (int i = 0; i < s.size (); ++i) + { + hash = ((hash << 5) + hash) + ((s.at (i).row () << 8) | s.at (i).cell ()); + } + return hash; + } + }; +} + // Register some useful Qt types with QMetaType Q_DECLARE_METATYPE (QHostAddress);