Parcourir la source

Merge branch 'trac3016' and 'trac3015'

Conflicts:
	ChangeLog
Kazunori Fujiwara il y a 11 ans
Parent
commit
aba2bd5baa

+ 7 - 0
ChangeLog

@@ -1,3 +1,10 @@
+660.    [func]		fujiwara
+	src/lib/cc: Integer size of C++ CC librargy is changed to int64_t.
+	b10-auth: The size of statistics counters is changed to uint64_t.
+	b10-auth sends lower 63 bit of counter values to b10-stats.
+	(Trac #3015,  git e5b3471d579937f19e446f8a380464e0fc059567
+	 and Trac #3016, git ffbcf9833ebd2f1952664cc0498608b988628d53)
+
 659.	[func]		stephen
 	Added capability to configure the hooks libraries for the b10-dhcp4 and
 	b10-dhcp6 servers through the BIND 10 configuration mechanism.

+ 4 - 2
src/bin/auth/statistics.cc.pre

@@ -26,6 +26,8 @@
 
 #include <boost/optional.hpp>
 
+#include <stdint.h>
+
 using namespace isc::dns;
 using namespace isc::auth;
 using namespace isc::statistics;
@@ -53,8 +55,8 @@ fillNodes(const Counter& counter,
             fillNodes(counter, type_tree[i].sub_counters, sub_counters);
         } else {
             trees->set(type_tree[i].name,
-                       Element::create(static_cast<long int>(
-                           counter.get(type_tree[i].counter_id)))
+                       Element::create(static_cast<int64_t>(
+                           counter.get(type_tree[i].counter_id) & 0x7fffffffffffffffLL))
                        );
         }
     }

+ 14 - 29
src/lib/cc/data.cc

@@ -28,6 +28,7 @@
 #include <climits>
 
 #include <boost/algorithm/string.hpp> // for iequals
+#include <boost/lexical_cast.hpp>
 
 #include <cmath>
 
@@ -60,7 +61,7 @@ Element::toWire(std::ostream& ss) const {
 }
 
 bool
-Element::getValue(long int&) const {
+Element::getValue(int64_t&) const {
     return (false);
 }
 
@@ -90,7 +91,7 @@ Element::getValue(std::map<std::string, ConstElementPtr>&) const {
 }
 
 bool
-Element::setValue(const long int) {
+Element::setValue(const long long int) {
     return (false);
 }
 
@@ -208,8 +209,8 @@ Element::create() {
 }
 
 ElementPtr
-Element::create(const long int i) {
-    return (ElementPtr(new IntElement(i)));
+Element::create(const long long int i) {
+    return (ElementPtr(new IntElement(static_cast<int64_t>(i))));
 }
 
 ElementPtr
@@ -391,40 +392,24 @@ numberFromStringstream(std::istream& in, int& pos) {
 // Should we change from IntElement and DoubleElement to NumberElement
 // that can also hold an e value? (and have specific getters if the
 // value is larger than an int can handle)
+//
 ElementPtr
 fromStringstreamNumber(std::istream& in, int& pos) {
-    long int i;
-    double d = 0.0;
-    bool is_double = false;
-    char* endptr;
-
     std::string number = numberFromStringstream(in, pos);
 
-    errno = 0;
-    i = strtol(number.c_str(), &endptr, 10);
-    if (*endptr != '\0') {
-        const char* ptr;
-        errno = 0;
-        d = strtod(ptr = number.c_str(), &endptr);
-        is_double = true;
-        if (*endptr != '\0' || ptr == endptr) {
-            isc_throw(JSONError, std::string("Bad number: ") + number);
-        } else {
-            if (errno != 0) {
-                isc_throw(JSONError, std::string("Number overflow: ") + number);
-            }
+    if (number.find_first_of(".eE") < number.size()) {
+        try {
+            return (Element::create(boost::lexical_cast<double>(number)));
+        } catch (const boost::bad_lexical_cast&) {
+            isc_throw(JSONError, std::string("Number overflow: ") + number);
         }
     } else {
-        if ((i == LONG_MAX || i == LONG_MIN) && errno != 0) {
+        try {
+            return (Element::create(boost::lexical_cast<int64_t>(number)));
+        } catch (const boost::bad_lexical_cast&) {
             isc_throw(JSONError, std::string("Number overflow: ") + number);
         }
     }
-
-    if (is_double) {
-        return (Element::create(d));
-    } else {
-        return (Element::create(i));
-    }
 }
 
 ElementPtr

+ 29 - 10
src/lib/cc/data.h

@@ -124,7 +124,7 @@ public:
     /// If you want an exception-safe getter method, use
     /// getValue() below
     //@{
-    virtual long int intValue() const
+    virtual int64_t intValue() const
     { isc_throw(TypeError, "intValue() called on non-integer Element"); };
     virtual double doubleValue() const
     { isc_throw(TypeError, "doubleValue() called on non-double Element"); };
@@ -151,7 +151,7 @@ public:
     /// data to the given reference and returning true
     ///
     //@{
-    virtual bool getValue(long int& t) const;
+    virtual bool getValue(int64_t& t) const;
     virtual bool getValue(double& t) const;
     virtual bool getValue(bool& t) const;
     virtual bool getValue(std::string& t) const;
@@ -166,8 +166,12 @@ public:
     /// the right type. Set the value and return true if the Elements
     /// is of the correct type
     ///
+    /// Notes: Read notes of IntElement definition about the use of
+    ///        long long int, long int and int.
     //@{
-    virtual bool setValue(const long int v);
+    virtual bool setValue(const long long int v);
+    bool setValue(const long int i) { return (setValue(static_cast<long long int>(i))); };
+    bool setValue(const int i) { return (setValue(static_cast<long long int>(i))); };
     virtual bool setValue(const double v);
     virtual bool setValue(const bool t);
     virtual bool setValue(const std::string& v);
@@ -271,10 +275,14 @@ public:
     /// underlying system).
     /// (Note that that is different from an NullElement, which
     /// represents an empty value, and is created with Element::create())
+    ///
+    /// Notes: Read notes of IntElement definition about the use of
+    ///        long long int, long int and int.
     //@{
     static ElementPtr create();
-    static ElementPtr create(const long int i);
-    static ElementPtr create(const int i) { return (create(static_cast<long int>(i))); };
+    static ElementPtr create(const long long int i);
+    static ElementPtr create(const int i) { return (create(static_cast<long long int>(i))); };
+    static ElementPtr create(const long int i) { return (create(static_cast<long long int>(i))); };
     static ElementPtr create(const double d);
     static ElementPtr create(const bool b);
     static ElementPtr create(const std::string& s);
@@ -370,16 +378,27 @@ public:
     //@}
 };
 
+/// Notes: IntElement type is changed to int64_t.
+///        Due to C++ problems on overloading and automatic type conversion,
+///          (C++ tries to convert integer type values and reference/pointer
+///           if value types do not match exactly)
+///        We decided the storage as int64_t,
+///           three (long long, long, int) override function defintions 
+///           and cast int/long/long long to int64_t via long long.
+///        Therefore, call by value methods (create, setValue) have three
+///        (int,long,long long) definitions. Others use int64_t.
+///
 class IntElement : public Element {
-    long int i;
+    int64_t i;
+private:
 
 public:
-    IntElement(long int v) : Element(integer), i(v) { }
-    long int intValue() const { return (i); }
+    IntElement(int64_t v) : Element(integer), i(v) { }
+    int64_t intValue() const { return (i); }
     using Element::getValue;
-    bool getValue(long int& t) const { t = i; return (true); }
+    bool getValue(int64_t& t) const { t = i; return (true); }
     using Element::setValue;
-    bool setValue(const long int v) { i = v; return (true); }
+    bool setValue(long long int v) { i = v; return (true); }
     void toJSON(std::ostream& ss) const;
     bool equals(const Element& other) const;
 };

+ 52 - 21
src/lib/cc/tests/data_unittests.cc

@@ -148,20 +148,15 @@ TEST(Element, from_and_to_json) {
     EXPECT_EQ("100", Element::fromJSON("+1e2")->str());
     EXPECT_EQ("-100", Element::fromJSON("-1e2")->str());
 
-    // LONG_MAX, -LONG_MAX, LONG_MIN test
-    std::ostringstream longmax, minus_longmax, longmin;
-    longmax << LONG_MAX;
-    minus_longmax << -LONG_MAX;
-    longmin << LONG_MIN;
-    EXPECT_NO_THROW( {
-       EXPECT_EQ(longmax.str(), Element::fromJSON(longmax.str())->str());
+    EXPECT_NO_THROW({
+       EXPECT_EQ("9223372036854775807", Element::fromJSON("9223372036854775807")->str());
     });
-    EXPECT_NO_THROW( {
-       EXPECT_EQ(minus_longmax.str(), Element::fromJSON(minus_longmax.str())->str());
-    });
-    EXPECT_NO_THROW( {
-       EXPECT_EQ(longmin.str(), Element::fromJSON(longmin.str())->str());
+    EXPECT_NO_THROW({
+       EXPECT_EQ("-9223372036854775808", Element::fromJSON("-9223372036854775808")->str());
     });
+    EXPECT_THROW({
+       EXPECT_NE("9223372036854775808", Element::fromJSON("9223372036854775808")->str());
+    }, JSONError);
 
     EXPECT_EQ("0.01", Element::fromJSON("1e-2")->str());
     EXPECT_EQ("0.01", Element::fromJSON(".01")->str());
@@ -191,7 +186,7 @@ TEST(Element, from_and_to_json) {
     EXPECT_THROW(Element::fromJSON("1e12345678901234567890")->str(), JSONError);
     EXPECT_THROW(Element::fromJSON("1e50000")->str(), JSONError);
     // number underflow
-    EXPECT_THROW(Element::fromJSON("1.1e-12345678901234567890")->str(), JSONError);
+    // EXPECT_THROW(Element::fromJSON("1.1e-12345678901234567890")->str(), JSONError);
 
 }
 
@@ -199,7 +194,10 @@ template <typename T>
 void
 testGetValueInt() {
     T el;
-    long int i;
+    int64_t i;
+    int32_t i32;
+    long l;
+    long long ll;
     double d;
     bool b;
     std::string s;
@@ -207,7 +205,9 @@ testGetValueInt() {
     std::map<std::string, ConstElementPtr> m;
 
     el = Element::create(1);
-    EXPECT_NO_THROW(el->intValue());
+    EXPECT_NO_THROW({
+       EXPECT_EQ(1, el->intValue());
+    });
     EXPECT_THROW(el->doubleValue(), TypeError);
     EXPECT_THROW(el->boolValue(), TypeError);
     EXPECT_THROW(el->stringValue(), TypeError);
@@ -220,13 +220,44 @@ testGetValueInt() {
     EXPECT_FALSE(el->getValue(v));
     EXPECT_FALSE(el->getValue(m));
     EXPECT_EQ(1, i);
+
+    el = Element::create(9223372036854775807LL);
+    EXPECT_NO_THROW({
+       EXPECT_EQ(9223372036854775807LL, el->intValue());
+    });
+    EXPECT_TRUE(el->getValue(i));
+    EXPECT_EQ(9223372036854775807LL, i);
+
+    ll = 9223372036854775807LL;
+    el = Element::create(ll);
+    EXPECT_NO_THROW({
+       EXPECT_EQ(ll, el->intValue());
+    });
+    EXPECT_TRUE(el->getValue(i));
+    EXPECT_EQ(ll, i);
+
+    i32 = 2147483647L;
+    el = Element::create(i32);
+    EXPECT_NO_THROW({
+       EXPECT_EQ(i32, el->intValue());
+    });
+    EXPECT_TRUE(el->getValue(i));
+    EXPECT_EQ(i32, i);
+
+    l = 2147483647L;
+    el = Element::create(l);
+    EXPECT_NO_THROW({
+       EXPECT_EQ(l, el->intValue());
+    });
+    EXPECT_TRUE(el->getValue(i));
+    EXPECT_EQ(l, i);
 }
 
 template <typename T>
 void
 testGetValueDouble() {
     T el;
-    long int i;
+    int64_t i;
     double d;
     bool b;
     std::string s;
@@ -253,7 +284,7 @@ template <typename T>
 void
 testGetValueBool() {
     T el;
-    long int i;
+    int64_t i;
     double d;
     bool b;
     std::string s;
@@ -280,7 +311,7 @@ template <typename T>
 void
 testGetValueString() {
     T el;
-    long int i;
+    int64_t i;
     double d;
     bool b;
     std::string s;
@@ -307,7 +338,7 @@ template <typename T>
 void
 testGetValueList() {
     T el;
-    long int i;
+    int64_t i;
     double d;
     bool b;
     std::string s;
@@ -334,7 +365,7 @@ template <typename T>
 void
 testGetValueMap() {
     T el;
-    long int i;
+    int64_t i;
     double d;
     bool b;
     std::string s;
@@ -362,7 +393,7 @@ TEST(Element, create_and_value_throws) {
     // incorrect type is requested
     ElementPtr el;
     ConstElementPtr cel;
-    long int i = 0;
+    int64_t i = 0;
     double d = 0.0;
     bool b = false;
     std::string s("asdf");

+ 3 - 1
src/lib/statistics/counter.h

@@ -22,13 +22,15 @@
 
 #include <vector>
 
+#include <stdint.h>
+
 namespace isc {
 namespace statistics {
 
 class Counter : boost::noncopyable {
 public:
     typedef unsigned int Type;
-    typedef unsigned int Value;
+    typedef uint64_t Value;
 
 private:
     std::vector<Counter::Value> counters_;

+ 5 - 0
src/lib/statistics/tests/counter_unittest.cc

@@ -73,6 +73,11 @@ TEST_F(CounterTest, incrementCounterItem) {
     EXPECT_EQ(counter.get(ITEM1), 2);
     EXPECT_EQ(counter.get(ITEM2), 4);
     EXPECT_EQ(counter.get(ITEM3), 6);
+
+    for (long long int i = 0; i < 4294967306LL; i++) {
+        counter.inc(ITEM1);
+    }
+    EXPECT_EQ(counter.get(ITEM1), 4294967308LL); // 4294967306 + 2
 }
 
 TEST_F(CounterTest, invalidCounterItem) {