1 /* 2 * Copyright (c) 2022, Amazon.com Inc. or its affiliates. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include "precompiled.hpp" 25 #include "gc/shenandoah/shenandoahNumberSeq.hpp" 26 #include "utilities/ostream.hpp" 27 28 #include "utilities/vmassert_uninstall.hpp" 29 #include <iostream> 30 #include "utilities/vmassert_reinstall.hpp" 31 32 #include "unittest.hpp" 33 34 class ShenandoahNumberSeqTest: public ::testing::Test { 35 protected: 36 const double err = 0.5; 37 38 HdrSeq seq1; 39 HdrSeq seq2; 40 HdrSeq seq3; 41 42 void print() { 43 if (seq1.num() > 0) { 44 print(seq1, "seq1"); 45 } 46 if (seq2.num() > 0) { 47 print(seq2, "seq2"); 48 } 49 if (seq3.num() > 0) { 50 print(seq3, "seq3"); 51 } 52 } 53 54 void print(HdrSeq& seq, const char* msg) { 55 std::cout << "["; 56 for (int i = 0; i <= 100; i += 10) { 57 std::cout << "\t" << seq.percentile(i); 58 } 59 std::cout << " ] : " << msg << "\n"; 60 } 61 }; 62 63 class BasicShenandoahNumberSeqTest: public ShenandoahNumberSeqTest { 64 public: 65 BasicShenandoahNumberSeqTest() { 66 seq1.add(0); 67 seq1.add(1); 68 seq1.add(10); 69 for (int i = 0; i < 7; i++) { 70 seq1.add(100); 71 } 72 ShenandoahNumberSeqTest::print(); 73 } 74 }; 75 76 class ShenandoahNumberSeqMergeTest: public ShenandoahNumberSeqTest { 77 public: 78 ShenandoahNumberSeqMergeTest() { 79 for (int i = 0; i < 80; i++) { 80 seq1.add(1); 81 seq3.add(1); 82 } 83 84 for (int i = 0; i < 20; i++) { 85 seq2.add(100); 86 seq3.add(100); 87 } 88 ShenandoahNumberSeqTest::print(); 89 } 90 }; 91 92 TEST_VM_F(BasicShenandoahNumberSeqTest, maximum_test) { 93 EXPECT_EQ(seq1.maximum(), 100); 94 } 95 96 TEST_VM_F(BasicShenandoahNumberSeqTest, minimum_test) { 97 EXPECT_EQ(0, seq1.percentile(0)); 98 } 99 100 TEST_VM_F(BasicShenandoahNumberSeqTest, percentile_test) { 101 EXPECT_NEAR(0, seq1.percentile(10), err); 102 EXPECT_NEAR(1, seq1.percentile(20), err); 103 EXPECT_NEAR(10, seq1.percentile(30), err); 104 EXPECT_NEAR(100, seq1.percentile(40), err); 105 EXPECT_NEAR(100, seq1.percentile(50), err); 106 EXPECT_NEAR(100, seq1.percentile(75), err); 107 EXPECT_NEAR(100, seq1.percentile(90), err); 108 EXPECT_NEAR(100, seq1.percentile(100), err); 109 } 110 111 TEST_VM_F(ShenandoahNumberSeqMergeTest, merge_test) { 112 EXPECT_EQ(seq1.num(), 80); 113 EXPECT_EQ(seq2.num(), 20); 114 EXPECT_FALSE(isnan(seq2.davg())); // Exercise the path; not a nan 115 EXPECT_FALSE(isnan(seq2.dsd())); 116 EXPECT_FALSE(isnan(seq2.dvariance())); 117 118 std::cout << "Pre-merge: \n"; 119 print(); 120 seq1.merge(seq2); // clears seq1, after merging into seq2 121 std::cout << "Post-merge: \n"; 122 print(); 123 124 EXPECT_EQ(seq1.num(), 0); 125 EXPECT_EQ(seq2.num(), 100); 126 EXPECT_EQ(seq2.num(), seq3.num()); 127 EXPECT_TRUE(isnan(seq2.davg())); // until we fix decayed stats 128 EXPECT_TRUE(isnan(seq2.dvariance())); 129 130 EXPECT_EQ(seq2.maximum(), seq3.maximum()); 131 EXPECT_EQ(seq2.percentile(0), seq3.percentile(0)); 132 for (int i = 0; i <= 100; i += 10) { 133 EXPECT_NEAR(seq2.percentile(i), seq3.percentile(i), err); 134 } 135 EXPECT_NEAR(seq2.avg(), seq3.avg(), err); 136 EXPECT_NEAR(seq2.sd(), seq3.sd(), err); 137 }