This is an automated email from the ASF dual-hosted git repository.

amc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 6661017  hostdb: Replace the last TSHashTable with IntrusiveHashMap.
6661017 is described below

commit 66610170f2b55dba968172b961288af9710b0839
Author: Xavier Chi <[email protected]>
AuthorDate: Tue Nov 13 16:06:42 2018 -0600

    hostdb: Replace the last TSHashTable with IntrusiveHashMap.
---
 iocore/hostdb/HostDB.cc         |   7 ++-
 iocore/hostdb/P_RefCountCache.h | 116 ++++++++++++++++++++--------------------
 2 files changed, 61 insertions(+), 62 deletions(-)

diff --git a/iocore/hostdb/HostDB.cc b/iocore/hostdb/HostDB.cc
index 5f76b1c..6e50c44 100644
--- a/iocore/hostdb/HostDB.cc
+++ b/iocore/hostdb/HostDB.cc
@@ -1558,14 +1558,13 @@ HostDBContinuation::iterateEvent(int event, Event *e)
       return EVENT_CONT;
     }
 
-    TSHashTable<RefCountCacheHashing> *partMap = 
hostDB.refcountcache->get_partition(current_iterate_pos).get_map();
-    for (RefCountCachePartition<HostDBInfo>::iterator_type i = 
partMap->begin(); i != partMap->end(); ++i) {
-      HostDBInfo *r = (HostDBInfo *)i.m_value->item.get();
+    IntrusiveHashMap<RefCountCacheLinkage> &partMap = 
hostDB.refcountcache->get_partition(current_iterate_pos).get_map();
+    for (const auto &it : partMap) {
+      HostDBInfo *r = static_cast<HostDBInfo *>(it.item.get());
       if (r && !r->is_failed()) {
         action.continuation->handleEvent(EVENT_INTERVAL, static_cast<void 
*>(r));
       }
     }
-
     current_iterate_pos++;
     // And reschedule ourselves to pickup the next bucket after 
HOST_DB_RETRY_PERIOD.
     Debug("hostdb", "iterateEvent event=%d eventp=%p: completed current 
iteration %ld of %ld", event, e, current_iterate_pos,
diff --git a/iocore/hostdb/P_RefCountCache.h b/iocore/hostdb/P_RefCountCache.h
index 5e1b7d6..8655d34 100644
--- a/iocore/hostdb/P_RefCountCache.h
+++ b/iocore/hostdb/P_RefCountCache.h
@@ -25,7 +25,7 @@
 #include <I_EventSystem.h>
 #include <P_EventSystem.h> // TODO: less? just need ET_TASK
 
-#include "tscore/Map.h"
+#include "tscore/IntrusiveHashMap.h"
 #include "tscore/PriorityQueue.h"
 
 #include "tscore/List.h"
@@ -75,7 +75,8 @@ class RefCountCacheHashEntry
 {
 public:
   Ptr<RefCountObj> item;
-  LINK(RefCountCacheHashEntry, item_link);
+  RefCountCacheHashEntry *_next{nullptr};
+  RefCountCacheHashEntry *_prev{nullptr};
   PriorityQueueEntry<RefCountCacheHashEntry *> *expiry_entry;
   RefCountCacheItemMeta meta;
 
@@ -115,24 +116,32 @@ public:
 // Since the hashing values are all fixed size, we can simply use a 
classAllocator to avoid mallocs
 extern ClassAllocator<PriorityQueueEntry<RefCountCacheHashEntry *>> 
expiryQueueEntry;
 
-struct RefCountCacheHashing {
-  typedef uint64_t ID;
-  typedef uint64_t const Key;
-  typedef RefCountCacheHashEntry Value;
-  typedef DList(RefCountCacheHashEntry, item_link) ListHead;
+struct RefCountCacheLinkage {
+  using key_type   = uint64_t const;
+  using value_type = RefCountCacheHashEntry;
 
-  static ID
-  hash(Key key)
+  static value_type *&
+  next_ptr(value_type *value)
+  {
+    return value->_next;
+  }
+  static value_type *&
+  prev_ptr(value_type *value)
+  {
+    return value->_prev;
+  }
+  static uint64_t
+  hash_of(key_type key)
   {
     return key;
   }
-  static Key
-  key(Value const *value)
+  static key_type
+  key_of(value_type *v)
   {
-    return value->meta.key;
+    return v->meta.key;
   }
   static bool
-  equal(Key lhs, Key rhs)
+  equal(key_type lhs, key_type rhs)
   {
     return lhs == rhs;
   }
@@ -143,6 +152,8 @@ struct RefCountCacheHashing {
 template <class C> class RefCountCachePartition
 {
 public:
+  using hash_type = IntrusiveHashMap<RefCountCacheLinkage>;
+
   RefCountCachePartition(unsigned int part_num, uint64_t max_size, unsigned 
int max_items, RecRawStatBlock *rsb = nullptr);
   Ptr<C> get(uint64_t key);
   void put(uint64_t key, C *item, int size = 0, int expire_time = 0);
@@ -151,15 +162,12 @@ public:
   void clear();
   bool is_full() const;
   bool make_space_for(unsigned int);
-  template <class Iterator> void dealloc_entry(Iterator ptr);
+  void dealloc_entry(hash_type::iterator ptr);
 
   size_t count() const;
   void copy(std::vector<RefCountCacheHashEntry *> &items);
 
-  typedef typename TSHashTable<RefCountCacheHashing>::iterator iterator_type;
-  typedef typename TSHashTable<RefCountCacheHashing>::self hash_type;
-  typedef typename TSHashTable<RefCountCacheHashing>::Location location_type;
-  TSHashTable<RefCountCacheHashing> *get_map();
+  hash_type &get_map();
 
   Ptr<ProxyMutex> lock; // Lock
 
@@ -190,11 +198,10 @@ Ptr<C>
 RefCountCachePartition<C>::get(uint64_t key)
 {
   this->metric_inc(refcountcache_total_lookups_stat, 1);
-  location_type l = this->item_map.find(key);
-  if (l.isValid()) {
+  if (auto it = this->item_map.find(key); it != this->item_map.end()) {
     // found
     this->metric_inc(refcountcache_total_hits_stat, 1);
-    return make_ptr((C *)l.m_value->item.get());
+    return make_ptr(static_cast<C *>(it->item.get()));
   } else {
     return Ptr<C>();
   }
@@ -241,44 +248,37 @@ template <class C>
 void
 RefCountCachePartition<C>::erase(uint64_t key, ink_time_t expiry_time)
 {
-  location_type l = this->item_map.find(key);
-  if (l.isValid()) {
-    if (expiry_time >= 0 && l.m_value->meta.expiry_time != expiry_time) {
+  if (auto it = this->item_map.find(key); it != this->item_map.end()) {
+    if (expiry_time >= 0 && it->meta.expiry_time != expiry_time) {
       return;
     }
-
-    // TSHashMap does NOT clean up the item-- this remove just removes it from 
the map
-    // we are responsible for cleaning it up here
-    this->item_map.remove(l);
-    this->dealloc_entry(l);
+    this->item_map.erase(it);
+    this->dealloc_entry(it);
   }
 }
 
 template <class C>
-template <class Iterator>
 void
-RefCountCachePartition<C>::dealloc_entry(Iterator ptr)
+RefCountCachePartition<C>::dealloc_entry(hash_type::iterator ptr)
 {
-  if (ptr.m_value) {
-    // decrement usag are not cleaned up. The values are not touched in this 
method, therefore it is safe
-    // counters
-    this->size -= ptr->meta.size;
-    this->items--;
-
-    this->metric_inc(refcountcache_current_size_stat, 
-((int64_t)ptr->meta.size));
-    this->metric_inc(refcountcache_current_items_stat, -1);
-
-    // remove from expiry queue
-    if (ptr->expiry_entry != nullptr) {
-      Debug("refcountcache", "partition %d deleting item from expiry_queue 
idx=%d", this->part_num, ptr->expiry_entry->index);
-
-      this->expiry_queue.erase(ptr->expiry_entry);
-      expiryQueueEntry.free(ptr->expiry_entry);
-      ptr->expiry_entry = nullptr; // To avoid the destruction of `l` calling 
the destructor again-- and causing issues
-    }
+  // decrement usage are not cleaned up. The values are not touched in this 
method, therefore it is safe
+  // counters
+  this->size -= ptr->meta.size;
+  this->items--;
+
+  this->metric_inc(refcountcache_current_size_stat, 
-((int64_t)ptr->meta.size));
+  this->metric_inc(refcountcache_current_items_stat, -1);
 
-    RefCountCacheHashEntry::free<C>(ptr.m_value);
+  // remove from expiry queue
+  if (ptr->expiry_entry != nullptr) {
+    Debug("refcountcache", "partition %d deleting item from expiry_queue 
idx=%d", this->part_num, ptr->expiry_entry->index);
+
+    this->expiry_queue.erase(ptr->expiry_entry);
+    expiryQueueEntry.free(ptr->expiry_entry);
+    ptr->expiry_entry = nullptr; // To avoid the destruction of `l` calling 
the destructor again-- and causing issues
   }
+
+  RefCountCacheHashEntry::free<C>(ptr);
 }
 
 template <class C>
@@ -288,12 +288,12 @@ RefCountCachePartition<C>::clear()
   // Since the hash nodes embed the list pointers, you can't iterate over the
   // hash elements and deallocate them, let alone remove them from the hash.
   // Hence, this monstrosity.
-  while (this->item_map.count() > 0) {
-    location_type pos = this->item_map.find(this->item_map.begin().m_value);
+  auto it = this->item_map.begin();
+  while (it != this->item_map.end()) {
+    auto cur = it;
 
-    ink_assert(pos.isValid());
-    this->item_map.remove(pos);
-    this->dealloc_entry(pos);
+    it = this->item_map.erase(it);
+    this->dealloc_entry(cur);
   }
 }
 
@@ -341,9 +341,9 @@ template <class C>
 void
 RefCountCachePartition<C>::copy(std::vector<RefCountCacheHashEntry *> &items)
 {
-  for (RefCountCachePartition<C>::iterator_type i = this->item_map.begin(); i 
!= this->item_map.end(); ++i) {
+  for (auto &&it : this->item_map) {
     RefCountCacheHashEntry *val = RefCountCacheHashEntry::alloc();
-    val->set(i.m_value->item.get(), i.m_value->meta.key, i.m_value->meta.size, 
i.m_value->meta.expiry_time);
+    val->set(it.item.get(), it.meta.key, it.meta.size, it.meta.expiry_time);
     items.push_back(val);
   }
 }
@@ -358,10 +358,10 @@ RefCountCachePartition<C>::metric_inc(RefCountCache_Stats 
metric_enum, int64_t d
 }
 
 template <class C>
-TSHashTable<RefCountCacheHashing> *
+IntrusiveHashMap<RefCountCacheLinkage> &
 RefCountCachePartition<C>::get_map()
 {
-  return &this->item_map;
+  return this->item_map;
 }
 
 // The header for the cache, this is used to check if the serialized cache is 
compatible

Reply via email to