123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- #ifndef __LOC_UNORDERDED_SETMAP_H__
- #define __LOC_UNORDERDED_SETMAP_H__
- #include <algorithm>
- #include <loc_pla.h>
- #ifdef NO_UNORDERED_SET_OR_MAP
- #include <set>
- #include <map>
- #define unordered_set set
- #define unordered_map map
- #else
- #include <unordered_set>
- #include <unordered_map>
- #endif
- using std::unordered_set;
- using std::unordered_map;
- namespace loc_util {
- template <typename T>
- inline static void trimSet(unordered_set<T>& fromSet, const unordered_set<T>& rVals,
- unordered_set<T>* goneVals) {
- for (auto val : rVals) {
- if (fromSet.erase(val) > 0 && nullptr != goneVals) {
- goneVals->insert(val);
- }
- }
- }
- template <typename T>
- static unordered_set<T> removeAndReturnInterset(unordered_set<T>& s1, unordered_set<T>& s2) {
- unordered_set<T> common = {};
- for (auto b = s2.begin(); b != s2.end(); b++) {
- auto a = find(s1.begin(), s1.end(), *b);
- if (a != s1.end()) {
-
-
- common.insert(*a);
- s1.erase(a);
- s2.erase(b);
- }
- }
- return common;
- }
- template <typename KEY, typename VAL>
- class LocUnorderedSetMap {
- unordered_map<KEY, unordered_set<VAL>> mMap;
-
-
-
- bool trimOrRemove(typename unordered_map<KEY, unordered_set<VAL>>::iterator iter,
- const unordered_set<VAL>& rVals, unordered_set<VAL>* goneVals) {
- trimSet<VAL>(iter->second, rVals, goneVals);
- bool removeEntry = (iter->second.empty());
- if (removeEntry) {
- mMap.erase(iter);
- }
- return removeEntry;
- }
- public:
- inline LocUnorderedSetMap() {}
- inline LocUnorderedSetMap(size_t size) : LocUnorderedSetMap() {
- mMap.get_allocator().allocate(size);
- }
- inline bool empty() { return mMap.empty(); }
-
-
- inline unordered_set<VAL>* getValSetPtr(const KEY& key) {
- auto entry = mMap.find(key);
- return (entry != mMap.end()) ? &(entry->second) : nullptr;
- }
-
-
- inline unordered_set<VAL> getValSet(const KEY& key) {
- auto entry = mMap.find(key);
- return (entry != mMap.end()) ? entry->second : unordered_set<VAL>{};
- }
-
- inline unordered_set<KEY> getKeys() {
- unordered_set<KEY> keys = {};
- for (auto entry : mMap) {
- keys.insert(entry.first);
- }
- return keys;
- }
- inline bool remove(const KEY& key) {
- return mMap.erase(key) > 0;
- }
-
-
-
-
- inline void trimOrRemove(unordered_set<KEY>&& keys, const unordered_set<VAL>& rVals,
- unordered_set<KEY>* goneKeys, unordered_set<VAL>* goneVals) {
- trimOrRemove(keys, rVals, goneKeys, goneVals);
- }
- inline void trimOrRemove(unordered_set<KEY>& keys, const unordered_set<VAL>& rVals,
- unordered_set<KEY>* goneKeys, unordered_set<VAL>* goneVals) {
- for (auto key : keys) {
- auto iter = mMap.find(key);
- if (iter != mMap.end() && trimOrRemove(iter, rVals, goneVals) && nullptr != goneKeys) {
- goneKeys->insert(iter->first);
- }
- }
- }
-
-
- bool add(const KEY& key, const unordered_set<VAL>& newVals) {
- bool newEntryAdded = false;
- if (!newVals.empty()) {
- auto iter = mMap.find(key);
- if (iter != mMap.end()) {
- iter->second.insert(newVals.begin(), newVals.end());
- } else {
- mMap[key] = newVals;
- newEntryAdded = true;
- }
- }
- return newEntryAdded;
- }
-
-
-
- inline void add(const unordered_set<KEY>& keys, const unordered_set<VAL>&& newVals,
- unordered_set<KEY>* newKeys) {
- add(keys, newVals, newKeys);
- }
- inline void add(const unordered_set<KEY>& keys, const unordered_set<VAL>& newVals,
- unordered_set<KEY>* newKeys) {
- for (auto key : keys) {
- if (add(key, newVals) && nullptr != newKeys) {
- newKeys->insert(key);
- }
- }
- }
-
-
-
- inline unordered_set<VAL> update(const KEY& key, unordered_set<VAL>& newVals) {
- unordered_set<VAL> goneVals = {};
- if (newVals.empty()) {
- mMap.erase(key);
- } else {
- auto curVals = mMap[key];
- mMap[key] = newVals;
- goneVals = removeAndReturnInterset(curVals, newVals);
- }
- return goneVals;
- }
- };
- }
- #endif
|