LCOV - code coverage report
Current view: top level - src/test - prevector_tests.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 221 221 100.0 %
Date: 2026-06-25 07:23:43 Functions: 39 39 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2015-2020 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <prevector.h>
       6             : #include <serialize.h>
       7             : #include <streams.h>
       8             : 
       9             : #include <test/util/random.h>
      10             : #include <test/util/setup_common.h>
      11             : 
      12             : #include <boost/test/unit_test.hpp>
      13             : 
      14             : #include <ranges>
      15             : #include <vector>
      16             : 
      17         146 : BOOST_FIXTURE_TEST_SUITE(prevector_tests, TestingSetup)
      18             : 
      19             : template<unsigned int N, typename T>
      20             : class prevector_tester {
      21             :     typedef std::vector<T> realtype;
      22             :     realtype real_vector;
      23             :     realtype real_vector_alt;
      24             : 
      25             :     typedef prevector<N, T> pretype;
      26             :     pretype pre_vector;
      27             :     pretype pre_vector_alt;
      28             : 
      29             :     typedef typename pretype::size_type Size;
      30          64 :     bool passed = true;
      31             :     FastRandomContext rand_cache;
      32             :     uint256 rand_seed;
      33             : 
      34             : 
      35             :     template <typename A, typename B>
      36     9199360 :         void local_check_equal(A a, B b)
      37             :         {
      38     9199360 :             local_check(a == b);
      39     9199360 :         }
      40    25912448 :     void local_check(bool b)
      41             :     {
      42    25912448 :         passed &= b;
      43    25912448 :     }
      44      271552 :     void test() {
      45      271552 :         const pretype& const_pre_vector = pre_vector;
      46      271552 :         local_check_equal(real_vector.size(), pre_vector.size());
      47      271552 :         local_check_equal(real_vector.empty(), pre_vector.empty());
      48     2291776 :         for (Size s = 0; s < real_vector.size(); s++) {
      49     2020224 :              local_check(real_vector[s] == pre_vector[s]);
      50     2020224 :              local_check(&(pre_vector[s]) == &(pre_vector.begin()[s]));
      51     2020224 :              local_check(&(pre_vector[s]) == &*(pre_vector.begin() + s));
      52     2020224 :              local_check(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size()));
      53     2020224 :         }
      54             :         // local_check(realtype(pre_vector) == real_vector);
      55      271552 :         local_check(pretype(real_vector.begin(), real_vector.end()) == pre_vector);
      56      271552 :         local_check(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector);
      57      271552 :         size_t pos = 0;
      58     2291776 :         for (const T& v : pre_vector) {
      59     2020224 :              local_check(v == real_vector[pos++]);
      60             :         }
      61     2291776 :         for (const T& v : pre_vector | std::views::reverse) {
      62     2020224 :             local_check(v == real_vector[--pos]);
      63             :         }
      64     2291776 :         for (const T& v : const_pre_vector) {
      65     2020224 :              local_check(v == real_vector[pos++]);
      66             :         }
      67     2291776 :         for (const T& v : const_pre_vector | std::views::reverse) {
      68     2020224 :             local_check(v == real_vector[--pos]);
      69             :         }
      70      271552 :         CDataStream ss1(SER_DISK, 0);
      71      271552 :         CDataStream ss2(SER_DISK, 0);
      72      271552 :         ss1 << real_vector;
      73      271552 :         ss2 << pre_vector;
      74      271552 :         local_check_equal(ss1.size(), ss2.size());
      75     8624000 :         for (Size s = 0; s < ss1.size(); s++) {
      76     8352448 :             local_check_equal(ss1[s], ss2[s]);
      77     8352448 :         }
      78      271552 :     }
      79             : 
      80             : public:
      81       16128 :     void resize(Size s) {
      82       16128 :         real_vector.resize(s);
      83       16128 :         local_check_equal(real_vector.size(), s);
      84       16128 :         pre_vector.resize(s);
      85       16128 :         local_check_equal(pre_vector.size(), s);
      86       16128 :         test();
      87       16128 :     }
      88             : 
      89        4096 :     void reserve(Size s) {
      90        4096 :         real_vector.reserve(s);
      91        4096 :         local_check(real_vector.capacity() >= s);
      92        4096 :         pre_vector.reserve(s);
      93        4096 :         local_check(pre_vector.capacity() >= s);
      94        4096 :         test();
      95        4096 :     }
      96             : 
      97       32512 :     void insert(Size position, const T& value) {
      98       32512 :         real_vector.insert(real_vector.begin() + position, value);
      99       32512 :         pre_vector.insert(pre_vector.begin() + position, value);
     100       32512 :         test();
     101       32512 :     }
     102             : 
     103       15744 :     void insert(Size position, Size count, const T& value) {
     104       15744 :         real_vector.insert(real_vector.begin() + position, count, value);
     105       15744 :         pre_vector.insert(pre_vector.begin() + position, count, value);
     106       15744 :         test();
     107       15744 :     }
     108             : 
     109             :     template<typename I>
     110        4672 :     void insert_range(Size position, I first, I last) {
     111        4672 :         real_vector.insert(real_vector.begin() + position, first, last);
     112        4672 :         pre_vector.insert(pre_vector.begin() + position, first, last);
     113        4672 :         test();
     114        4672 :     }
     115             : 
     116       28608 :     void erase(Size position) {
     117       28608 :         real_vector.erase(real_vector.begin() + position);
     118       28608 :         pre_vector.erase(pre_vector.begin() + position);
     119       28608 :         test();
     120       28608 :     }
     121             : 
     122       20544 :     void erase(Size first, Size last) {
     123       20544 :         real_vector.erase(real_vector.begin() + first, real_vector.begin() + last);
     124       20544 :         pre_vector.erase(pre_vector.begin() + first, pre_vector.begin() + last);
     125       20544 :         test();
     126       20544 :     }
     127             : 
     128      111040 :     void update(Size pos, const T& value) {
     129      111040 :         real_vector[pos] = value;
     130      111040 :         pre_vector[pos] = value;
     131      111040 :         test();
     132      111040 :     }
     133             : 
     134        8192 :     void push_back(const T& value) {
     135        8192 :         real_vector.push_back(value);
     136        8192 :         pre_vector.push_back(value);
     137        8192 :         test();
     138        8192 :     }
     139             : 
     140        7872 :     void pop_back() {
     141        7872 :         real_vector.pop_back();
     142        7872 :         pre_vector.pop_back();
     143        7872 :         test();
     144        7872 :     }
     145             : 
     146         256 :     void clear() {
     147         256 :         real_vector.clear();
     148         256 :         pre_vector.clear();
     149         256 :     }
     150             : 
     151         576 :     void assign(Size n, const T& value) {
     152         576 :         real_vector.assign(n, value);
     153         576 :         pre_vector.assign(n, value);
     154         576 :     }
     155             : 
     156      643008 :     Size size() const {
     157      643008 :         return real_vector.size();
     158             :     }
     159             : 
     160             :     Size capacity() const {
     161             :         return pre_vector.capacity();
     162             :     }
     163             : 
     164        1728 :     void shrink_to_fit() {
     165        1728 :         pre_vector.shrink_to_fit();
     166        1728 :         test();
     167        1728 :     }
     168             : 
     169       16320 :     void swap() noexcept
     170             :     {
     171       16320 :         real_vector.swap(real_vector_alt);
     172       16320 :         pre_vector.swap(pre_vector_alt);
     173       16320 :         test();
     174       16320 :     }
     175             : 
     176        4288 :     void move() {
     177        4288 :         real_vector = std::move(real_vector_alt);
     178        4288 :         real_vector_alt.clear();
     179        4288 :         pre_vector = std::move(pre_vector_alt);
     180        4288 :         pre_vector_alt.clear();
     181        4288 :     }
     182             : 
     183        8832 :     void copy() {
     184        8832 :         real_vector = real_vector_alt;
     185        8832 :         pre_vector = pre_vector_alt;
     186        8832 :     }
     187             : 
     188        4096 :     void resize_uninitialized(realtype values) {
     189        4096 :         size_t r = values.size();
     190        4096 :         size_t s = real_vector.size() / 2;
     191        4096 :         if (real_vector.capacity() < s + r) {
     192        1600 :             real_vector.reserve(s + r);
     193        1600 :         }
     194        4096 :         real_vector.resize(s);
     195        4096 :         pre_vector.resize_uninitialized(s);
     196       38656 :         for (auto v : values) {
     197       34560 :             real_vector.push_back(v);
     198             :         }
     199        4096 :         auto p = pre_vector.size();
     200        4096 :         pre_vector.resize_uninitialized(p + r);
     201       38656 :         for (auto v : values) {
     202       34560 :             pre_vector[p] = v;
     203       34560 :             ++p;
     204             :         }
     205        4096 :         test();
     206        4096 :     }
     207             : 
     208         128 :     ~prevector_tester() {
     209          64 :         BOOST_CHECK_MESSAGE(passed, "insecure_rand: " + rand_seed.ToString());
     210         128 :     }
     211             : 
     212         128 :     prevector_tester() {
     213          64 :         SeedInsecureRand();
     214          64 :         rand_seed = InsecureRand256();
     215          64 :         rand_cache = FastRandomContext(rand_seed);
     216         128 :     }
     217             : };
     218             : 
     219         149 : BOOST_AUTO_TEST_CASE(PrevectorTestInt)
     220             : {
     221          65 :     for (int j = 0; j < 64; j++) {
     222          64 :         prevector_tester<8, int> test;
     223      131136 :         for (int i = 0; i < 2048; i++) {
     224      131072 :             if (InsecureRandBits(2) == 0) {
     225       32512 :                 test.insert(InsecureRandRange(test.size() + 1), int(InsecureRand32()));
     226       32512 :             }
     227      131072 :             if (test.size() > 0 && InsecureRandBits(2) == 1) {
     228       28608 :                 test.erase(InsecureRandRange(test.size()));
     229       28608 :             }
     230      131072 :             if (InsecureRandBits(3) == 2) {
     231       16128 :                 int new_size = std::max(0, std::min(30, (int)test.size() + (int)InsecureRandRange(5) - 2));
     232       16128 :                 test.resize(new_size);
     233       16128 :             }
     234      131072 :             if (InsecureRandBits(3) == 3) {
     235       15744 :                 test.insert(InsecureRandRange(test.size() + 1), 1 + InsecureRandBool(), int(InsecureRand32()));
     236       15744 :             }
     237      131072 :             if (InsecureRandBits(3) == 4) {
     238       16128 :                 int del = std::min<int>(test.size(), 1 + (InsecureRandBool()));
     239       16128 :                 int beg = InsecureRandRange(test.size() + 1 - del);
     240       16128 :                 test.erase(beg, beg + del);
     241       16128 :             }
     242      131072 :             if (InsecureRandBits(4) == 5) {
     243        8192 :                 test.push_back(int(InsecureRand32()));
     244        8192 :             }
     245      131072 :             if (test.size() > 0 && InsecureRandBits(4) == 6) {
     246        7872 :                 test.pop_back();
     247        7872 :             }
     248      131072 :             if (InsecureRandBits(5) == 7) {
     249             :                 int values[4];
     250        4672 :                 int num = 1 + (InsecureRandBits(2));
     251       16768 :                 for (int k = 0; k < num; k++) {
     252       12096 :                     values[k] = int(InsecureRand32());
     253       12096 :                 }
     254        4672 :                 test.insert_range(InsecureRandRange(test.size() + 1), values, values + num);
     255        4672 :             }
     256      131072 :             if (InsecureRandBits(5) == 8) {
     257        4416 :                 int del = std::min<int>(test.size(), 1 + (InsecureRandBits(2)));
     258        4416 :                 int beg = InsecureRandRange(test.size() + 1 - del);
     259        4416 :                 test.erase(beg, beg + del);
     260        4416 :             }
     261      131072 :             if (InsecureRandBits(5) == 9) {
     262        4096 :                 test.reserve(InsecureRandBits(5));
     263        4096 :             }
     264      131072 :             if (InsecureRandBits(6) == 10) {
     265        1728 :                 test.shrink_to_fit();
     266        1728 :             }
     267      131072 :             if (test.size() > 0) {
     268      111040 :                 test.update(InsecureRandRange(test.size()), int(InsecureRand32()));
     269      111040 :             }
     270      131072 :             if (InsecureRandBits(10) == 11) {
     271         256 :                 test.clear();
     272         256 :             }
     273      131072 :             if (InsecureRandBits(9) == 12) {
     274         576 :                 test.assign(InsecureRandBits(5), int(InsecureRand32()));
     275         576 :             }
     276      131072 :             if (InsecureRandBits(3) == 3) {
     277       16320 :                 test.swap();
     278       16320 :             }
     279      131072 :             if (InsecureRandBits(4) == 8) {
     280        8832 :                 test.copy();
     281        8832 :             }
     282      131072 :             if (InsecureRandBits(5) == 18) {
     283        4288 :                 test.move();
     284        4288 :             }
     285      131072 :             if (InsecureRandBits(5) == 19) {
     286        4096 :                 unsigned int num = 1 + (InsecureRandBits(4));
     287        4096 :                 std::vector<int> values(num);
     288       38656 :                 for (int& v : values) {
     289       34560 :                     v = int(InsecureRand32());
     290             :                 }
     291        4096 :                 test.resize_uninitialized(values);
     292        4096 :             }
     293      131072 :         }
     294          64 :     }
     295           1 : }
     296             : 
     297         146 : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.16