1 /*++
2 Copyright (c) 2017 Microsoft Corporation
3 
4 Module Name:
5 
6     obj_ref_hashtable.h
7 
8 Abstract:
9 
10     corresponding obj_map with reference count management.
11 
12 Author:
13 
14     Nikolaj Bjorner (nbjorner) 2017-12-8
15 
16 Revision History:
17 
18 --*/
19 #pragma once
20 
21 #include "util/obj_hashtable.h"
22 
23 template<typename M, typename Key, typename Value>
24 class obj_ref_map {
25     M&                  m;
26     obj_map<Key, Value> m_table;
27 public:
28     typedef typename obj_map<Key, Value>::iterator iterator;
29     typedef Key key;
30     typedef Value value;
31     typedef typename obj_map<Key, Value>::key_data key_data;
32     typedef typename obj_map<Key, Value>::obj_map_entry obj_map_entry;
33 
obj_ref_map(M & m)34     obj_ref_map(M& m):m(m) {}
35 
~obj_ref_map()36     ~obj_ref_map() { reset();  }
37 
reset()38     void reset() {
39         for (auto& kv : m_table) {
40             m.dec_ref(kv.m_key);
41         }
42         m_table.reset();
43     }
44 
finalize()45     void finalize() {
46         reset();
47         m_table.finalize();
48     }
49 
empty()50     bool empty() const { return m_table.empty(); }
51 
size()52     unsigned size() const { return m_table.size();  }
53 
capacity()54     unsigned capacity() const { return m_table.capacity();  }
55 
begin()56     iterator begin() const { return m_table.begin(); }
57 
end()58     iterator end() const { return m_table.end();  }
59 
insert(Key * const k,Value const & v)60     void insert(Key * const k, Value const & v) {
61         if (!m_table.contains(k)) m.inc_ref(k);
62         m_table.insert(k, v);
63     }
64 
insert(Key * const k,Value && v)65     void insert(Key * const k, Value && v) {
66         if (!m_table.contains(k)) m.inc_ref(k);
67         m_table.insert(k, v);
68     }
69 
insert_if_not_there(Key * k,Value const & v)70     key_data const & insert_if_not_there(Key * k, Value const & v) {
71         if (!m_table.contains(k)) m.inc_ref(k);
72         return m_table.insert_if_not_there(k, v);
73     }
74 
insert_if_not_there2(Key * k,Value const & v)75     obj_map_entry * insert_if_not_there2(Key * k, Value const & v) {
76         if (!m_table.contains(k)) m.inc_ref(k);
77         return m_table.insert_if_not_there2(k, v);
78     }
79 
find_core(Key * k)80     obj_map_entry * find_core(Key * k) const { return m_table.find_core(k); }
81 
find(Key * const k,Value & v)82     bool find(Key * const k, Value & v) const { return m_table.find(k, v); }
83 
find(key * k)84     value const & find(key * k) const { return m_table.find(k); }
85 
find(key * k)86     value & find(key * k)  { return m_table.find(k); }
87 
88     value const & operator[](key * k) const { return find(k); }
89 
90     value & operator[](key * k) { return find(k); }
91 
find_iterator(Key * k)92     iterator find_iterator(Key * k) const { return m_table.find_iterator(k); }
93 
contains(Key * k)94     bool contains(Key * k) const { return m_table.contains(k); }
95 
remove(Key * k)96     void remove(Key * k) {
97         if (m_table.contains(k)) {
98             m_table.remove(k);
99             m.dec_ref(k);
100         }
101     }
102 
erase(Key * k)103     void erase(Key * k) { remove(k); }
104 
get_num_collision()105     unsigned long long get_num_collision() const { return m_table.get_num_collision(); }
106 
swap(obj_ref_map & other)107     void swap(obj_ref_map & other) {
108         m_table.swap(other.m_table);
109     }
110 
111 
112 };
113 
114 
115 
116