~ubuntu-branches/ubuntu/trusty/quassel/trusty-proposed

« back to all changes in this revision

Viewing changes to src/common/network.cpp

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2014-02-18 23:18:25 UTC
  • mto: This revision was merged to the branch mainline in revision 98.
  • Revision ID: package-import@ubuntu.com-20140218231825-hfgaeo3nmszt2pth
Tags: upstream-0.10~beta1
ImportĀ upstreamĀ versionĀ 0.10~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/***************************************************************************
2
 
 *   Copyright (C) 2005-2013 by the Quassel Project                        *
 
2
 *   Copyright (C) 2005-2014 by the Quassel Project                        *
3
3
 *   devel@quassel-irc.org                                                 *
4
4
 *                                                                         *
5
5
 *   This program is free software; you can redistribute it and/or modify  *
234
234
 
235
235
        _ircUsers[nick] = ircuser;
236
236
 
237
 
        SYNC_OTHER(addIrcUser, ARG(hostmask))
238
 
        // emit ircUserAdded(hostmask);
 
237
        // This method will be called with a nick instead of hostmask by setInitIrcUsersAndChannels().
 
238
        // Not a problem because initData contains all we need; however, making sure here to get the real
 
239
        // hostmask out of the IrcUser afterwards.
 
240
        QString mask = ircuser->hostmask();
 
241
        SYNC_OTHER(addIrcUser, ARG(mask));
 
242
        // emit ircUserAdded(mask);
239
243
        emit ircUserAdded(ircuser);
240
244
    }
241
245
 
774
778
}
775
779
 
776
780
 
 
781
// There's potentially a lot of users and channels, so it makes sense to optimize the format of this.
 
782
// Rather than sending a thousand maps with identical keys, we convert this into one map containing lists
 
783
// where each list index corresponds to a particular IrcUser. This saves sending the key names a thousand times.
 
784
// Benchmarks have shown space savings of around 56%, resulting in saving several MBs worth of data on sync
 
785
// (without compression) with a decent amount of IrcUsers.
777
786
QVariantMap Network::initIrcUsersAndChannels() const
778
787
{
779
788
    QVariantMap usersAndChannels;
780
 
    QVariantMap users;
781
 
    QVariantMap channels;
782
 
 
783
 
    QHash<QString, IrcUser *>::const_iterator userIter = _ircUsers.constBegin();
784
 
    QHash<QString, IrcUser *>::const_iterator userIterEnd = _ircUsers.constEnd();
785
 
    while (userIter != userIterEnd) {
786
 
        users[userIter.value()->hostmask()] = userIter.value()->toVariantMap();
787
 
        userIter++;
788
 
    }
789
 
    usersAndChannels["users"] = users;
790
 
 
791
 
    QHash<QString, IrcChannel *>::const_iterator channelIter = _ircChannels.constBegin();
792
 
    QHash<QString, IrcChannel *>::const_iterator channelIterEnd = _ircChannels.constEnd();
793
 
    while (channelIter != channelIterEnd) {
794
 
        channels[channelIter.value()->name()] = channelIter.value()->toVariantMap();
795
 
        channelIter++;
796
 
    }
797
 
    usersAndChannels["channels"] = channels;
 
789
 
 
790
    if (_ircUsers.count()) {
 
791
        QHash<QString, QVariantList> users;
 
792
        QHash<QString, IrcUser *>::const_iterator it = _ircUsers.begin();
 
793
        QHash<QString, IrcUser *>::const_iterator end = _ircUsers.end();
 
794
        while (it != end) {
 
795
            const QVariantMap &map = it.value()->toVariantMap();
 
796
            QVariantMap::const_iterator mapiter = map.begin();
 
797
            while (mapiter != map.end()) {
 
798
                users[mapiter.key()] << mapiter.value();
 
799
                ++mapiter;
 
800
            }
 
801
            ++it;
 
802
        }
 
803
        // Can't have a container with a value type != QVariant in a QVariant :(
 
804
        // However, working directly on a QVariantMap is awkward for appending, thus the detour via the hash above.
 
805
        QVariantMap userMap;
 
806
        foreach(const QString &key, users.keys())
 
807
            userMap[key] = users[key];
 
808
        usersAndChannels["Users"] = userMap;
 
809
    }
 
810
 
 
811
    if (_ircChannels.count()) {
 
812
        QHash<QString, QVariantList> channels;
 
813
        QHash<QString, IrcChannel *>::const_iterator it = _ircChannels.begin();
 
814
        QHash<QString, IrcChannel *>::const_iterator end = _ircChannels.end();
 
815
        while (it != end) {
 
816
            const QVariantMap &map = it.value()->toVariantMap();
 
817
            QVariantMap::const_iterator mapiter = map.begin();
 
818
            while (mapiter != map.end()) {
 
819
                channels[mapiter.key()] << mapiter.value();
 
820
                ++mapiter;
 
821
            }
 
822
            ++it;
 
823
        }
 
824
        QVariantMap channelMap;
 
825
        foreach(const QString &key, channels.keys())
 
826
            channelMap[key] = channels[key];
 
827
        usersAndChannels["Channels"] = channelMap;
 
828
    }
798
829
 
799
830
    return usersAndChannels;
800
831
}
804
835
{
805
836
    Q_ASSERT(proxy());
806
837
    if (isInitialized()) {
807
 
        qWarning() << "Network" << networkId() << "received init data for users and channels allthough there allready are known users or channels!";
 
838
        qWarning() << "Network" << networkId() << "received init data for users and channels although there already are known users or channels!";
808
839
        return;
809
840
    }
810
841
 
811
 
    QVariantMap users = usersAndChannels.value("users").toMap();
812
 
    QVariantMap::const_iterator userIter = users.constBegin();
813
 
    QVariantMap::const_iterator userIterEnd = users.constEnd();
814
 
    while (userIter != userIterEnd) {
815
 
        newIrcUser(userIter.key(), userIter.value().toMap());
816
 
        userIter++;
817
 
    }
818
 
 
819
 
    QVariantMap channels = usersAndChannels.value("channels").toMap();
820
 
    QVariantMap::const_iterator channelIter = channels.constBegin();
821
 
    QVariantMap::const_iterator channelIterEnd = channels.constEnd();
822
 
    while (channelIter != channelIterEnd) {
823
 
        newIrcChannel(channelIter.key(), channelIter.value().toMap());
824
 
        channelIter++;
 
842
    // toMap() and toList() are cheap, so we can avoid copying to lists...
 
843
    // However, we really have to make sure to never accidentally detach from the shared data!
 
844
 
 
845
    const QVariantMap &users = usersAndChannels["Users"].toMap();
 
846
 
 
847
    // sanity check
 
848
    int count = users["nick"].toList().count();
 
849
    foreach(const QString &key, users.keys()) {
 
850
        if (users[key].toList().count() != count) {
 
851
            qWarning() << "Received invalid usersAndChannels init data, sizes of attribute lists don't match!";
 
852
            return;
 
853
        }
 
854
    }
 
855
 
 
856
    // now create the individual IrcUsers
 
857
    for(int i = 0; i < count; i++) {
 
858
        QVariantMap map;
 
859
        foreach(const QString &key, users.keys())
 
860
            map[key] = users[key].toList().at(i);
 
861
        newIrcUser(map["nick"].toString(), map); // newIrcUser() properly handles the hostmask being just the nick
 
862
    }
 
863
 
 
864
    // same thing for IrcChannels
 
865
    const QVariantMap &channels = usersAndChannels["Channels"].toMap();
 
866
 
 
867
    // sanity check
 
868
    count = channels["name"].toList().count();
 
869
    foreach(const QString &key, channels.keys()) {
 
870
        if (channels[key].toList().count() != count) {
 
871
            qWarning() << "Received invalid usersAndChannels init data, sizes of attribute lists don't match!";
 
872
            return;
 
873
        }
 
874
    }
 
875
    // now create the individual IrcChannels
 
876
    for(int i = 0; i < count; i++) {
 
877
        QVariantMap map;
 
878
        foreach(const QString &key, channels.keys())
 
879
            map[key] = channels[key].toList().at(i);
 
880
        newIrcChannel(map["name"].toString(), map);
825
881
    }
826
882
}
827
883