|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <cstdlib> |
| 4 | +#include <map> |
| 5 | +#include <vector> |
| 6 | + |
| 7 | +struct DenseUniqueValueMap { |
| 8 | + using key_type = int; // IRL we store client here |
| 9 | + using value_type = size_t; // IRL we store taskId here |
| 10 | + using iterator_type = std::map<key_type, size_t>::iterator; |
| 11 | + std::map<value_type, iterator_type> valueToKeyIter; |
| 12 | + // Bunch of keys(clients), and number of tasks belongs to it |
| 13 | + std::map<key_type, size_t> keyToRefCount; |
| 14 | + |
| 15 | + key_type get_key(value_type value) { |
| 16 | + if (!valueToKeyIter.contains(value)) { |
| 17 | + // TODO: handle error more gracefully |
| 18 | + exit(1); |
| 19 | + } |
| 20 | + auto keyIter = valueToKeyIter[value]; |
| 21 | + return keyIter->first; |
| 22 | + } |
| 23 | + |
| 24 | + void add(key_type key, value_type value) { |
| 25 | + auto it = valueToKeyIter.find(value); |
| 26 | + if (it != valueToKeyIter.end()) { |
| 27 | + if (it->first != key) { |
| 28 | + // TODO: handle error more gracefully |
| 29 | + exit(1); |
| 30 | + } else { |
| 31 | + return; |
| 32 | + } |
| 33 | + } |
| 34 | + |
| 35 | + auto [kIter, _] = keyToRefCount.insert_or_assign(key, ++keyToRefCount[key]); |
| 36 | + it->second = kIter; |
| 37 | + } |
| 38 | + |
| 39 | + key_type removeValue(value_type value) { |
| 40 | + auto it = valueToKeyIter.find(value); |
| 41 | + if (it == valueToKeyIter.end()) { |
| 42 | + // TODO: handle error more gracefully |
| 43 | + exit(1); |
| 44 | + } |
| 45 | + auto keysMapIter = it->second; |
| 46 | + valueToKeyIter.erase(it); |
| 47 | + auto key = keysMapIter->first; |
| 48 | + if (keysMapIter->second == 1) { |
| 49 | + keyToRefCount.erase(keysMapIter); |
| 50 | + } |
| 51 | + return key; |
| 52 | + } |
| 53 | + |
| 54 | + auto& getKeysRef() { return keyToRefCount; } |
| 55 | +}; |
0 commit comments