From: Tudor Bosman Date: Tue, 5 Mar 2013 00:31:58 +0000 (-0800) Subject: Add resizing constructor to folly::padded::Adaptor X-Git-Tag: v0.22.0~1047 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f4cbf351c0943c93a98388461a2d00341b3e7ac5;p=folly.git 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 --- diff --git a/folly/Padded.h b/folly/Padded.h index f4d3b9c7..6de44a3b 100644 --- a/folly/Padded.h +++ b/folly/Padded.h @@ -343,6 +343,11 @@ 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) @@ -444,6 +449,7 @@ class Adaptor { assert(n >= 0); c_.reserve(Node::nodeCount(n)); } + size_type capacity() const { return c_.capacity() * Node::kElementCount; } @@ -475,12 +481,20 @@ 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: + 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 }; diff --git a/folly/test/PaddedTest.cpp b/folly/test/PaddedTest.cpp index f5fde484..32ef4762 100644 --- a/folly/test/PaddedTest.cpp +++ b/folly/test/PaddedTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012 Facebook, Inc. + * Copyright 2013 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,9 @@ #include using namespace folly; -namespace ps = ::folly::padded; TEST(NodeTest, Padding) { - typedef ps::Node IntNode; + typedef padded::Node IntNode; EXPECT_EQ(16, IntNode::kElementCount); EXPECT_EQ(0, IntNode::kPaddingBytes); EXPECT_EQ(alignof(int32_t), alignof(IntNode)); @@ -50,7 +49,7 @@ TEST(NodeTest, Padding) { char c[7]; }; EXPECT_EQ(1, alignof(SevenBytes)); - typedef ps::Node SevenByteNode; + typedef padded::Node SevenByteNode; EXPECT_EQ(9, SevenByteNode::kElementCount); // 64 / 7 EXPECT_EQ(1, SevenByteNode::kPaddingBytes); // 64 % 7 EXPECT_EQ(1, alignof(SevenByteNode)); @@ -77,7 +76,7 @@ TEST(NodeTest, Padding) { class IntPaddedTestBase : public ::testing::Test { protected: - typedef ps::Node IntNode; + typedef padded::Node IntNode; typedef std::vector IntNodeVec; IntNodeVec v_; int n_; @@ -98,16 +97,16 @@ class IntPaddedConstTest : public IntPaddedTestBase { TEST_F(IntPaddedConstTest, Iteration) { 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(n_, k); } 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 - auto it = ps::cbegin(v_); + auto it = padded::cbegin(v_); EXPECT_EQ(0, *it); { auto i2 = it; @@ -154,7 +153,7 @@ TEST_F(IntPaddedNonConstTest, Iteration) { n_ = 64; 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; } EXPECT_EQ(n_, k); @@ -174,7 +173,7 @@ class StructPaddedTestBase : public ::testing::Test { uint8_t y; uint8_t z; }; - typedef ps::Node PointNode; + typedef padded::Node PointNode; typedef std::vector PointNodeVec; PointNodeVec v_; int n_; @@ -198,7 +197,7 @@ class StructPaddedConstTest : public StructPaddedTestBase { TEST_F(StructPaddedConstTest, Iteration) { 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 + 1, it->y); EXPECT_EQ(k + 2, it->z); @@ -208,7 +207,7 @@ TEST_F(StructPaddedConstTest, Iteration) { class IntAdaptorTest : public IntPaddedConstTest { protected: - typedef ps::Adaptor IntAdaptor; + typedef padded::Adaptor IntAdaptor; IntAdaptor a_; }; @@ -232,3 +231,12 @@ TEST_F(IntAdaptorTest, Simple) { EXPECT_EQ(16, p.second); 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]); + } +} +