Commit f4cbf351 authored by Tudor Bosman's avatar Tudor Bosman Committed by Jordan DeLong

Add resizing constructor to folly::padded::Adaptor

Summary: Added Adaptor(size_t, const value_type&)

Test Plan: test added

Reviewed By: soren@fb.com

FB internal diff: D726358
parent 218b5231
...@@ -343,6 +343,11 @@ class Adaptor { ...@@ -343,6 +343,11 @@ class Adaptor {
: c_(std::move(c)), : c_(std::move(c)),
lastCount_(lastCount) { 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(const Adaptor&) = default;
Adaptor& operator=(const Adaptor&) = default; Adaptor& operator=(const Adaptor&) = default;
Adaptor(Adaptor&& other) Adaptor(Adaptor&& other)
...@@ -444,6 +449,7 @@ class Adaptor { ...@@ -444,6 +449,7 @@ class Adaptor {
assert(n >= 0); assert(n >= 0);
c_.reserve(Node::nodeCount(n)); c_.reserve(Node::nodeCount(n));
} }
size_type capacity() const { size_type capacity() const {
return c_.capacity() * Node::kElementCount; return c_.capacity() * Node::kElementCount;
} }
...@@ -475,12 +481,20 @@ class Adaptor { ...@@ -475,12 +481,20 @@ class Adaptor {
} }
void padToFullNode(const value_type& padValue) { void padToFullNode(const value_type& padValue) {
while (lastCount_ != Node::kElementCount) { // the if is necessary because c_ may be empty so we can't call c_.back()
push_back(padValue); if (lastCount_ != Node::kElementCount) {
auto last = c_.back().data();
std::fill(last + lastCount_, last + Node::kElementCount, padValue);
lastCount_ = Node::kElementCount;
} }
} }
private: private:
static Node fullNode(const value_type& value) {
Node n;
std::fill(n.data(), n.data() + kElementsPerNode, value);
return n;
}
Container c_; // container of Nodes Container c_; // container of Nodes
size_t lastCount_; // number of elements in last Node size_t lastCount_; // number of elements in last Node
}; };
......
/* /*
* Copyright 2012 Facebook, Inc. * Copyright 2013 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -20,10 +20,9 @@ ...@@ -20,10 +20,9 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
using namespace folly; using namespace folly;
namespace ps = ::folly::padded;
TEST(NodeTest, Padding) { TEST(NodeTest, Padding) {
typedef ps::Node<int32_t, 64> IntNode; typedef padded::Node<int32_t, 64> IntNode;
EXPECT_EQ(16, IntNode::kElementCount); EXPECT_EQ(16, IntNode::kElementCount);
EXPECT_EQ(0, IntNode::kPaddingBytes); EXPECT_EQ(0, IntNode::kPaddingBytes);
EXPECT_EQ(alignof(int32_t), alignof(IntNode)); EXPECT_EQ(alignof(int32_t), alignof(IntNode));
...@@ -50,7 +49,7 @@ TEST(NodeTest, Padding) { ...@@ -50,7 +49,7 @@ TEST(NodeTest, Padding) {
char c[7]; char c[7];
}; };
EXPECT_EQ(1, alignof(SevenBytes)); EXPECT_EQ(1, alignof(SevenBytes));
typedef ps::Node<SevenBytes, 64> SevenByteNode; typedef padded::Node<SevenBytes, 64> SevenByteNode;
EXPECT_EQ(9, SevenByteNode::kElementCount); // 64 / 7 EXPECT_EQ(9, SevenByteNode::kElementCount); // 64 / 7
EXPECT_EQ(1, SevenByteNode::kPaddingBytes); // 64 % 7 EXPECT_EQ(1, SevenByteNode::kPaddingBytes); // 64 % 7
EXPECT_EQ(1, alignof(SevenByteNode)); EXPECT_EQ(1, alignof(SevenByteNode));
...@@ -77,7 +76,7 @@ TEST(NodeTest, Padding) { ...@@ -77,7 +76,7 @@ TEST(NodeTest, Padding) {
class IntPaddedTestBase : public ::testing::Test { class IntPaddedTestBase : public ::testing::Test {
protected: protected:
typedef ps::Node<uint32_t, 64> IntNode; typedef padded::Node<uint32_t, 64> IntNode;
typedef std::vector<IntNode> IntNodeVec; typedef std::vector<IntNode> IntNodeVec;
IntNodeVec v_; IntNodeVec v_;
int n_; int n_;
...@@ -98,16 +97,16 @@ class IntPaddedConstTest : public IntPaddedTestBase { ...@@ -98,16 +97,16 @@ class IntPaddedConstTest : public IntPaddedTestBase {
TEST_F(IntPaddedConstTest, Iteration) { TEST_F(IntPaddedConstTest, Iteration) {
int k = 0; int k = 0;
for (auto it = ps::cbegin(v_); it != ps::cend(v_); ++it, ++k) { for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
EXPECT_EQ(k, *it); EXPECT_EQ(k, *it);
} }
EXPECT_EQ(n_, k); EXPECT_EQ(n_, k);
} }
TEST_F(IntPaddedConstTest, Arithmetic) { TEST_F(IntPaddedConstTest, Arithmetic) {
EXPECT_EQ(64, ps::cend(v_) - ps::cbegin(v_)); EXPECT_EQ(64, padded::cend(v_) - padded::cbegin(v_));
// Play around block boundaries // Play around block boundaries
auto it = ps::cbegin(v_); auto it = padded::cbegin(v_);
EXPECT_EQ(0, *it); EXPECT_EQ(0, *it);
{ {
auto i2 = it; auto i2 = it;
...@@ -154,7 +153,7 @@ TEST_F(IntPaddedNonConstTest, Iteration) { ...@@ -154,7 +153,7 @@ TEST_F(IntPaddedNonConstTest, Iteration) {
n_ = 64; n_ = 64;
int k = 0; int k = 0;
for (auto it = ps::begin(v_); it != ps::end(v_); ++it, ++k) { for (auto it = padded::begin(v_); it != padded::end(v_); ++it, ++k) {
*it = k; *it = k;
} }
EXPECT_EQ(n_, k); EXPECT_EQ(n_, k);
...@@ -174,7 +173,7 @@ class StructPaddedTestBase : public ::testing::Test { ...@@ -174,7 +173,7 @@ class StructPaddedTestBase : public ::testing::Test {
uint8_t y; uint8_t y;
uint8_t z; uint8_t z;
}; };
typedef ps::Node<Point, 64> PointNode; typedef padded::Node<Point, 64> PointNode;
typedef std::vector<PointNode> PointNodeVec; typedef std::vector<PointNode> PointNodeVec;
PointNodeVec v_; PointNodeVec v_;
int n_; int n_;
...@@ -198,7 +197,7 @@ class StructPaddedConstTest : public StructPaddedTestBase { ...@@ -198,7 +197,7 @@ class StructPaddedConstTest : public StructPaddedTestBase {
TEST_F(StructPaddedConstTest, Iteration) { TEST_F(StructPaddedConstTest, Iteration) {
int k = 0; int k = 0;
for (auto it = ps::cbegin(v_); it != ps::cend(v_); ++it, ++k) { for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
EXPECT_EQ(k, it->x); EXPECT_EQ(k, it->x);
EXPECT_EQ(k + 1, it->y); EXPECT_EQ(k + 1, it->y);
EXPECT_EQ(k + 2, it->z); EXPECT_EQ(k + 2, it->z);
...@@ -208,7 +207,7 @@ TEST_F(StructPaddedConstTest, Iteration) { ...@@ -208,7 +207,7 @@ TEST_F(StructPaddedConstTest, Iteration) {
class IntAdaptorTest : public IntPaddedConstTest { class IntAdaptorTest : public IntPaddedConstTest {
protected: protected:
typedef ps::Adaptor<IntNodeVec> IntAdaptor; typedef padded::Adaptor<IntNodeVec> IntAdaptor;
IntAdaptor a_; IntAdaptor a_;
}; };
...@@ -232,3 +231,12 @@ TEST_F(IntAdaptorTest, Simple) { ...@@ -232,3 +231,12 @@ TEST_F(IntAdaptorTest, Simple) {
EXPECT_EQ(16, p.second); EXPECT_EQ(16, p.second);
EXPECT_TRUE(v_ == p.first); EXPECT_TRUE(v_ == p.first);
} }
TEST_F(IntAdaptorTest, ResizeConstructor) {
IntAdaptor a(n_, 42);
EXPECT_EQ(n_, a.size());
for (int i = 0; i < n_; ++i) {
EXPECT_EQ(42, a[i]);
}
}
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