Commit 95ad385e authored by Tudor Bosman's avatar Tudor Bosman Committed by Jordan DeLong

folly/PaddedSequence.h

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
parent d12f21b0
...@@ -49,4 +49,11 @@ ...@@ -49,4 +49,11 @@
#endif #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_ #endif // FOLLY_PORTABILITY_H_
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
# error "SmallLocks.h is currently x64-only." # error "SmallLocks.h is currently x64-only."
#endif #endif
#include "folly/Portability.h"
namespace folly { namespace folly {
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
...@@ -309,7 +311,6 @@ struct SpinLockArray { ...@@ -309,7 +311,6 @@ struct SpinLockArray {
// Check if T can theoretically cross a cache line. // Check if T can theoretically cross a cache line.
// NOTE: It should be alignof(std::max_align_t), but max_align_t // NOTE: It should be alignof(std::max_align_t), but max_align_t
// isn't supported by gcc 4.6.2. // isn't supported by gcc 4.6.2.
struct MaxAlign { char c; } __attribute__((aligned));
static_assert(alignof(MaxAlign) > 0 && static_assert(alignof(MaxAlign) > 0 &&
FOLLY_CACHE_LINE_SIZE % alignof(MaxAlign) == 0 && FOLLY_CACHE_LINE_SIZE % alignof(MaxAlign) == 0 &&
sizeof(T) <= alignof(MaxAlign), sizeof(T) <= alignof(MaxAlign),
......
...@@ -38,6 +38,13 @@ template <class T> ...@@ -38,6 +38,13 @@ template <class T>
class TypedIOBuf { class TypedIOBuf {
static_assert(std::is_standard_layout<T>::value, "must be standard layout"); static_assert(std::is_standard_layout<T>::value, "must be standard layout");
public: 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) { } explicit TypedIOBuf(IOBuf* buf) : buf_(buf) { }
IOBuf* ioBuf() { IOBuf* ioBuf() {
...@@ -65,6 +72,8 @@ class TypedIOBuf { ...@@ -65,6 +72,8 @@ class TypedIOBuf {
uint32_t length() const { uint32_t length() const {
return sdiv(buf_->length()); return sdiv(buf_->length());
} }
uint32_t size() const { return length(); }
uint32_t headroom() const { uint32_t headroom() const {
return sdiv(buf_->headroom()); return sdiv(buf_->headroom());
} }
...@@ -107,6 +116,31 @@ class TypedIOBuf { ...@@ -107,6 +116,31 @@ class TypedIOBuf {
void reserve(uint32_t minHeadroom, uint32_t minTailroom) { void reserve(uint32_t minHeadroom, uint32_t minTailroom) {
buf_->reserve(smul(minHeadroom), smul(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 * Simple wrapper to make it easier to treat this TypedIOBuf as an array of
...@@ -123,6 +157,7 @@ class TypedIOBuf { ...@@ -123,6 +157,7 @@ class TypedIOBuf {
void push(const T& data) { void push(const T& data) {
push(&data, &data + 1); push(&data, &data + 1);
} }
void push_back(const T& data) { push(data); }
/** /**
* Append multiple elements in a sequence; will call distance(). * Append multiple elements in a sequence; will call distance().
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment