Lua exception handling test
[folly.git] / folly / ConcurrentSkipList-inl.h
index 11813f03e4931cd042b573f98fb330e87fa9910f..61279a9652ac1e31b3a023d85c9910903bbc7b9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 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 <xliux@fb.com>
 
-#ifndef FOLLY_CONCURRENTSKIPLIST_INL_H_
-#define FOLLY_CONCURRENTSKIPLIST_INL_H_
+#pragma once
 
 #include <algorithm>
 #include <atomic>
 #include <mutex>
 #include <type_traits>
 #include <vector>
+
 #include <boost/noncopyable.hpp>
 #include <boost/random.hpp>
 #include <boost/type_traits.hpp>
 #include <glog/logging.h>
 
-#include "folly/Memory.h"
-#include "folly/SmallLocks.h"
-#include "folly/ThreadLocal.h"
+#include <folly/Memory.h>
+#include <folly/MicroSpinLock.h>
+#include <folly/ThreadLocal.h>
 
 namespace folly { namespace detail {
 
@@ -42,11 +42,12 @@ template<typename ValT, typename NodeT> class csl_iterator;
 
 template<typename T>
 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;
 
@@ -60,7 +61,7 @@ class SkipListNode : private boost::noncopyable {
       height * sizeof(std::atomic<SkipListNode*>);
     auto* node = static_cast<SkipListNode*>(alloc.allocate(size));
     // do placement new
-    new (node) SkipListNode(height, std::forward<U>(data), isHead);
+    new (node) SkipListNode(uint8_t(height), std::forward<U>(data), isHead);
     return node;
   }
 
@@ -71,16 +72,15 @@ class SkipListNode : private boost::noncopyable {
   }
 
   template<typename NodeAlloc>
-  static constexpr bool destroyIsNoOp() {
-    return IsArenaAllocator<NodeAlloc>::value &&
-           boost::has_trivial_destructor<std::atomic<SkipListNode*>>::value;
-  }
+  struct DestroyIsNoOp : std::integral_constant<bool,
+    IsArenaAllocator<NodeAlloc>::value &&
+    boost::has_trivial_destructor<SkipListNode>::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,13 +119,13 @@ 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:
@@ -231,11 +231,13 @@ class NodeRecycler;
 
 template<typename NodeType, typename NodeAlloc>
 class NodeRecycler<NodeType, NodeAlloc, typename std::enable_if<
-  !NodeType::template destroyIsNoOp<NodeAlloc>()>::type> {
+  !NodeType::template DestroyIsNoOp<NodeAlloc>::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_) {
@@ -315,14 +317,14 @@ class NodeRecycler<NodeType, NodeAlloc, typename std::enable_if<
 // to save on ConcurrentSkipList size.
 template<typename NodeType, typename NodeAlloc>
 class NodeRecycler<NodeType, NodeAlloc, typename std::enable_if<
-  NodeType::template destroyIsNoOp<NodeAlloc>()>::type> {
+  NodeType::template DestroyIsNoOp<NodeAlloc>::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_; }
 
@@ -331,5 +333,3 @@ class NodeRecycler<NodeType, NodeAlloc, typename std::enable_if<
 };
 
 }}  // namespaces
-
-#endif  // FOLLY_CONCURRENTSKIPLIST_INL_H_