< prev index next >

src/hotspot/share/utilities/resourceHash.hpp

Print this page

 89       }
 90       ptr = &(node->_next);
 91     }
 92     return ptr;
 93   }
 94 
 95   Node const** lookup_node(unsigned hash, K const& key) const {
 96     return const_cast<Node const**>(
 97         const_cast<ResourceHashtableBase*>(this)->lookup_node(hash, key));
 98   }
 99 
100  protected:
101   Node** table() const { return STORAGE::table(); }
102 
103   ResourceHashtableBase() : STORAGE(), _number_of_entries(0) {}
104   ResourceHashtableBase(unsigned size) : STORAGE(size), _number_of_entries(0) {}
105   NONCOPYABLE(ResourceHashtableBase);
106 
107   ~ResourceHashtableBase() {
108     if (ALLOC_TYPE == AnyObj::C_HEAP) {
109       Node* const* bucket = table();
110       const unsigned sz = table_size();
111       while (bucket < bucket_at(sz)) {
112         Node* node = *bucket;
113         while (node != nullptr) {
114           Node* cur = node;
115           node = node->_next;
116           delete cur;
117         }
118         ++bucket;
119       }
120     }
121   }
122 
123  public:
124   unsigned table_size() const { return STORAGE::table_size(); }
125   int number_of_entries() const { return _number_of_entries; }
126 
127   bool contains(K const& key) const {
128     return get(key) != nullptr;
129   }
130 
131   V* get(K const& key) const {
132     unsigned hv = HASH(key);
133     Node const** ptr = lookup_node(hv, key);
134     if (*ptr != nullptr) {
135       return const_cast<V*>(&(*ptr)->_value);
136     } else {
137       return nullptr;
138     }
139   }

278       ++bucket;
279     }
280   }
281 
282   // same as above, but unconditionally iterate all entries
283   template<typename Function>
284   void iterate_all(Function function) const { // lambda enabled API
285     auto wrapper = [&] (K& k, V& v) {
286       function(k, v);
287       return true;
288     };
289     iterate(wrapper);
290   }
291 
292   // ITER contains bool do_entry(K const&, V const&), which will be
293   // called for each entry in the table.  If do_entry() returns true,
294   // the entry is deleted.
295   template<class ITER>
296   void unlink(ITER* iter) {
297     const unsigned sz = table_size();
298     for (unsigned index = 0; index < sz; index++) {


299       Node** ptr = bucket_at(index);

300       while (*ptr != nullptr) {
301         Node* node = *ptr;
302         // do_entry must clean up the key and value in Node.
303         bool clean = iter->do_entry(node->_key, node->_value);
304         if (clean) {
305           *ptr = node->_next;
306           if (ALLOC_TYPE == AnyObj::C_HEAP) {
307             delete node;
308           }
309           _number_of_entries --;
310         } else {
311           ptr = &(node->_next);
312         }






















313       }






314     }


315   }
316 
317   template<typename Function>
318   TableStatistics statistics_calculate(Function size_function) const {
319     NumberSeq summary;
320     size_t literal_bytes = 0;
321     Node* const* bucket = table();
322     const unsigned sz = table_size();
323     while (bucket < bucket_at(sz)) {
324       Node* node = *bucket;
325       int count = 0;
326       while (node != nullptr) {
327         literal_bytes += size_function(node->_key, node->_value);
328         count++;
329         node = node->_next;
330       }
331       summary.add((double)count);
332       ++bucket;
333     }
334     return TableStatistics(summary, literal_bytes, sizeof(Node*), sizeof(Node));

 89       }
 90       ptr = &(node->_next);
 91     }
 92     return ptr;
 93   }
 94 
 95   Node const** lookup_node(unsigned hash, K const& key) const {
 96     return const_cast<Node const**>(
 97         const_cast<ResourceHashtableBase*>(this)->lookup_node(hash, key));
 98   }
 99 
100  protected:
101   Node** table() const { return STORAGE::table(); }
102 
103   ResourceHashtableBase() : STORAGE(), _number_of_entries(0) {}
104   ResourceHashtableBase(unsigned size) : STORAGE(size), _number_of_entries(0) {}
105   NONCOPYABLE(ResourceHashtableBase);
106 
107   ~ResourceHashtableBase() {
108     if (ALLOC_TYPE == AnyObj::C_HEAP) {
109       unlink_all();










110     }
111   }
112 
113  public:
114   unsigned table_size() const { return STORAGE::table_size(); }
115   int number_of_entries() const { return _number_of_entries; }
116 
117   bool contains(K const& key) const {
118     return get(key) != nullptr;
119   }
120 
121   V* get(K const& key) const {
122     unsigned hv = HASH(key);
123     Node const** ptr = lookup_node(hv, key);
124     if (*ptr != nullptr) {
125       return const_cast<V*>(&(*ptr)->_value);
126     } else {
127       return nullptr;
128     }
129   }

268       ++bucket;
269     }
270   }
271 
272   // same as above, but unconditionally iterate all entries
273   template<typename Function>
274   void iterate_all(Function function) const { // lambda enabled API
275     auto wrapper = [&] (K& k, V& v) {
276       function(k, v);
277       return true;
278     };
279     iterate(wrapper);
280   }
281 
282   // ITER contains bool do_entry(K const&, V const&), which will be
283   // called for each entry in the table.  If do_entry() returns true,
284   // the entry is deleted.
285   template<class ITER>
286   void unlink(ITER* iter) {
287     const unsigned sz = table_size();
288     int cnt = _number_of_entries;
289 
290     for (unsigned index = 0; cnt > 0 && index < sz; ++index) {
291       Node** ptr = bucket_at(index);
292 
293       while (*ptr != nullptr) {
294         Node* node = *ptr;
295         // do_entry must clean up the key and value in Node.
296         bool clean = iter->do_entry(node->_key, node->_value);
297         if (clean) {
298           *ptr = node->_next;
299           if (ALLOC_TYPE == AnyObj::C_HEAP) {
300             delete node;
301           }
302           _number_of_entries --;
303         } else {
304           ptr = &(node->_next);
305         }
306         if (--cnt <= 0) return;
307       }
308     }
309   }
310 
311   // unlink_all() is a specialized version of unlink() when we decide to remove all elements.
312   // It can not replace unlink(ITER* iter) if user-provided iter releases key/value
313   void unlink_all() {
314     Node** bucket = table();
315     const unsigned sz = table_size();
316 
317     while (_number_of_entries > 0 && bucket < bucket_at(sz)) {
318       Node* node = *bucket;
319       int n = 0;
320 
321       while (node != NULL) {
322         Node* cur = node;
323         node = node->_next;
324         if (ALLOC_TYPE == AnyObj::C_HEAP) {
325           delete cur;
326         }
327         n++;
328       }
329 
330       if (n > 0) {
331         *bucket = nullptr;
332         _number_of_entries -= n;
333       }
334       bucket++;
335     }
336 
337     assert(_number_of_entries == 0, "sanity check");
338   }
339 
340   template<typename Function>
341   TableStatistics statistics_calculate(Function size_function) const {
342     NumberSeq summary;
343     size_t literal_bytes = 0;
344     Node* const* bucket = table();
345     const unsigned sz = table_size();
346     while (bucket < bucket_at(sz)) {
347       Node* node = *bucket;
348       int count = 0;
349       while (node != nullptr) {
350         literal_bytes += size_function(node->_key, node->_value);
351         count++;
352         node = node->_next;
353       }
354       summary.add((double)count);
355       ++bucket;
356     }
357     return TableStatistics(summary, literal_bytes, sizeof(Node*), sizeof(Node));
< prev index next >