Browse Source

Add random number generator implementation and unit test

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac356@3639 e5f2f494-b856-4b98-b285-d166d9295462
Haidong Wang 14 years ago
parent
commit
9282b638e6

+ 6 - 1
src/lib/nsas/nameserver_entry.cc

@@ -40,13 +40,18 @@ using namespace std;
 namespace isc {
 namespace nsas {
 
+// Generate a small random RTT when initialize the list of addresses
+// to select all the addresses in unpredicable order
+// The initia RTT is between 0ms and 7ms which is as the same as bind9
+#define MIN_INIT_RTT 0
+#define MAX_INIT_RTT 7
+UniformRandomIntegerGenerator NameserverEntry::rndRttGen_(MIN_INIT_RTT, MAX_INIT_RTT);
 
 // Constructor, initialized with the list of addresses associated with this
 // nameserver.
 NameserverEntry::NameserverEntry(const AbstractRRset* v4Set,
     const AbstractRRset* v6Set, time_t curtime) : expiration_(0)
 {
-    // TODO: Use pseudo-random RTT
     uint32_t rtt = 0;       // Round-trip time for an address
     string v4name = "";     // Name from the V4 RRset
     string v6name = "";     // Name from the v6 RRset

+ 9 - 7
src/lib/nsas/nameserver_entry.h

@@ -24,9 +24,10 @@
 #include "address_entry.h"
 #include "asiolink.h"
 #include "exceptions/exceptions.h"
-#include "nsas_entry.h"
 #include "hash_key.h"
 #include "lru_list.h"
+#include "nsas_entry.h"
+#include "random_number_generator.h"
 #include "rrset.h"
 
 namespace isc {
@@ -195,12 +196,13 @@ public:
     };
 
 private:
-    boost::mutex    mutex_;             ///< Mutex protecting this object
-    std::string     name_;              ///< Canonical name of the nameserver
-    uint16_t        classCode_;         ///< Class of the nameserver
-    std::vector<AddressEntry> address_; ///< Set of V4/V6 addresses
-    time_t          expiration_;        ///< Summary expiration time
-    time_t          last_access_;       ///< Last access time to the structure
+    boost::mutex    mutex_;                          ///< Mutex protecting this object
+    std::string     name_;                           ///< Canonical name of the nameserver
+    uint16_t        classCode_;                      ///< Class of the nameserver
+    std::vector<AddressEntry> address_;              ///< Set of V4/V6 addresses
+    time_t          expiration_;                     ///< Summary expiration time
+    time_t          last_access_;                    ///< Last access time to the structure
+    static UniformRandomIntegerGenerator rndRttGen_; ///< Small random RTT generator
 };
 
 }   // namespace dns

+ 58 - 0
src/lib/nsas/random_number_generator.h

@@ -0,0 +1,58 @@
+// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// $Id$
+
+#ifndef __NSAS_RANDOM_NUMBER_GENERATOR_H
+#define __NSAS_RANDOM_NUMBER_GENERATOR_H
+
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/variate_generator.hpp>
+
+
+namespace isc {
+namespace nsas {
+
+/// \brief Uniform random integer generator
+///
+/// Generate uniformly distributed integers in range of [min, max]
+/// \param min The minimum number in the range
+/// \param max The maximum number in the range
+class UniformRandomIntegerGenerator{
+public:
+    UniformRandomIntegerGenerator(int min, int max):
+        min_(min), max_(max), dist_(min, max), generator_(rng_, dist_)
+    {
+        rng_.seed(time(NULL));
+    }
+
+    int operator()() { return generator_(); }
+private:
+    ///< Hide default and copy constructor
+    UniformRandomIntegerGenerator();///< Default constructor
+    UniformRandomIntegerGenerator(const UniformRandomIntegerGenerator&); ///< Copy constructor
+
+    int min_;                       ///< The minimum integer that can generate
+    int max_;                       ///< The maximum integer that can generate
+    boost::uniform_int<> dist_;     ///< Distribute uniformly.
+    boost::mt19937 rng_;            ///< Mersenne Twister: A 623-dimensionally equidistributed uniform pseudo-random number generator
+    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > generator_; ///< Uniform generator
+};
+
+}   // namespace dns
+}   // namespace isc
+
+
+#endif//__NSAS_RANDOM_NUMBER_GENERATOR_H

+ 1 - 0
src/lib/nsas/tests/Makefile.am

@@ -29,6 +29,7 @@ run_unittests_SOURCES += nameserver_entry_unittest.cc
 run_unittests_SOURCES += nsas_entry_compare_unittest.cc
 run_unittests_SOURCES += nsas_test_utilities.h 
 run_unittests_SOURCES += zone_entry_unittest.cc
+run_unittests_SOURCES += random_number_generator_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)

+ 79 - 0
src/lib/nsas/tests/random_number_generator_unittest.cc

@@ -0,0 +1,79 @@
+// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// $Id$
+
+#include <gtest/gtest.h>
+#include <boost/shared_ptr.hpp>
+
+#include <algorithm>
+#include <iostream>
+#include <vector>
+
+#include "random_number_generator.h"
+
+namespace isc {
+namespace nsas {
+
+using namespace std;
+
+/// \brief Test Fixture Class for uniform random number generator
+///
+/// The hard part for this test is how to test that the number is random?
+/// and how to test that the number is uniformly distributed? 
+/// Or maybe we can trust the boost implementation
+class UniformRandomIntegerGeneratorTest : public ::testing::Test {
+public:
+    UniformRandomIntegerGeneratorTest():
+        gen_(min_, max_)
+    {
+    }
+    virtual ~UniformRandomIntegerGeneratorTest(){}
+
+    int gen() { return gen_(); }
+    int max() const { return max_; }
+    int min() const { return min_; }
+
+private:
+    UniformRandomIntegerGenerator gen_;
+
+    const static int min_ = 1;
+    const static int max_ = 10;
+};
+
+// Test of the constructor
+TEST_F(UniformRandomIntegerGeneratorTest, Constructor) {
+    //The range must be min<=max
+    ASSERT_DEATH(UniformRandomIntegerGenerator(3, 2), "");
+}
+
+// Test of the generated integers are in the range [min, max]
+TEST_F(UniformRandomIntegerGeneratorTest, IntegerRange) {
+    vector<int> numbers;
+
+    //Generate a lot of random integers
+    for(int i = 0; i < max()*10; ++i){
+        numbers.push_back(gen());
+    }
+
+    //Remove the duplicated values
+    sort(numbers.begin(), numbers.end());
+    vector<int>::iterator it = unique(numbers.begin(), numbers.end());
+
+    //make sure the numbers are in range [min, max]
+    ASSERT_EQ(it - numbers.begin(), max() - min() + 1); 
+}
+
+} // namespace nsas
+} // namespace isc