From 13d21020715ec6ec3ee4bdc1a8217739db1bed7e Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Tue, 6 Sep 2016 16:19:25 -0400 Subject: [PATCH 1/3] Minimal fix to slow prevector tests as stopgap measure --- src/test/prevector_tests.cpp | 56 +++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index 525c1b87f7a3..77fc7ef4d6ce 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -26,53 +26,66 @@ class prevector_tester { pretype pre_vector_alt; typedef typename pretype::size_type Size; + bool passed = true; + FastRandomContext rand_cache; + uint256 rand_seed; + template + void local_check_equal(A a, B b) + { + local_check(a == b); + } + void local_check(bool b) + { + passed &= b; + } void test() { const pretype& const_pre_vector = pre_vector; - BOOST_CHECK_EQUAL(real_vector.size(), pre_vector.size()); - BOOST_CHECK_EQUAL(real_vector.empty(), pre_vector.empty()); + local_check_equal(real_vector.size(), pre_vector.size()); + local_check_equal(real_vector.empty(), pre_vector.empty()); for (Size s = 0; s < real_vector.size(); s++) { - BOOST_CHECK(real_vector[s] == pre_vector[s]); - BOOST_CHECK(&(pre_vector[s]) == &(pre_vector.begin()[s])); - BOOST_CHECK(&(pre_vector[s]) == &*(pre_vector.begin() + s)); - BOOST_CHECK(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size())); + local_check(real_vector[s] == pre_vector[s]); + local_check(&(pre_vector[s]) == &(pre_vector.begin()[s])); + local_check(&(pre_vector[s]) == &*(pre_vector.begin() + s)); + local_check(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size())); } - // BOOST_CHECK(realtype(pre_vector) == real_vector); - BOOST_CHECK(pretype(real_vector.begin(), real_vector.end()) == pre_vector); - BOOST_CHECK(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector); + // local_check(realtype(pre_vector) == real_vector); + local_check(pretype(real_vector.begin(), real_vector.end()) == pre_vector); + local_check(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector); size_t pos = 0; + for (const T& v : pre_vector) { - BOOST_CHECK(v == real_vector[pos++]); + local_check(v == real_vector[pos++]); } pos = 0; for (const T& v : const_pre_vector) { - BOOST_CHECK(v == real_vector[pos++]); + local_check(v == real_vector[pos++]); } CDataStream ss1(SER_DISK, 0); CDataStream ss2(SER_DISK, 0); ss1 << real_vector; ss2 << pre_vector; - BOOST_CHECK_EQUAL(ss1.size(), ss2.size()); + local_check_equal(ss1.size(), ss2.size()); for (Size s = 0; s < ss1.size(); s++) { - BOOST_CHECK_EQUAL(ss1[s], ss2[s]); + local_check_equal(ss1[s], ss2[s]); } } public: void resize(Size s) { real_vector.resize(s); - BOOST_CHECK_EQUAL(real_vector.size(), s); + local_check_equal(real_vector.size(), s); pre_vector.resize(s); - BOOST_CHECK_EQUAL(pre_vector.size(), s); + local_check_equal(pre_vector.size(), s); test(); } void reserve(Size s) { real_vector.reserve(s); - BOOST_CHECK(real_vector.capacity() >= s); + local_check(real_vector.capacity() >= s); pre_vector.reserve(s); - BOOST_CHECK(pre_vector.capacity() >= s); + local_check(pre_vector.capacity() >= s); test(); } @@ -165,6 +178,15 @@ class prevector_tester { real_vector = real_vector_alt; pre_vector = pre_vector_alt; } + + ~prevector_tester() { + BOOST_CHECK_MESSAGE(passed, "insecure_rand: " + rand_seed.ToString()); + } + prevector_tester() { + SeedInsecureRand(); + rand_seed = InsecureRand256(); + rand_cache = FastRandomContext(rand_seed); + } }; BOOST_AUTO_TEST_CASE(PrevectorTestInt) From b389b3fd340e7c4a59de605ea3563f7e73215c53 Mon Sep 17 00:00:00 2001 From: Akio Nakamura Date: Thu, 1 Feb 2018 19:34:50 +0900 Subject: [PATCH 2/3] speed up Unserialize_impl for prevector The unserializer for prevector uses resize() for reserve the area, but it's prefer to use reserve() because resize() have overhead to call its constructor many times. However, reserve() does not change the value of "_size" (a private member of prevector). This PR introduce resize_uninitialized() to prevector that similar to resize() but does not call constructor, and added elements are explicitly initialized in Unserialize_imple(). The changes are as follows: 1. prevector.h Add a public member function named 'resize_uninitialized'. This function processes like as resize() but does not call constructors. So added elemensts needs explicitly initialized after this returns. 2. serialize.h In the following two function: Unserialize_impl(Stream& is, prevector& v, const unsigned char&) Unserialize_impl(Stream& is, prevector& v, const V&) Calls resize_uninitialized() instead of resize() 3. test/prevector_tests.cpp Add a test for resize_uninitialized(). --- src/prevector.h | 15 +++++++++++++++ src/serialize.h | 6 +++--- src/test/prevector_tests.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/prevector.h b/src/prevector.h index f3294870b46f..d73e67806974 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -381,6 +381,21 @@ class prevector { } } + inline void resize_uninitialized(size_type new_size) { + // resize_uninitialized changes the size of the prevector but does not initialize it. + // If size < new_size, the added elements must be initialized explicitly. + if (capacity() < new_size) { + change_capacity(new_size); + _size += new_size - size(); + return; + } + if (new_size < size()) { + erase(item_ptr(new_size), end()); + } else { + _size += new_size - size(); + } + } + iterator erase(iterator pos) { return erase(pos, pos + 1); } diff --git a/src/serialize.h b/src/serialize.h index 46b72ee583f0..333586d66a3c 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -803,7 +803,7 @@ void Unserialize_impl(Stream& is, prevector& v, const unsigned char&) while (i < nSize) { unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); - v.resize(i + blk); + v.resize_uninitialized(i + blk); is.read((char*)&v[i], blk * sizeof(T)); i += blk; } @@ -821,8 +821,8 @@ void Unserialize_impl(Stream& is, prevector& v, const V&) nMid += 5000000 / sizeof(T); if (nMid > nSize) nMid = nSize; - v.resize(nMid); - for (; i < nMid; i++) + v.resize_uninitialized(nMid); + for (; i < nMid; ++i) Unserialize(is, v[i]); } } diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index 77fc7ef4d6ce..57ea3db45694 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -179,6 +179,26 @@ class prevector_tester { pre_vector = pre_vector_alt; } + void resize_uninitialized(realtype values) { + size_t r = values.size(); + size_t s = real_vector.size() / 2; + if (real_vector.capacity() < s + r) { + real_vector.reserve(s + r); + } + real_vector.resize(s); + pre_vector.resize_uninitialized(s); + for (auto v : values) { + real_vector.push_back(v); + } + auto p = pre_vector.size(); + pre_vector.resize_uninitialized(p + r); + for (auto v : values) { + pre_vector[p] = v; + ++p; + } + test(); + } + ~prevector_tester() { BOOST_CHECK_MESSAGE(passed, "insecure_rand: " + rand_seed.ToString()); } @@ -257,6 +277,14 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt) if (((r >> 15) % 32) == 18) { test.move(); } + if (InsecureRandBits(5) == 19) { + unsigned int num = 1 + (InsecureRandBits(4)); + std::vector values(num); + for (auto &v : values) { + v = InsecureRand32(); + } + test.resize_uninitialized(values); + } } } } From b886a4c9c7045db4983b071568c9ad1ebe91344c Mon Sep 17 00:00:00 2001 From: Dan Raviv Date: Sat, 26 Aug 2017 02:56:53 +0300 Subject: [PATCH 3/3] Fix header guards using reserved identifiers Identifiers beginning with an underscore followed immediately by an uppercase letter are reserved. --- src/cuckoocache.h | 6 +++--- src/prevector.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cuckoocache.h b/src/cuckoocache.h index efd6a820b5ce..20c0193856ca 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -2,8 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef _BITCOIN_CUCKOOCACHE_H_ -#define _BITCOIN_CUCKOOCACHE_H_ +#ifndef BITCOIN_CUCKOOCACHE_H +#define BITCOIN_CUCKOOCACHE_H #include #include @@ -454,4 +454,4 @@ class cache }; } // namespace CuckooCache -#endif +#endif // BITCOIN_CUCKOOCACHE_H diff --git a/src/prevector.h b/src/prevector.h index d73e67806974..386a1781a27d 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -2,8 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef _BITCOIN_PREVECTOR_H_ -#define _BITCOIN_PREVECTOR_H_ +#ifndef BITCOIN_PREVECTOR_H +#define BITCOIN_PREVECTOR_H #include #include @@ -528,4 +528,4 @@ class prevector { }; #pragma pack(pop) -#endif +#endif // BITCOIN_PREVECTOR_H