allow AsyncSignalHandler to attach and detach from an EventBase
[folly.git] / folly / io / TypedIOBuf.h
index 3e8d2297cb8e9551e298be6680f90f3e0d716887..9358cd4dfa61b34d1749339ca05fc487eba23f33 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 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.
  * limitations under the License.
  */
 
-#ifndef FOLLY_IO_TYPEDIOBUF_H_
-#define FOLLY_IO_TYPEDIOBUF_H_
+#pragma once
 
 #include <algorithm>
 #include <iterator>
 #include <type_traits>
-#include "folly/io/IOBuf.h"
+
+#include <folly/Malloc.h>
+#include <folly/io/IOBuf.h>
 
 namespace folly {
 
@@ -151,6 +152,11 @@ class TypedIOBuf {
     return data()[idx];
   }
 
+  T& operator[](ssize_t idx) {
+    assert(idx >= 0 && idx < length());
+    return writableData()[idx];
+  }
+
   /**
    * Append one element.
    */
@@ -164,8 +170,14 @@ class TypedIOBuf {
    */
   template <class IT>
   void push(IT begin, IT end) {
-    auto n = std::distance(begin, end);
-    reserve(headroom(), n);
+    uint32_t n = std::distance(begin, end);
+    if (usingJEMalloc()) {
+      // Rely on xallocx() and avoid exponential growth to limit
+      // amount of memory wasted.
+      reserve(headroom(), n);
+    } else if (tailroom() < n) {
+      reserve(headroom(), std::max(n, 3 + size() / 2));
+    }
     std::copy(begin, end, writableTail());
     append(n);
   }
@@ -201,6 +213,3 @@ class TypedIOBuf {
 };
 
 }  // namespace folly
-
-#endif /* FOLLY_IO_TYPEDIOBUF_H_ */
-