folly/PaddedSequence.h
authorTudor Bosman <tudorb@fb.com>
Mon, 3 Dec 2012 20:54:57 +0000 (12:54 -0800)
committerJordan DeLong <jdelong@fb.com>
Sun, 16 Dec 2012 22:46:24 +0000 (14:46 -0800)
Summary:
Code that aids in storing data aligned on block (possibly cache-line)
boundaries, perhaps with padding. There's class Node which represents one
block, and Iterator which, given an iterator to a container of Nodes, gives you
an iterator to the underlying elements.  There's also Adaptor, which converts a
sequence of Node into a sequence of underlying elements. (with enough
functionality to make it useful, although it's not fully STL compatible)

Split off from https://phabricator.fb.com/D641114

Also includes changes to make TypedIOBuf container-like so it can be used with padded_sequence::Adaptor.

I plan to rename this to Padded.h / folly::padded in a separate diff.

Test Plan: test added

Reviewed By: soren@fb.com

FB internal diff: D646249

folly/Portability.h
folly/SmallLocks.h
folly/experimental/io/TypedIOBuf.h

index 6d373a2cef8840a5fb9aed3d37b6c3bb5195d56c..06241044f40c9648616161d9a8accf6afecdfa95 100644 (file)
 #endif
 
 
+// MaxAlign: max_align_t isn't supported by gcc
+#ifdef __GNUC__
+struct MaxAlign { char c; } __attribute__((aligned));
+#else /* !__GNUC__ */
+# error Cannot define MaxAlign on this platform
+#endif
+
 #endif // FOLLY_PORTABILITY_H_
index cefe2f3a0fe4b5cad386cfe3a2032c2a48664e46..0aa6f5dee521e0d261982bad5c1c49967f35c636 100644 (file)
@@ -49,6 +49,8 @@
 # error "SmallLocks.h is currently x64-only."
 #endif
 
+#include "folly/Portability.h"
+
 namespace folly {
 
 //////////////////////////////////////////////////////////////////////
@@ -309,7 +311,6 @@ struct SpinLockArray {
   // Check if T can theoretically cross a cache line.
   // NOTE: It should be alignof(std::max_align_t), but max_align_t
   // isn't supported by gcc 4.6.2.
-  struct MaxAlign { char c; } __attribute__((aligned));
   static_assert(alignof(MaxAlign) > 0 &&
                 FOLLY_CACHE_LINE_SIZE % alignof(MaxAlign) == 0 &&
                 sizeof(T) <= alignof(MaxAlign),
index 5658010ffda2cf86f986406c5310abb095c4067e..f9901a80a0af454c822a0213e71e0d748af9b75f 100644 (file)
@@ -38,6 +38,13 @@ template <class T>
 class TypedIOBuf {
   static_assert(std::is_standard_layout<T>::value, "must be standard layout");
  public:
+  typedef T value_type;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef uint32_t size_type;
+  typedef value_type* iterator;
+  typedef const value_type* const_iterator;
+
   explicit TypedIOBuf(IOBuf* buf) : buf_(buf) { }
 
   IOBuf* ioBuf() {
@@ -65,6 +72,8 @@ class TypedIOBuf {
   uint32_t length() const {
     return sdiv(buf_->length());
   }
+  uint32_t size() const { return length(); }
+
   uint32_t headroom() const {
     return sdiv(buf_->headroom());
   }
@@ -107,6 +116,31 @@ class TypedIOBuf {
   void reserve(uint32_t minHeadroom, uint32_t minTailroom) {
     buf_->reserve(smul(minHeadroom), smul(minTailroom));
   }
+  void reserve(uint32_t minTailroom) { reserve(0, minTailroom); }
+
+  const T* cbegin() const { return data(); }
+  const T* cend() const { return tail(); }
+  const T* begin() const { return cbegin(); }
+  const T* end() const { return cend(); }
+  T* begin() { return writableData(); }
+  T* end() { return writableTail(); }
+
+  const T& front() const {
+    assert(!empty());
+    return *begin();
+  }
+  T& front() {
+    assert(!empty());
+    return *begin();
+  }
+  const T& back() const {
+    assert(!empty());
+    return end()[-1];
+  }
+  T& back() {
+    assert(!empty());
+    return end()[-1];
+  }
 
   /**
    * Simple wrapper to make it easier to treat this TypedIOBuf as an array of
@@ -123,6 +157,7 @@ class TypedIOBuf {
   void push(const T& data) {
     push(&data, &data + 1);
   }
+  void push_back(const T& data) { push(data); }
 
   /**
    * Append multiple elements in a sequence; will call distance().