File indexing completed on 2024-04-28 15:39:55
0001 /* SPDX-FileCopyrightText: 2003-2020 The KPhotoAlbum Development Team 0002 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "GroupCounter.h" 0007 0008 #include "ImageDB.h" 0009 #include "MemberMap.h" 0010 0011 #include <kpabase/StringSet.h> 0012 using namespace DB; 0013 0014 /** 0015 * \class DB::GroupCounter 0016 * \brief Utility class to help counting matches for member groups. 0017 * 0018 * This class is used to count the member group matches when 0019 * categorizing. The class is instantiating with the category we currently 0020 * are counting items for. 0021 * 0022 * The class builds the inverse member map, that is a map pointing from items 0023 * to parent. 0024 * 0025 * As an example, imagine we have the following member map (stored in the 0026 * variable groupToMemberMap in the code): 0027 * \code 0028 * { USA |-> [Chicago, Santa Clara], 0029 * California |-> [Santa Clara, Los Angeles] } 0030 * \endcode 0031 * 0032 * The inverse map (stored in m_memberToGroup in the code ) will then look 0033 * like this: 0034 * \code 0035 * { Chicago |-> [USA], 0036 * Sanata Clara |-> [ USA, California ], 0037 * Los Angeless |-> [ California ] } 0038 * \endcode 0039 */ 0040 GroupCounter::GroupCounter(const QString &category) 0041 { 0042 const MemberMap map = DB::ImageDB::instance()->memberMap(); 0043 QMap<QString, StringSet> groupToMemberMap = map.groupMap(category); 0044 0045 m_memberToGroup.reserve(2729 /* A large prime */); 0046 m_groupCount.reserve(2729 /* A large prime */); 0047 0048 // Populate the m_memberToGroup map 0049 for (QMap<QString, StringSet>::Iterator groupToMemberIt = groupToMemberMap.begin(); groupToMemberIt != groupToMemberMap.end(); ++groupToMemberIt) { 0050 const StringSet members = groupToMemberIt.value(); 0051 const QString group = groupToMemberIt.key(); 0052 0053 for (const auto &member : members) { 0054 m_memberToGroup[member].append(group); 0055 } 0056 m_groupCount.insert(group, CountWithRange()); 0057 } 0058 } 0059 0060 /** 0061 * categories is the selected categories for one image, members may be Las Vegas, Chicago, and Los Angeles if the 0062 * category in question is Places. 0063 * This function then increases m_groupCount with 1 for each of the groups the relavant items belongs to 0064 * Las Vegas might increase the m_groupCount[Nevada] by one. 0065 * The tricky part is to avoid increasing it by more than 1 per image, that is what the countedGroupDict is 0066 * used for. 0067 */ 0068 void GroupCounter::count(const StringSet &categories, const ImageDate &date) 0069 { 0070 static StringSet countedGroupDict; 0071 0072 countedGroupDict.clear(); 0073 for (StringSet::const_iterator categoryIt = categories.begin(); categoryIt != categories.end(); ++categoryIt) { 0074 if (m_memberToGroup.contains(*categoryIt)) { 0075 const QStringList groups = m_memberToGroup[*categoryIt]; 0076 for (const QString &group : groups) { 0077 if (!countedGroupDict.contains(group)) { 0078 countedGroupDict.insert(group); 0079 m_groupCount[group].add(date); 0080 } 0081 } 0082 } 0083 // The item Nevada should itself go into the group Nevada. 0084 if (!countedGroupDict.contains(*categoryIt) && m_groupCount.contains(*categoryIt)) { 0085 countedGroupDict.insert(*categoryIt); 0086 m_groupCount[*categoryIt].add(date); 0087 } 0088 } 0089 } 0090 0091 QMap<QString, CountWithRange> GroupCounter::result() 0092 { 0093 QMap<QString, CountWithRange> res; 0094 0095 for (QHash<QString, CountWithRange>::const_iterator it = m_groupCount.constBegin(); it != m_groupCount.constEnd(); ++it) { 0096 if (it.value().count != 0) 0097 res.insert(it.key(), it.value()); 0098 } 0099 return res; 0100 } 0101 // vi:expandtab:tabstop=4 shiftwidth=4: