PaddedTest.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * Copyright 2012-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. #include <folly/Padded.h>
  17. #include <glog/logging.h>
  18. #include <folly/portability/GTest.h>
  19. using namespace folly;
  20. TEST(NodeTest, Padding) {
  21. typedef padded::Node<int32_t, 64> IntNode;
  22. EXPECT_EQ(16, IntNode::kElementCount);
  23. EXPECT_EQ(0, IntNode::kPaddingBytes);
  24. EXPECT_EQ(alignof(int32_t), alignof(IntNode));
  25. EXPECT_EQ(64, sizeof(IntNode));
  26. EXPECT_EQ(0, IntNode::nodeCount(0));
  27. EXPECT_EQ(0, IntNode::paddedByteSize(0));
  28. EXPECT_EQ(0, IntNode::unpaddedByteSize(0));
  29. EXPECT_EQ(1, IntNode::nodeCount(1));
  30. EXPECT_EQ(64, IntNode::paddedByteSize(1));
  31. EXPECT_EQ(4, IntNode::unpaddedByteSize(1));
  32. EXPECT_EQ(1, IntNode::nodeCount(16));
  33. EXPECT_EQ(64, IntNode::paddedByteSize(16));
  34. EXPECT_EQ(64, IntNode::unpaddedByteSize(16));
  35. EXPECT_EQ(2, IntNode::nodeCount(17));
  36. EXPECT_EQ(128, IntNode::paddedByteSize(17));
  37. EXPECT_EQ(68, IntNode::unpaddedByteSize(17));
  38. EXPECT_EQ(128, IntNode::paddedByteSize(32));
  39. EXPECT_EQ(128, IntNode::unpaddedByteSize(32));
  40. EXPECT_EQ(3, IntNode::nodeCount(33));
  41. EXPECT_EQ(192, IntNode::paddedByteSize(33));
  42. EXPECT_EQ(132, IntNode::unpaddedByteSize(33));
  43. struct SevenBytes {
  44. char c[7];
  45. };
  46. EXPECT_EQ(1, alignof(SevenBytes));
  47. typedef padded::Node<SevenBytes, 64> SevenByteNode;
  48. EXPECT_EQ(9, SevenByteNode::kElementCount); // 64 / 7
  49. EXPECT_EQ(1, SevenByteNode::kPaddingBytes); // 64 % 7
  50. EXPECT_EQ(1, alignof(SevenByteNode));
  51. EXPECT_EQ(64, sizeof(SevenByteNode));
  52. EXPECT_EQ(0, SevenByteNode::nodeCount(0));
  53. EXPECT_EQ(0, SevenByteNode::paddedByteSize(0));
  54. EXPECT_EQ(0, SevenByteNode::unpaddedByteSize(0));
  55. EXPECT_EQ(1, SevenByteNode::nodeCount(1));
  56. EXPECT_EQ(64, SevenByteNode::paddedByteSize(1));
  57. EXPECT_EQ(7, SevenByteNode::unpaddedByteSize(1));
  58. EXPECT_EQ(1, SevenByteNode::nodeCount(9));
  59. EXPECT_EQ(64, SevenByteNode::paddedByteSize(9));
  60. EXPECT_EQ(63, SevenByteNode::unpaddedByteSize(9));
  61. EXPECT_EQ(2, SevenByteNode::nodeCount(10));
  62. EXPECT_EQ(128, SevenByteNode::paddedByteSize(10));
  63. EXPECT_EQ(71, SevenByteNode::unpaddedByteSize(10));
  64. EXPECT_EQ(2, SevenByteNode::nodeCount(18));
  65. EXPECT_EQ(128, SevenByteNode::paddedByteSize(18));
  66. EXPECT_EQ(127, SevenByteNode::unpaddedByteSize(18));
  67. EXPECT_EQ(3, SevenByteNode::nodeCount(19));
  68. EXPECT_EQ(192, SevenByteNode::paddedByteSize(19));
  69. EXPECT_EQ(135, SevenByteNode::unpaddedByteSize(19));
  70. }
  71. class IntPaddedTestBase : public ::testing::Test {
  72. protected:
  73. typedef padded::Node<uint32_t, 64> IntNode;
  74. typedef std::vector<IntNode> IntNodeVec;
  75. IntNodeVec v_;
  76. int n_;
  77. };
  78. class IntPaddedConstTest : public IntPaddedTestBase {
  79. protected:
  80. void SetUp() override {
  81. v_.resize(4);
  82. n_ = 0;
  83. for (int i = 0; i < 4; i++) {
  84. for (size_t j = 0; j < IntNode::kElementCount; ++j, ++n_) {
  85. v_[i].data()[j] = n_;
  86. }
  87. }
  88. }
  89. };
  90. TEST_F(IntPaddedConstTest, Iteration) {
  91. int k = 0;
  92. for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
  93. EXPECT_EQ(k, *it);
  94. }
  95. EXPECT_EQ(n_, k);
  96. }
  97. TEST_F(IntPaddedConstTest, Arithmetic) {
  98. EXPECT_EQ(64, padded::cend(v_) - padded::cbegin(v_));
  99. // Play around block boundaries
  100. auto it = padded::cbegin(v_);
  101. EXPECT_EQ(0, *it);
  102. {
  103. auto i2 = it;
  104. EXPECT_EQ(0, i2 - it);
  105. i2 += 1;
  106. EXPECT_EQ(1, *i2);
  107. EXPECT_EQ(1, i2 - it);
  108. EXPECT_EQ(-1, it - i2);
  109. }
  110. it += 15;
  111. EXPECT_EQ(15, *it);
  112. {
  113. auto i2 = it;
  114. i2 += 1;
  115. EXPECT_EQ(16, *i2);
  116. EXPECT_EQ(1, i2 - it);
  117. EXPECT_EQ(-1, it - i2);
  118. }
  119. ++it;
  120. EXPECT_EQ(16, *it);
  121. {
  122. auto i2 = it;
  123. i2 -= 1;
  124. EXPECT_EQ(15, *i2);
  125. EXPECT_EQ(-1, i2 - it);
  126. EXPECT_EQ(1, it - i2);
  127. }
  128. --it;
  129. EXPECT_EQ(15, *it);
  130. {
  131. auto i2 = it;
  132. i2 -= 1;
  133. EXPECT_EQ(14, *i2);
  134. EXPECT_EQ(-1, i2 - it);
  135. EXPECT_EQ(1, it - i2);
  136. }
  137. }
  138. class IntPaddedNonConstTest : public IntPaddedTestBase {};
  139. TEST_F(IntPaddedNonConstTest, Iteration) {
  140. v_.resize(4);
  141. n_ = 64;
  142. int k = 0;
  143. for (auto it = padded::begin(v_); it != padded::end(v_); ++it, ++k) {
  144. *it = k;
  145. }
  146. EXPECT_EQ(n_, k);
  147. k = 0;
  148. for (int i = 0; i < 4; i++) {
  149. for (size_t j = 0; j < IntNode::kElementCount; ++j, ++k) {
  150. EXPECT_EQ(k, v_[i].data()[j]);
  151. }
  152. }
  153. }
  154. class StructPaddedTestBase : public ::testing::Test {
  155. protected:
  156. struct Point {
  157. uint8_t x;
  158. uint8_t y;
  159. uint8_t z;
  160. };
  161. typedef padded::Node<Point, 64> PointNode;
  162. typedef std::vector<PointNode> PointNodeVec;
  163. PointNodeVec v_;
  164. int n_;
  165. };
  166. class StructPaddedConstTest : public StructPaddedTestBase {
  167. protected:
  168. void SetUp() override {
  169. v_.resize(4);
  170. n_ = 0;
  171. for (int i = 0; i < 4; i++) {
  172. for (size_t j = 0; j < PointNode::kElementCount; ++j, ++n_) {
  173. auto& point = v_[i].data()[j];
  174. point.x = n_;
  175. point.y = n_ + 1;
  176. point.z = n_ + 2;
  177. }
  178. }
  179. }
  180. };
  181. TEST_F(StructPaddedConstTest, Iteration) {
  182. int k = 0;
  183. for (auto it = padded::cbegin(v_); it != padded::cend(v_); ++it, ++k) {
  184. EXPECT_EQ(k, it->x);
  185. EXPECT_EQ(k + 1, it->y);
  186. EXPECT_EQ(k + 2, it->z);
  187. }
  188. EXPECT_EQ(n_, k);
  189. }
  190. class IntAdaptorTest : public IntPaddedConstTest {
  191. protected:
  192. typedef padded::Adaptor<IntNodeVec> IntAdaptor;
  193. IntAdaptor a_;
  194. };
  195. TEST_F(IntAdaptorTest, Simple) {
  196. for (int i = 0; i < n_; ++i) {
  197. EXPECT_EQ((i == 0), a_.empty());
  198. EXPECT_EQ(i, a_.size());
  199. a_.push_back(i);
  200. }
  201. EXPECT_EQ(n_, a_.size());
  202. int k = 0;
  203. for (auto it = a_.begin(); it != a_.end(); ++it, ++k) {
  204. EXPECT_EQ(k, a_[k]);
  205. EXPECT_EQ(k, *it);
  206. }
  207. EXPECT_EQ(n_, k);
  208. auto p = a_.move();
  209. EXPECT_TRUE(a_.empty());
  210. EXPECT_EQ(16, p.second);
  211. EXPECT_TRUE(v_ == p.first);
  212. }
  213. TEST_F(IntAdaptorTest, ResizeConstructor) {
  214. IntAdaptor a(n_, 42);
  215. EXPECT_EQ(n_, a.size());
  216. for (int i = 0; i < n_; ++i) {
  217. EXPECT_EQ(42, a[i]);
  218. }
  219. }
  220. TEST_F(IntAdaptorTest, SimpleEmplaceBack) {
  221. for (int i = 0; i < n_; ++i) {
  222. EXPECT_EQ((i == 0), a_.empty());
  223. EXPECT_EQ(i, a_.size());
  224. a_.emplace_back(i);
  225. }
  226. EXPECT_EQ(n_, a_.size());
  227. int k = 0;
  228. for (auto it = a_.begin(); it != a_.end(); ++it, ++k) {
  229. EXPECT_EQ(k, a_[k]);
  230. EXPECT_EQ(k, *it);
  231. }
  232. EXPECT_EQ(n_, k);
  233. auto p = a_.move();
  234. EXPECT_TRUE(a_.empty());
  235. EXPECT_EQ(16, p.second);
  236. EXPECT_TRUE(v_ == p.first);
  237. }