| OLD | NEW |
| 1 // Copyright (c) 2005, Google Inc. | 1 // Copyright (c) 2005, Google Inc. |
| 2 // All rights reserved. | 2 // All rights reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
| 9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
| 10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 void* get(Number k) const { | 88 void* get(Number k) const { |
| 89 if ((k >> BITS) > 0) { | 89 if ((k >> BITS) > 0) { |
| 90 return NULL; | 90 return NULL; |
| 91 } | 91 } |
| 92 return array_[k]; | 92 return array_[k]; |
| 93 } | 93 } |
| 94 | 94 |
| 95 // REQUIRES "k" is in range "[0,2^BITS-1]". | 95 // REQUIRES "k" is in range "[0,2^BITS-1]". |
| 96 // REQUIRES "k" has been ensured before. | 96 // REQUIRES "k" has been ensured before. |
| 97 // | 97 // |
| 98 // Sets the value 'v' for key 'k'. | 98 // Sets the value for KEY. |
| 99 void set(Number k, void* v) { | 99 void set(Number k, void* v) { |
| 100 array_[k] = v; | 100 array_[k] = v; |
| 101 } | 101 } |
| 102 | |
| 103 // Return the first non-NULL pointer found in this map for | |
| 104 // a page number >= k. Returns NULL if no such number is found. | |
| 105 void* Next(Number k) const { | |
| 106 while (k < (1 << BITS)) { | |
| 107 if (array_[k] != NULL) return array_[k]; | |
| 108 k++; | |
| 109 } | |
| 110 return NULL; | |
| 111 } | |
| 112 }; | 102 }; |
| 113 | 103 |
| 114 // Two-level radix tree | 104 // Two-level radix tree |
| 115 template <int BITS> | 105 template <int BITS> |
| 116 class TCMalloc_PageMap2 { | 106 class TCMalloc_PageMap2 { |
| 117 private: | 107 private: |
| 118 // Put 32 entries in the root and (2^BITS)/32 entries in each leaf. | 108 // Put 32 entries in the root and (2^BITS)/32 entries in each leaf. |
| 119 static const int ROOT_BITS = 5; | 109 static const int ROOT_BITS = 5; |
| 120 static const int ROOT_LENGTH = 1 << ROOT_BITS; | 110 static const int ROOT_LENGTH = 1 << ROOT_BITS; |
| 121 | 111 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 // Advance key past whatever is covered by this leaf node | 163 // Advance key past whatever is covered by this leaf node |
| 174 key = ((key >> LEAF_BITS) + 1) << LEAF_BITS; | 164 key = ((key >> LEAF_BITS) + 1) << LEAF_BITS; |
| 175 } | 165 } |
| 176 return true; | 166 return true; |
| 177 } | 167 } |
| 178 | 168 |
| 179 void PreallocateMoreMemory() { | 169 void PreallocateMoreMemory() { |
| 180 // Allocate enough to keep track of all possible pages | 170 // Allocate enough to keep track of all possible pages |
| 181 Ensure(0, 1 << BITS); | 171 Ensure(0, 1 << BITS); |
| 182 } | 172 } |
| 183 | |
| 184 void* Next(Number k) const { | |
| 185 while (k < (1 << BITS)) { | |
| 186 const Number i1 = k >> LEAF_BITS; | |
| 187 Leaf* leaf = root_[i1]; | |
| 188 if (leaf != NULL) { | |
| 189 // Scan forward in leaf | |
| 190 for (Number i2 = k & (LEAF_LENGTH - 1); i2 < LEAF_LENGTH; i2++) { | |
| 191 if (leaf->values[i2] != NULL) { | |
| 192 return leaf->values[i2]; | |
| 193 } | |
| 194 } | |
| 195 } | |
| 196 // Skip to next top-level entry | |
| 197 k = (i1 + 1) << LEAF_BITS; | |
| 198 } | |
| 199 return NULL; | |
| 200 } | |
| 201 }; | 173 }; |
| 202 | 174 |
| 203 // Three-level radix tree | 175 // Three-level radix tree |
| 204 template <int BITS> | 176 template <int BITS> |
| 205 class TCMalloc_PageMap3 { | 177 class TCMalloc_PageMap3 { |
| 206 private: | 178 private: |
| 207 // How many bits should we consume at each interior level | 179 // How many bits should we consume at each interior level |
| 208 static const int INTERIOR_BITS = (BITS + 2) / 3; // Round-up | 180 static const int INTERIOR_BITS = (BITS + 2) / 3; // Round-up |
| 209 static const int INTERIOR_LENGTH = 1 << INTERIOR_BITS; | 181 static const int INTERIOR_LENGTH = 1 << INTERIOR_BITS; |
| 210 | 182 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 } | 257 } |
| 286 | 258 |
| 287 // Advance key past whatever is covered by this leaf node | 259 // Advance key past whatever is covered by this leaf node |
| 288 key = ((key >> LEAF_BITS) + 1) << LEAF_BITS; | 260 key = ((key >> LEAF_BITS) + 1) << LEAF_BITS; |
| 289 } | 261 } |
| 290 return true; | 262 return true; |
| 291 } | 263 } |
| 292 | 264 |
| 293 void PreallocateMoreMemory() { | 265 void PreallocateMoreMemory() { |
| 294 } | 266 } |
| 295 | |
| 296 void* Next(Number k) const { | |
| 297 while (k < (Number(1) << BITS)) { | |
| 298 const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS); | |
| 299 const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1); | |
| 300 if (root_->ptrs[i1] == NULL) { | |
| 301 // Advance to next top-level entry | |
| 302 k = (i1 + 1) << (LEAF_BITS + INTERIOR_BITS); | |
| 303 } else { | |
| 304 Leaf* leaf = reinterpret_cast<Leaf*>(root_->ptrs[i1]->ptrs[i2]); | |
| 305 if (leaf != NULL) { | |
| 306 for (Number i3 = (k & (LEAF_LENGTH-1)); i3 < LEAF_LENGTH; i3++) { | |
| 307 if (leaf->values[i3] != NULL) { | |
| 308 return leaf->values[i3]; | |
| 309 } | |
| 310 } | |
| 311 } | |
| 312 // Advance to next interior entry | |
| 313 k = ((k >> LEAF_BITS) + 1) << LEAF_BITS; | |
| 314 } | |
| 315 } | |
| 316 return NULL; | |
| 317 } | |
| 318 }; | 267 }; |
| 319 | 268 |
| 320 #endif // TCMALLOC_PAGEMAP_H_ | 269 #endif // TCMALLOC_PAGEMAP_H_ |
| OLD | NEW |