• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2014 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef EMUGL_COMMON_ID_TO_OBJECT_MAP_H
16 #define EMUGL_COMMON_ID_TO_OBJECT_MAP_H
17 
18 #include <stddef.h>
19 
20 namespace emugl {
21 
22 // Base implementation class for IdToObjectMap template.
23 // Used to reduce template-instanciated code generation.
24 class IdToObjectMapBase {
25 public:
26     // The type of keys in this map.
27     typedef unsigned KeyType;
28 
29     // Values higher than kMaxId cannot be used as map keys.
30     enum {
31         kMaxId = 0xfffffffdU,
32     };
33 
isValidKey(KeyType key)34     static inline bool isValidKey(KeyType key) {
35         return key <= kMaxId;
36     }
37 
38 protected:
39     IdToObjectMapBase();
40 
41     ~IdToObjectMapBase();
42 
43     void clear();
44 
45     // Return size
size()46     inline size_t size() const { return mCount; }
47 
capacity()48     inline size_t capacity() const { return 1U << mShift; }
49 
50     // Return true iff the map contains a given key.
51     bool contains(KeyType key) const;
52 
53     // Find a value associated with a given |key| in the map.
54     // On success, return true and sets |*value| to the value/pointer,
55     // which is _still_ owned by the map.
56     // On failure, return false and sets |*value| to NULL.
57     bool find(KeyType key, void** value) const;
58 
59     // Associate a value with a given |key| in the map.
60     // Return the old value for the key, if any. Caller is responsible
61     // for freeing it.
62     void* set(KeyType key, void* value);
63 
64     // Remove the value associated with a given |key|.
65     // Return the old value, if any. Caller is responsible for
66     // freeing it.
67     void* remove(KeyType key);
68 
69     size_t mCount;
70     size_t mShift;
71     KeyType* mKeys;
72     void** mValues;
73 
74 private:
75     // Resize the map if needed to ensure it can hold at least |newSize|
76     // entries.
77     void resize(size_t newSize);
78 };
79 
80 // A templated data container that acts as a dictionary mapping unsigned
81 // integer keys to heap-allocated objects of type T. The dictionary
82 // owns the objects associated with its keys, and automatically destroys
83 // them when it is destroyed, or during replacement or removal.
84 template <class T>
85 class IdToObjectMap : public IdToObjectMapBase {
86 public:
87     // Initialize an empty instance.
IdToObjectMap()88     IdToObjectMap() : IdToObjectMapBase() {}
89 
90     // Destroy this instance.
~IdToObjectMap()91     ~IdToObjectMap() {
92         clear();
93     }
94 
95     // Return the number of items in this map.
size()96     inline size_t size() const { return IdToObjectMapBase::size(); }
97 
98     // Return true iff the map is empty.
empty()99     inline bool empty() const { return !IdToObjectMapBase::size(); }
100 
101     // Remove all items from the map.
102     void clear();
103 
104     // Returns true iff the dictionary contains a value for |key|.
contains(KeyType key)105     inline bool contains(KeyType key) const {
106         return IdToObjectMapBase::contains(key);
107     }
108 
109     // Find the value corresponding to |key| in this map.
110     // On success, return true, and sets |*value| to point to the
111     // value (still owned by the instance). On failure, return false.
find(KeyType key,T ** value)112     inline bool find(KeyType key, T** value) const {
113         return IdToObjectMapBase::find(key, reinterpret_cast<void**>(value));
114     }
115 
116     // Return the value associated with a given |key|, or NULL if it is
117     // not in the map. Result is still owned by the map.
get(KeyType key)118     inline T* get(KeyType key) const {
119         T* result = NULL;
120         this->find(key, &result);
121         return result;
122     }
123 
124     // Associate |value| with a given |key|. Returns true if a previous
125     // value was replaced, and false if this is the first time a value
126     // was associated with the given key. IMPORTANT: This transfers
127     // ownership of |value| to the map instance. In case of replacement,
128     // the old value is automatically destroyed. Using NULL as the value
129     // is equivalent to calling remove().
130     bool set(KeyType key, T* value);
131 
132     // Remove any value associated with |key|.
133     // Return true iff a value was associated with the key and destroyed
134     // by this function, false if there was no value associated with the
135     // key (or if it was NULL).
136     bool remove(KeyType key);
137 };
138 
139 template <class T>
clear()140 void IdToObjectMap<T>::clear() {
141     size_t n = capacity();
142     while (n > 0) {
143         --n;
144         if (!isValidKey(mKeys[n]))
145             continue;
146 
147         delete static_cast<T*>(mValues[n]);
148         mValues[n] = NULL;
149         mKeys[n] = kMaxId + 1U;
150     }
151     mCount = 0;
152 }
153 
154 template <class T>
set(KeyType key,T * value)155 bool IdToObjectMap<T>::set(KeyType key, T* value) {
156     T* oldValue = static_cast<T*>(IdToObjectMapBase::set(key, value));
157     if (!oldValue) {
158         return false;
159     }
160     delete oldValue;
161     return true;
162 }
163 
164 template <class T>
remove(KeyType key)165 bool IdToObjectMap<T>::remove(KeyType key) {
166     T* oldValue = static_cast<T*>(IdToObjectMapBase::remove(key));
167     if (!oldValue)
168         return false;
169     delete oldValue;
170     return true;
171 }
172 
173 }  // namespace emugl
174 
175 
176 #endif  // EMUGL_COMMON_ID_TO_OBJECT_MAP_H
177