mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-15 08:31:57 -05:00
Fix badly broken worked before database indexing
This commit is contained in:
parent
a87f3d3a27
commit
dd9da021dd
@ -1,18 +1,34 @@
|
||||
#include "WorkedBefore.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/key_extractors.hpp>
|
||||
#include <QChar>
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
#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<QString> {} (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<identity<worked_entry>>,
|
||||
|
||||
//
|
||||
// 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<tag<call_mode_band>,
|
||||
ordered_non_unique<tag<call_mode_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, QString, &worked_entry::call_>,
|
||||
member<worked_entry, QString, &worked_entry::mode_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > >,
|
||||
// call+band
|
||||
ordered_unique<tag<call_band>,
|
||||
ordered_non_unique<tag<call_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, QString, &worked_entry::call_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > >,
|
||||
// grid+mode+band
|
||||
ordered_unique<tag<grid_mode_band>,
|
||||
ordered_non_unique<tag<grid_mode_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, QString, &worked_entry::grid_>,
|
||||
member<worked_entry, QString, &worked_entry::mode_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > >,
|
||||
// grid+band
|
||||
ordered_unique<tag<grid_band>,
|
||||
ordered_non_unique<tag<grid_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, QString, &worked_entry::grid_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > >,
|
||||
// country+mode+band
|
||||
ordered_unique<tag<entity_mode_band>,
|
||||
ordered_non_unique<tag<entity_mode_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, QString, &worked_entry::country_>,
|
||||
member<worked_entry, QString, &worked_entry::mode_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > >,
|
||||
// country+band
|
||||
ordered_unique<tag<entity_band>,
|
||||
ordered_non_unique<tag<entity_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, QString, &worked_entry::country_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > >,
|
||||
// continent+mode+band
|
||||
ordered_unique<tag<continent_mode_band>,
|
||||
ordered_non_unique<tag<continent_mode_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, AD1CCty::Continent, &worked_entry::continent_>,
|
||||
member<worked_entry, QString, &worked_entry::mode_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> >,
|
||||
composite_key_compare<
|
||||
Continent_less,
|
||||
std::less<QString>,
|
||||
std::less<QString> > >,
|
||||
composite_key_compare<Continent_less, std::less<QString>, std::less<QString> > >,
|
||||
// continent+band
|
||||
ordered_unique<tag<continent_band>,
|
||||
ordered_non_unique<tag<continent_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, AD1CCty::Continent, &worked_entry::continent_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> >,
|
||||
composite_key_compare<
|
||||
Continent_less,
|
||||
std::less<QString> > >,
|
||||
composite_key_compare<Continent_less, std::less<QString> > >,
|
||||
// CQ-zone+mode+band
|
||||
ordered_unique<tag<CQ_zone_mode_band>,
|
||||
ordered_non_unique<tag<CQ_zone_mode_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, int, &worked_entry::CQ_zone_>,
|
||||
member<worked_entry, QString, &worked_entry::mode_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > >,
|
||||
// CQ-zone+band
|
||||
ordered_unique<tag<CQ_zone_band>,
|
||||
ordered_non_unique<tag<CQ_zone_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, int, &worked_entry::CQ_zone_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > >,
|
||||
// ITU-zone+mode+band
|
||||
ordered_unique<tag<ITU_zone_mode_band>,
|
||||
ordered_non_unique<tag<ITU_zone_mode_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, int, &worked_entry::ITU_zone_>,
|
||||
member<worked_entry, QString, &worked_entry::mode_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > >,
|
||||
// ITU-zone+band
|
||||
ordered_unique<tag<ITU_zone_band>,
|
||||
ordered_non_unique<tag<ITU_zone_band>,
|
||||
composite_key<worked_entry,
|
||||
member<worked_entry, int, &worked_entry::ITU_zone_>,
|
||||
member<worked_entry, QString, &worked_entry::band_> > > >
|
||||
> worked_type;
|
||||
> 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};
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QString>
|
||||
#include <QChar>
|
||||
#include <QMetaObject>
|
||||
#include <QHostAddress>
|
||||
#include <QDataStream>
|
||||
@ -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<QString>
|
||||
{
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user