libmoost
|
00001 /* vim:set ts=3 sw=3 sts=3 et: */ 00028 #include <boost/test/unit_test.hpp> 00029 #include <boost/test/test_tools.hpp> 00030 00031 #include <vector> 00032 00033 #include "../../include/moost/algorithm/ketama_partitioner.hpp" 00034 00035 using namespace moost::algorithm; 00036 00037 BOOST_AUTO_TEST_SUITE( ketama_partitioner_test ) 00038 00039 BOOST_AUTO_TEST_CASE( test_ketama ) 00040 { 00041 int from = 9; 00042 int to = 10; 00043 00044 ketama_partitioner<int> old_kp(from, 4096); 00045 ketama_partitioner<int> new_kp(to, 4096); 00046 00047 std::vector<int> bucket_counts(new_kp.num_buckets()); 00048 00049 for (int i = 0; i != 5000000; ++i) 00050 { 00051 int old_bucket = old_kp.partition(i); 00052 int new_bucket = new_kp.partition(i); 00053 ++bucket_counts[new_bucket]; 00054 BOOST_REQUIRE(old_bucket == new_bucket || new_bucket == to - 1); 00055 } 00056 00057 // make sure none deviate more than 5% from the average 00058 int average_min = (5000000 / to) * 0.95F; 00059 int average_max = (5000000 / to) * 1.05F; 00060 for (size_t i = 0; i != bucket_counts.size(); ++i) 00061 { 00062 BOOST_CHECK_PREDICATE( std::greater<int>(), (bucket_counts[i]) (average_min) ); 00063 BOOST_CHECK_PREDICATE( std::less<int>(), (bucket_counts[i]) (average_max) ); 00064 } 00065 } 00066 00067 BOOST_AUTO_TEST_CASE( test_bucket_Y_ketama ) 00068 { 00069 std::vector<int> from; 00070 from.push_back(1); 00071 from.push_back(2); 00072 from.push_back(3); 00073 00074 std::vector<int> to; 00075 to.push_back(1); 00076 to.push_back(2); 00077 to.push_back(3); 00078 to.push_back(4); 00079 00080 ketama_partitioner<int> old_kp(from, 4096); 00081 ketama_partitioner<int> new_kp(to, 4096); 00082 00083 std::vector<int> bucket_counts(new_kp.num_buckets()); 00084 00085 for (int i = 0; i != 5000000; ++i) 00086 { 00087 int old_bucket = old_kp.partition(i); 00088 int new_bucket = new_kp.partition(i); 00089 ++bucket_counts[new_bucket]; 00090 BOOST_REQUIRE(old_bucket == new_bucket || new_bucket == 3); // 3 is the index of the new server 00091 } 00092 00093 // make sure none deviate more than 5% from the average 00094 int average_min = (5000000 / to.size() ) * 0.95F; 00095 int average_max = (5000000 / to.size() ) * 1.05F; 00096 for (size_t i = 0; i != bucket_counts.size(); ++i) 00097 { 00098 BOOST_CHECK_PREDICATE( std::greater<int>(), (bucket_counts[i]) (average_min) ); 00099 BOOST_CHECK_PREDICATE( std::less<int>(), (bucket_counts[i]) (average_max) ); 00100 } 00101 } 00102 00103 BOOST_AUTO_TEST_CASE( test_bucket_string_ketama ) 00104 { 00105 std::vector<std::string> from; 00106 from.push_back("10.0.1.101:11211"); 00107 from.push_back("10.0.1.102:11211"); 00108 from.push_back("10.0.1.103:11211"); 00109 00110 std::vector<std::string> to; 00111 to.push_back("10.0.1.101:11211"); 00112 to.push_back("10.0.1.102:11211"); 00113 to.push_back("10.0.1.103:11211"); 00114 to.push_back("10.0.1.104:11211"); 00115 00116 ketama_partitioner<int> old_kp(from, 4096); 00117 ketama_partitioner<int> new_kp(to, 4096); 00118 00119 std::vector<int> bucket_counts(new_kp.num_buckets()); 00120 00121 const std::string new_guy = "10.0.1.104:11211"; 00122 for (int i = 0; i != 5000000; ++i) 00123 { 00124 int old_bucket = old_kp.partition(i); 00125 int new_bucket = new_kp.partition(i); 00126 ++bucket_counts[new_bucket]; 00127 BOOST_REQUIRE(old_bucket == new_bucket || new_bucket == 3); // 3 is the index of the new server 00128 } 00129 00130 // make sure none deviate more than 5% from the average 00131 int average_min = (5000000 / to.size()) * 0.95F; 00132 int average_max = (5000000 / to.size()) * 1.05F; 00133 for (size_t i = 0; i != bucket_counts.size(); ++i) 00134 { 00135 BOOST_CHECK_PREDICATE( std::greater<int>(), (bucket_counts[i]) (average_min) ); 00136 BOOST_CHECK_PREDICATE( std::less<int>(), (bucket_counts[i]) (average_max) ); 00137 } 00138 } 00139 00140 BOOST_AUTO_TEST_SUITE_END()