X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FPadded.h;h=94fc1103b43026e5b8ec256ff2f714c209d5f492;hb=b1eb6819f3ffe6b645f39d505ca8ace3116b7873;hp=f4d3b9c7af57d72deb2f644d015bf2e4fbb61ccf;hpb=86d219c38847965714df9eba03b07fa2f6e30ecc;p=folly.git diff --git a/folly/Padded.h b/folly/Padded.h index f4d3b9c7..94fc1103 100644 --- a/folly/Padded.h +++ b/folly/Padded.h @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2016 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ #ifndef FOLLY_PADDED_H_ #define FOLLY_PADDED_H_ +#include #include #include #include @@ -27,7 +28,8 @@ #include -#include "folly/Portability.h" +#include +#include /** * Code that aids in storing data aligned on block (possibly cache-line) @@ -343,9 +345,14 @@ class Adaptor { : c_(std::move(c)), lastCount_(lastCount) { } + explicit Adaptor(size_t n, const value_type& value = value_type()) + : c_(Node::nodeCount(n), fullNode(value)), + lastCount_(n % Node::kElementCount ?: Node::kElementCount) { + } + Adaptor(const Adaptor&) = default; Adaptor& operator=(const Adaptor&) = default; - Adaptor(Adaptor&& other) + Adaptor(Adaptor&& other) noexcept : c_(std::move(other.c_)), lastCount_(other.lastCount_) { other.lastCount_ = Node::kElementCount; @@ -419,12 +426,13 @@ class Adaptor { return c_.back().data()[lastCount_ - 1]; } + template + void emplace_back(Args&&... args) { + new (allocate_back()) value_type(std::forward(args)...); + } + void push_back(value_type x) { - if (lastCount_ == Node::kElementCount) { - c_.push_back(Node()); - lastCount_ = 0; - } - c_.back().data()[lastCount_++] = std::move(x); + emplace_back(std::move(x)); } void pop_back() { @@ -444,6 +452,7 @@ class Adaptor { assert(n >= 0); c_.reserve(Node::nodeCount(n)); } + size_type capacity() const { return c_.capacity() * Node::kElementCount; } @@ -475,12 +484,28 @@ class Adaptor { } void padToFullNode(const value_type& padValue) { - while (lastCount_ != Node::kElementCount) { - push_back(padValue); + // the if is necessary because c_ may be empty so we can't call c_.back() + if (lastCount_ != Node::kElementCount) { + auto last = c_.back().data(); + std::fill(last + lastCount_, last + Node::kElementCount, padValue); + lastCount_ = Node::kElementCount; } } private: + value_type* allocate_back() { + if (lastCount_ == Node::kElementCount) { + container_emplace_back_or_push_back(c_); + lastCount_ = 0; + } + return &c_.back().data()[lastCount_++]; + } + + static Node fullNode(const value_type& value) { + Node n; + std::fill(n.data(), n.data() + kElementsPerNode, value); + return n; + } Container c_; // container of Nodes size_t lastCount_; // number of elements in last Node }; @@ -489,4 +514,3 @@ class Adaptor { } // namespace folly #endif /* FOLLY_PADDED_H_ */ -