proxygen
TypedIOBuf.h
Go to the documentation of this file.
1 /*
2  * Copyright 2013-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <algorithm>
20 #include <iterator>
21 #include <type_traits>
22 
23 #include <folly/io/IOBuf.h>
24 #include <folly/memory/Malloc.h>
25 
26 namespace folly {
27 
38 template <class T>
39 class TypedIOBuf {
40  static_assert(std::is_standard_layout<T>::value, "must be standard layout");
41 
42  public:
43  typedef T value_type;
44  typedef value_type& reference;
45  typedef const value_type& const_reference;
47  typedef value_type* iterator;
48  typedef const value_type* const_iterator;
49 
50  explicit TypedIOBuf(IOBuf* buf) : buf_(buf) {}
51 
52  IOBuf* ioBuf() {
53  return buf_;
54  }
55  const IOBuf* ioBuf() const {
56  return buf_;
57  }
58 
59  bool empty() const {
60  return buf_->empty();
61  }
62  const T* data() const {
63  return cast(buf_->data());
64  }
66  return cast(buf_->writableData());
67  }
68  const T* tail() const {
69  return cast(buf_->tail());
70  }
72  return cast(buf_->writableTail());
73  }
74  uint32_t length() const {
75  return sdiv(buf_->length());
76  }
77  uint32_t size() const {
78  return length();
79  }
80 
81  uint32_t headroom() const {
82  return sdiv(buf_->headroom());
83  }
84  uint32_t tailroom() const {
85  return sdiv(buf_->tailroom());
86  }
87  const T* buffer() const {
88  return cast(buf_->buffer());
89  }
91  return cast(buf_->writableBuffer());
92  }
93  const T* bufferEnd() const {
94  return cast(buf_->bufferEnd());
95  }
96  uint32_t capacity() const {
97  return sdiv(buf_->capacity());
98  }
99  void advance(uint32_t n) {
100  buf_->advance(smul(n));
101  }
102  void retreat(uint32_t n) {
103  buf_->retreat(smul(n));
104  }
105  void prepend(uint32_t n) {
106  buf_->prepend(smul(n));
107  }
108  void append(uint32_t n) {
109  buf_->append(smul(n));
110  }
111  void trimStart(uint32_t n) {
112  buf_->trimStart(smul(n));
113  }
114  void trimEnd(uint32_t n) {
115  buf_->trimEnd(smul(n));
116  }
117  void clear() {
118  buf_->clear();
119  }
120  void reserve(uint32_t minHeadroom, uint32_t minTailroom) {
121  buf_->reserve(smul(minHeadroom), smul(minTailroom));
122  }
123  void reserve(uint32_t minTailroom) {
124  reserve(0, minTailroom);
125  }
126 
127  const T* cbegin() const {
128  return data();
129  }
130  const T* cend() const {
131  return tail();
132  }
133  const T* begin() const {
134  return cbegin();
135  }
136  const T* end() const {
137  return cend();
138  }
139  T* begin() {
140  return writableData();
141  }
142  T* end() {
143  return writableTail();
144  }
145 
146  const T& front() const {
147  assert(!empty());
148  return *begin();
149  }
150  T& front() {
151  assert(!empty());
152  return *begin();
153  }
154  const T& back() const {
155  assert(!empty());
156  return end()[-1];
157  }
158  T& back() {
159  assert(!empty());
160  return end()[-1];
161  }
162 
167  const T& operator[](ssize_t idx) const {
168  assert(idx >= 0 && idx < length());
169  return data()[idx];
170  }
171 
172  T& operator[](ssize_t idx) {
173  assert(idx >= 0 && idx < length());
174  return writableData()[idx];
175  }
176 
180  void push(const T& data) {
181  push(&data, &data + 1);
182  }
183  void push_back(const T& data) {
184  push(data);
185  }
186 
190  template <class IT>
191  void push(IT begin, IT end) {
192  uint32_t n = std::distance(begin, end);
193  if (usingJEMalloc()) {
194  // Rely on xallocx() and avoid exponential growth to limit
195  // amount of memory wasted.
196  reserve(headroom(), n);
197  } else if (tailroom() < n) {
198  reserve(headroom(), std::max(n, 3 + size() / 2));
199  }
200  std::copy(begin, end, writableTail());
201  append(n);
202  }
203 
204  // Movable
205  TypedIOBuf(TypedIOBuf&&) = default;
206  TypedIOBuf& operator=(TypedIOBuf&&) = default;
207 
208  private:
209  // Non-copyable
210  TypedIOBuf(const TypedIOBuf&) = delete;
211  TypedIOBuf& operator=(const TypedIOBuf&) = delete;
212 
213  // cast to T*
214  static T* cast(uint8_t* p) {
215  return reinterpret_cast<T*>(p);
216  }
217  static const T* cast(const uint8_t* p) {
218  return reinterpret_cast<const T*>(p);
219  }
220  // divide by size
221  static uint32_t sdiv(uint32_t n) {
222  return n / sizeof(T);
223  }
224  // multiply by size
225  static uint32_t smul(uint32_t n) {
226  // In debug mode, check for overflow
227  assert((uint64_t(n) * sizeof(T)) < (uint64_t(1) << 32));
228  return n * sizeof(T);
229  }
230 
232 };
233 
234 } // namespace folly
static T * cast(uint8_t *p)
Definition: TypedIOBuf.h:214
const T * cbegin() const
Definition: TypedIOBuf.h:127
void trimEnd(uint32_t n)
Definition: TypedIOBuf.h:114
bool empty() const
Definition: IOBuf.cpp:482
const T & front() const
Definition: TypedIOBuf.h:146
LogLevel max
Definition: LogLevel.cpp:31
const T * bufferEnd() const
Definition: TypedIOBuf.h:93
void append(uint32_t n)
Definition: TypedIOBuf.h:108
bool usingJEMalloc() noexcept
Definition: Malloc.h:147
value_type & reference
Definition: TypedIOBuf.h:44
T & operator[](ssize_t idx)
Definition: TypedIOBuf.h:172
void retreat(uint32_t n)
Definition: TypedIOBuf.h:102
static uint32_t smul(uint32_t n)
Definition: TypedIOBuf.h:225
const uint8_t * tail() const
Definition: IOBuf.h:516
IOBuf * ioBuf()
Definition: TypedIOBuf.h:52
uint32_t size_type
Definition: TypedIOBuf.h:46
void advance(std::size_t amount)
Definition: IOBuf.h:632
const uint8_t * data() const
Definition: IOBuf.h:499
void reserve(std::size_t minHeadroom, std::size_t minTailroom)
Definition: IOBuf.h:741
uint32_t tailroom() const
Definition: TypedIOBuf.h:84
folly::std T
uint32_t size() const
Definition: TypedIOBuf.h:77
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
const uint8_t * bufferEnd() const
Definition: IOBuf.h:583
std::size_t capacity() const
Definition: IOBuf.h:593
std::size_t tailroom() const
Definition: IOBuf.h:551
bool empty() const
Definition: TypedIOBuf.h:59
void prepend(uint32_t n)
Definition: TypedIOBuf.h:105
uint8_t * writableTail()
Definition: IOBuf.h:526
uint8_t * writableBuffer()
Definition: IOBuf.h:572
uint32_t capacity() const
Definition: TypedIOBuf.h:96
const IOBuf * ioBuf() const
Definition: TypedIOBuf.h:55
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
const T * end() const
Definition: TypedIOBuf.h:136
void push(IT begin, IT end)
Definition: TypedIOBuf.h:191
value_type * iterator
Definition: TypedIOBuf.h:47
void push_back(const T &data)
Definition: TypedIOBuf.h:183
uint32_t length() const
Definition: TypedIOBuf.h:74
void prepend(std::size_t amount)
Definition: IOBuf.h:673
uint8_t * writableData()
Definition: IOBuf.h:509
std::size_t headroom() const
Definition: IOBuf.h:542
std::size_t length() const
Definition: IOBuf.h:533
void push(const T &data)
Definition: TypedIOBuf.h:180
const value_type * const_iterator
Definition: TypedIOBuf.h:48
void retreat(std::size_t amount)
Definition: IOBuf.h:653
static const char *const value
Definition: Conv.cpp:50
const T * data() const
Definition: TypedIOBuf.h:62
const value_type & const_reference
Definition: TypedIOBuf.h:45
const T * begin() const
Definition: TypedIOBuf.h:133
static uint32_t sdiv(uint32_t n)
Definition: TypedIOBuf.h:221
void trimStart(uint32_t n)
Definition: TypedIOBuf.h:111
void clear()
Definition: IOBuf.h:728
TypedIOBuf & operator=(TypedIOBuf &&)=default
T * writableBuffer()
Definition: TypedIOBuf.h:90
static const T * cast(const uint8_t *p)
Definition: TypedIOBuf.h:217
void trimStart(std::size_t amount)
Definition: IOBuf.h:703
const T & operator[](ssize_t idx) const
Definition: TypedIOBuf.h:167
TypedIOBuf(IOBuf *buf)
Definition: TypedIOBuf.h:50
const T & back() const
Definition: TypedIOBuf.h:154
const T * buffer() const
Definition: TypedIOBuf.h:87
void trimEnd(std::size_t amount)
Definition: IOBuf.h:718
const uint8_t * buffer() const
Definition: IOBuf.h:562
const T * tail() const
Definition: TypedIOBuf.h:68
void reserve(uint32_t minHeadroom, uint32_t minTailroom)
Definition: TypedIOBuf.h:120
void reserve(uint32_t minTailroom)
Definition: TypedIOBuf.h:123
const T * cend() const
Definition: TypedIOBuf.h:130
void advance(uint32_t n)
Definition: TypedIOBuf.h:99
void append(std::size_t amount)
Definition: IOBuf.h:689
uint32_t headroom() const
Definition: TypedIOBuf.h:81