proxygen
folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type > Class Template Reference

#include <ConcurrentSkipList-inl.h>

Public Member Functions

 NodeRecycler (const NodeAlloc &alloc)
 
 NodeRecycler ()
 
 ~NodeRecycler ()
 
void add (NodeType *node)
 
int addRef ()
 
int releaseRef ()
 
NodeAlloc & alloc ()
 

Private Member Functions

int refs () const
 

Private Attributes

std::unique_ptr< std::vector< NodeType * > > nodes_
 
std::atomic< int32_trefs_
 
std::atomic< bool > dirty_
 
MicroSpinLock lock_
 
NodeAlloc alloc_
 

Detailed Description

template<typename NodeType, typename NodeAlloc>
class folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >

Definition at line 259 of file ConcurrentSkipList-inl.h.

Constructor & Destructor Documentation

template<typename NodeType , typename NodeAlloc >
folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::~NodeRecycler ( )
inline

Member Function Documentation

template<typename NodeType , typename NodeAlloc >
void folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::add ( NodeType *  node)
inline
template<typename NodeType , typename NodeAlloc >
int folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::addRef ( )
inline

Definition at line 294 of file ConcurrentSkipList-inl.h.

template<typename NodeType , typename NodeAlloc >
NodeAlloc& folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::alloc ( )
inline
template<typename NodeType , typename NodeAlloc >
int folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::refs ( ) const
inlineprivate
template<typename NodeType , typename NodeAlloc >
int folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::releaseRef ( )
inline

Definition at line 298 of file ConcurrentSkipList-inl.h.

References destroy(), g(), LIKELY, and refs.

298  {
299  // We don't expect to clean the recycler immediately everytime it is OK
300  // to do so. Here, it is possible that multiple accessors all release at
301  // the same time but nobody would clean the recycler here. If this
302  // happens, the recycler will usually still get cleaned when
303  // such a race doesn't happen. The worst case is the recycler will
304  // eventually get deleted along with the skiplist.
305  if (LIKELY(!dirty_.load(std::memory_order_relaxed) || refs() > 1)) {
306  return refs_.fetch_add(-1, std::memory_order_relaxed);
307  }
308 
309  std::unique_ptr<std::vector<NodeType*>> newNodes;
310  {
311  std::lock_guard<MicroSpinLock> g(lock_);
312  if (nodes_.get() == nullptr || refs() > 1) {
313  return refs_.fetch_add(-1, std::memory_order_relaxed);
314  }
315  // once refs_ reaches 1 and there is no other accessor, it is safe to
316  // remove all the current nodes in the recycler, as we already acquired
317  // the lock here so no more new nodes can be added, even though new
318  // accessors may be added after that.
319  newNodes.swap(nodes_);
320  dirty_.store(false, std::memory_order_relaxed);
321  }
322 
323  // TODO(xliu) should we spawn a thread to do this when there are large
324  // number of nodes in the recycler?
325  for (auto& node : *newNodes) {
326  NodeType::destroy(alloc_, node);
327  }
328 
329  // decrease the ref count at the very end, to minimize the
330  // chance of other threads acquiring lock_ to clear the deleted
331  // nodes again.
332  return refs_.fetch_add(-1, std::memory_order_relaxed);
333  }
#define LIKELY(x)
Definition: Likely.h:47
static void destroy()
g_t g(f_t)

Member Data Documentation

template<typename NodeType , typename NodeAlloc >
NodeAlloc folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::alloc_
private

Definition at line 348 of file ConcurrentSkipList-inl.h.

template<typename NodeType , typename NodeAlloc >
std::atomic<bool> folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::dirty_
private

Definition at line 346 of file ConcurrentSkipList-inl.h.

template<typename NodeType , typename NodeAlloc >
MicroSpinLock folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::lock_
private

Definition at line 347 of file ConcurrentSkipList-inl.h.

template<typename NodeType , typename NodeAlloc >
std::unique_ptr<std::vector<NodeType*> > folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::nodes_
private

Definition at line 344 of file ConcurrentSkipList-inl.h.

template<typename NodeType , typename NodeAlloc >
std::atomic<int32_t> folly::detail::NodeRecycler< NodeType, NodeAlloc, typename std::enable_if< !NodeType::template DestroyIsNoOp< NodeAlloc >::value >::type >::refs_
private

Definition at line 345 of file ConcurrentSkipList-inl.h.


The documentation for this class was generated from the following file: