1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
22 * Cache Map implementation.
24 * Cache Map makes the following assumptions:
25 * - Cache Map is used for very fast but not guaranteed mapping;
26 * - only REL_EQ Relation can be used;
27 * - all objects used as keys or values has to be managed
28 * outside CacheMap (f.e. deletion);
29 * - (Key_t)0 is invalid key;
30 * - (Value_t)0 is invalid value;
34 #ifndef _DBE_CACHEMAP_H
35 #define _DBE_CACHEMAP_H
41 template <typename Key_t, typename Value_t>
42 class CacheMap : public Map<Key_t, Value_t>
48 void put (Key_t key, Value_t val);
49 Value_t get (Key_t key);
50 Value_t get (Key_t key, typename Map<Key_t, Value_t>::Relation rel);
67 static const int INIT_SIZE;
68 static const int MAX_SIZE;
70 static unsigned hash (Key_t key);
71 Entry *getEntry (Key_t key);
79 template <typename Key_t, typename Value_t>
80 const int CacheMap<Key_t, Value_t>::INIT_SIZE = 1 << 14;
81 template <typename Key_t, typename Value_t>
82 const int CacheMap<Key_t, Value_t>::MAX_SIZE = 1 << 20;
84 template <typename Key_t, typename Value_t>CacheMap<Key_t, Value_t>
88 chunks = new Entry*[32];
90 chunks[nchunks++] = new Entry[cursize];
94 template <typename Key_t, typename Value_t>
95 CacheMap<Key_t, Value_t>::~CacheMap ()
97 for (int i = 0; i < nchunks; i++)
102 template <typename Key_t, typename Value_t>
104 CacheMap<Key_t, Value_t>::hash (Key_t key)
106 unsigned h = (unsigned) key ^ (unsigned) (key >> 32);
107 h ^= (h >> 20) ^ (h >> 12);
108 return h ^ (h >> 7) ^ (h >> 4);
111 template <typename Key_t, typename Value_t>
113 CacheMap<Key_t, Value_t>::put (Key_t key, Value_t val)
115 if (nputs >= cursize && cursize < MAX_SIZE)
117 // Allocate new chunk for entries.
118 chunks[nchunks++] = new Entry[cursize];
121 // Copy all old entries to the newly allocated chunk
122 Entry *newchunk = chunks[nchunks - 1];
124 int nextsz = INIT_SIZE;
125 for (int i = 0; i < nchunks - 1; i++)
127 Entry *oldchunk = chunks[i];
128 for (int j = prevsz; j < nextsz; j++)
129 newchunk[j] = oldchunk[j - prevsz];
134 Entry *entry = getEntry (key);
140 template <typename Key_t, typename Value_t>
141 typename CacheMap<Key_t, Value_t>::Entry *
142 CacheMap<Key_t, Value_t>::getEntry (Key_t key)
144 unsigned idx = hash (key);
147 for (; i > 0; i -= 1, j /= 2)
152 return &chunks[i][idx & (j - 1)];
155 template <typename Key_t, typename Value_t>
157 CacheMap<Key_t, Value_t>::get (Key_t key)
159 Entry *entry = getEntry (key);
160 return entry->key == key ? entry->val : (Value_t) 0;
163 template <typename Key_t, typename Value_t>
165 CacheMap<Key_t, Value_t>::get (Key_t key, typename Map<Key_t, Value_t>::Relation rel)
167 if (rel != Map<Key_t, Value_t>::REL_EQ)
172 template <typename Key_t, typename Value_t>
174 CacheMap<Key_t, Value_t>::remove (Key_t key)
176 Entry *entry = getEntry (key);
177 Value_t res = (Value_t) 0;
178 if (entry->key == key)
181 entry->val = (Value_t) 0;