X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FConcurrentSkipList-inl.h;h=881d05350bb31b77794c5d097a423d20e1687502;hb=d389a33028d1a8a8520bc5c85dbcf767131fd51c;hp=a875b69faecde2b22e35d38bbefe63371ecfa58b;hpb=406822b8462145dc26be2a1a837eda9c6706dfb2;p=folly.git diff --git a/folly/ConcurrentSkipList-inl.h b/folly/ConcurrentSkipList-inl.h index a875b69f..881d0535 100644 --- a/folly/ConcurrentSkipList-inl.h +++ b/folly/ConcurrentSkipList-inl.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,7 @@ // @author: Xin Liu -#ifndef FOLLY_CONCURRENTSKIPLIST_INL_H_ -#define FOLLY_CONCURRENTSKIPLIST_INL_H_ +#pragma once #include #include @@ -27,6 +26,7 @@ #include #include #include + #include #include #include @@ -38,20 +38,24 @@ namespace folly { namespace detail { -template class csl_iterator; +template class csl_iterator; -template +template class SkipListNode : private boost::noncopyable { - enum { + enum : uint16_t { IS_HEAD_NODE = 1, MARKED_FOR_REMOVAL = (1 << 1), FULLY_LINKED = (1 << 2), }; + public: typedef T value_type; - template::value>::type> + template < + typename NodeAlloc, + typename U, + typename = + typename std::enable_if::value>::type> static SkipListNode* create( NodeAlloc& alloc, int height, U&& data, bool isHead = false) { DCHECK(height >= 1 && height < 64) << height; @@ -60,27 +64,26 @@ class SkipListNode : private boost::noncopyable { height * sizeof(std::atomic); auto* node = static_cast(alloc.allocate(size)); // do placement new - new (node) SkipListNode(height, std::forward(data), isHead); + new (node) SkipListNode(uint8_t(height), std::forward(data), isHead); return node; } - template + template static void destroy(NodeAlloc& alloc, SkipListNode* node) { node->~SkipListNode(); alloc.deallocate(node); } - template - static constexpr bool destroyIsNoOp() { - return IsArenaAllocator::value && - boost::has_trivial_destructor>::value; - } + template + struct DestroyIsNoOp : std::integral_constant::value && + boost::has_trivial_destructor::value> { }; // copy the head node to a new head node assuming lock acquired SkipListNode* copyHead(SkipListNode* node) { DCHECK(node != nullptr && height_ > node->height_); setFlags(node->getFlags()); - for (int i = 0; i < node->height_; ++i) { + for (uint8_t i = 0; i < node->height_; ++i) { setSkip(i, node->skip(i)); } return this; @@ -119,23 +122,25 @@ class SkipListNode : private boost::noncopyable { bool isHeadNode() const { return getFlags() & IS_HEAD_NODE; } void setIsHeadNode() { - setFlags(getFlags() | IS_HEAD_NODE); + setFlags(uint16_t(getFlags() | IS_HEAD_NODE)); } void setFullyLinked() { - setFlags(getFlags() | FULLY_LINKED); + setFlags(uint16_t(getFlags() | FULLY_LINKED)); } void setMarkedForRemoval() { - setFlags(getFlags() | MARKED_FOR_REMOVAL); + setFlags(uint16_t(getFlags() | MARKED_FOR_REMOVAL)); } private: // Note! this can only be called from create() as a placement new. - template + template SkipListNode(uint8_t height, U&& data, bool isHead) : height_(height), data_(std::forward(data)) { spinLock_.init(); setFlags(0); - if (isHead) setIsHeadNode(); + if (isHead) { + setIsHeadNode(); + } // need to explicitly init the dynamic atomic pointer array for (uint8_t i = 0; i < height_; ++i) { new (&skip_[i]) std::atomic(nullptr); @@ -226,16 +231,18 @@ class SkipListRandomHeight { size_t sizeLimitTable_[kMaxHeight]; }; -template +template class NodeRecycler; -template +template class NodeRecycler()>::type> { + !NodeType::template DestroyIsNoOp::value>::type> { public: explicit NodeRecycler(const NodeAlloc& alloc) : refs_(0), dirty_(false), alloc_(alloc) { lock_.init(); } + explicit NodeRecycler() : refs_(0), dirty_(false) { lock_.init(); } + ~NodeRecycler() { CHECK_EQ(refs(), 0); if (nodes_) { @@ -248,7 +255,7 @@ class NodeRecycler g(lock_); if (nodes_.get() == nullptr) { - nodes_.reset(new std::vector(1, node)); + nodes_ = std::make_unique>(1, node); } else { nodes_->push_back(node); } @@ -313,16 +320,16 @@ class NodeRecycler +template class NodeRecycler()>::type> { + NodeType::template DestroyIsNoOp::value>::type> { public: explicit NodeRecycler(const NodeAlloc& alloc) : alloc_(alloc) { } void addRef() { } void releaseRef() { } - void add(NodeType* node) { } + void add(NodeType* /* node */) {} NodeAlloc& alloc() { return alloc_; } @@ -330,6 +337,5 @@ class NodeRecycler