Skip to content

Instantly share code, notes, and snippets.

@Chippiewill
Last active February 1, 2017 18:20
Show Gist options
  • Save Chippiewill/ce9e81342207a6cdc44bad08e49c4b81 to your computer and use it in GitHub Desktop.
Save Chippiewill/ce9e81342207a6cdc44bad08e49c4b81 to your computer and use it in GitHub Desktop.
namespace cb {
/**
* Intrusive map generates the key for the map based on the mapped
* value and a KeyFunc supplied as a template parameter.
*/
template <class KeyFunc,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T>>
class IntrusiveMap {
public:
using key_type = std::result_of<KeyFunc(const T&)>;
using mapped_type = T;
using _map_type = std::unordered_map<key_type, mapped_type, Hash, KeyEqual, Allocator>;
using value_type = _map_type::value_type;
using size_type = _map_type::size_type;
using difference_type = _map_type::difference_type;
using hasher = _map_type::hasher;
using key_equal = _map_type::key_equal;
using allocator_type = _map_type::allocator_type;
using reference = _map_type::reference;
using const_reference = _map_type::const_reference;
using pointer = _map_type::pointer;
using const_pointer = _map_type::const_pointer;
using iterator = _map_type::iterator;
using const_iterator = _map_type::const_iterator;
using local_iterator = _map_type::local_iterator;
using const_local_iterator = _map_type::const_local_iterator;
// constructors, destructors etc.
// Only const iterators to prevent mapped object being mutated
const_iterator begin() const;
const_iterator cbegin() const;
const_iterator end() const;
const_iterator cend() const;
const_iterator rbegin() const;
const_iterator crbegin() const;
const_iterator rend() const;
const_iterator crend() const;
bool empty() const;
size_type size() const;
size_type max_size() const;
void clear();
// Insert/emplace overloads look something like this
// General theme is to generate the key from the mapped value
// using the KeyFunc
std::pair<iterator,bool> insert(const mapped_type& value) {
return m.insert(KeyFunc(value), value);
}
// Lookup has two overloads, one with the key type, another with the mapped type
// also only returns const references
const T& at(const key_type& key) {
return m.at(key);
}
const T& at(const mapped_type& key) {
return m.at(KeyFunc(key));
}
private:
_map_type m;
}
}
#include "collections/vbucket_manifest_entry.h"
cb::const_char_buffer ManifestEntryKeyFunc(const Collections::VB::ManifestEntry& entry) {
return entry.getCharBuffer();
}
int main(int argc, char** argv) {
// Some sample usage
IntrusiveMap<ManifestEntryKeyFunc, Collections::VB::ManifestEntry> my_entry_map;
ManifestEntry entry{"my_collection", 0, 0, 0};
my_entry_map.insert(entry);
auto& entry_copy = my_entry_map.at("my_collection");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment