folly: add bser encode/decode for dynamic
[folly.git] / folly / experimental / LockFreeRingBuffer.h
index f8dff773c317eafb3af13bb26bebd7da09c13815..f8c76e4174a17fe2dd8bc30ad204dad1c4245f10 100644 (file)
@@ -70,16 +70,24 @@ public:
   struct Cursor {
     explicit Cursor(uint64_t initialTicket) noexcept : ticket(initialTicket) {}
 
-    void moveForward(uint64_t steps = 1) noexcept {
+    /// Returns true if this cursor now points to a different
+    /// write, false otherwise.
+    bool moveForward(uint64_t steps = 1) noexcept {
+      uint64_t prevTicket = ticket;
       ticket += steps;
+      return prevTicket != ticket;
     }
 
-    void moveBackward(uint64_t steps = 1) noexcept {
+    /// Returns true if this cursor now points to a previous
+    /// write, false otherwise.
+    bool moveBackward(uint64_t steps = 1) noexcept {
+      uint64_t prevTicket = ticket;
       if (steps > ticket) {
         ticket = 0;
       } else {
         ticket -= steps;
       }
+      return prevTicket != ticket;
     }
 
   protected: // for test visibility reasons
@@ -87,7 +95,7 @@ public:
     friend class LockFreeRingBuffer;
   };
 
-  explicit LockFreeRingBuffer(size_t capacity) noexcept
+  explicit LockFreeRingBuffer(uint32_t capacity) noexcept
     : capacity_(capacity)
     , slots_(new detail::RingBufferSlot<T,Atom>[capacity])
     , ticket_(0)
@@ -101,6 +109,16 @@ public:
     slots_[idx(ticket)].write(turn(ticket), value);
   }
 
+  /// Perform a single write of an object of type T.
+  /// Writes can block iff a previous writer has not yet completed a write
+  /// for the same slot (before the most recent wrap-around).
+  /// Returns a Cursor pointing to the just-written T.
+  Cursor writeAndGetCursor(T& value) noexcept {
+    uint64_t ticket = ticket_.fetch_add(1);
+    slots_[idx(ticket)].write(turn(ticket), value);
+    return Cursor(ticket);
+  }
+
   /// Read the value at the cursor.
   /// Returns true if the read succeeded, false otherwise. If the return
   /// value is false, dest is to be considered partially read and in an
@@ -145,7 +163,7 @@ public:
   }
 
 private:
-  const size_t capacity_;
+  const uint32_t capacity_;
 
   const std::unique_ptr<detail::RingBufferSlot<T,Atom>[]> slots_;
 
@@ -156,7 +174,7 @@ private:
   }
 
   uint32_t turn(uint64_t ticket) noexcept {
-    return (ticket / capacity_);
+    return (uint32_t)(ticket / capacity_);
   }
 }; // LockFreeRingBuffer