[svn] commit: r1041 - in /trunk/src: bin/auth/auth_srv.cc lib/cc/cpp/data.cc lib/cc/cpp/data.h lib/cc/cpp/data_unittests.cc lib/config/cpp/ccsession.cc

BIND 10 source code commits bind10-changes at lists.isc.org
Sun Feb 28 20:33:42 UTC 2010


Author: jelte
Date: Sun Feb 28 20:33:42 2010
New Revision: 1041

Log:
added isc::data::merge(element, element), that merges the values in the second mapelement into the first (copies the pointers that are present in the second element, and removes from a the values that are empty pointers in the second)

the ElementPtr passed to the module's config handler now only contains the data that has actually changed (settings that are the same as before are removed from what is passed to the config handler)

Modified:
    trunk/src/bin/auth/auth_srv.cc
    trunk/src/lib/cc/cpp/data.cc
    trunk/src/lib/cc/cpp/data.h
    trunk/src/lib/cc/cpp/data_unittests.cc
    trunk/src/lib/config/cpp/ccsession.cc

Modified: trunk/src/bin/auth/auth_srv.cc
==============================================================================
--- trunk/src/bin/auth/auth_srv.cc (original)
+++ trunk/src/bin/auth/auth_srv.cc Sun Feb 28 20:33:42 2010
@@ -128,10 +128,8 @@
 void
 AuthSrv::setDbFile(const std::string& db_file)
 {
-    if (_db_file != db_file) {
-        cout << "Change data source file, call our data source's function to now read " << db_file << endl;
-        _db_file = db_file;
-    }
+    cout << "Change data source file, call our data source's function to now read " << db_file << endl;
+    _db_file = db_file;
 }
 
 ElementPtr
@@ -140,9 +138,7 @@
         // the ModuleCCSession has already checked if we have
         // the correct ElementPtr type as specified in our .spec file
         if (new_config->contains("database_file")) {
-            // Since we also get this value if it hasn't changed,
-            // but is non-default, setDbFile here should only really
-            // do anything if it has actually changed
+            // We only get this if the value has actually changed.
             setDbFile(new_config->get("database_file")->stringValue());
         }
     }

Modified: trunk/src/lib/cc/cpp/data.cc
==============================================================================
--- trunk/src/lib/cc/cpp/data.cc (original)
+++ trunk/src/lib/cc/cpp/data.cc Sun Feb 28 20:33:42 2010
@@ -1005,21 +1005,40 @@
 void
 isc::data::removeIdentical(ElementPtr a, const ElementPtr b)
 {
+    if (!b) {
+        return;
+    }
     if (a->getType() != Element::map || b->getType() != Element::map) {
         dns_throw(TypeError, "Non-map Elements passed to removeIdentical");
     }
-    std::cout<<"[XX] removeidentical from " << a << " and " << b << std::endl;
-    
+
     std::map<std::string, ElementPtr> m = a->mapValue();
     for (std::map<std::string, ElementPtr>::iterator it = m.begin() ;
          it != m.end() ; ++it) {
         if (b->contains((*it).first)) {
             if (a->get((*it).first)->equals(b->get((*it).first))) {
-                std::cout<<"[XX] remove " << (*it).first << std::endl;
                 a->remove((*it).first);
             }
         }
     }
-    std::cout<<"[XX] a now " << a << std::endl;
-
-}
+}
+
+void
+isc::data::merge(ElementPtr element, const ElementPtr other)
+{
+    if (element->getType() != Element::map ||
+        other->getType() != Element::map) {
+        dns_throw(TypeError, "merge arguments not MapElements");
+    }
+    
+    std::map<std::string, ElementPtr> m = other->mapValue();
+    for (std::map<std::string, ElementPtr>::iterator it = m.begin() ;
+         it != m.end() ; ++it) {
+        if ((*it).second) {
+            element->set((*it).first, (*it).second);
+        } else if (element->contains((*it).first)) {
+            element->remove((*it).first);
+        }
+    }
+}
+

Modified: trunk/src/lib/cc/cpp/data.h
==============================================================================
--- trunk/src/lib/cc/cpp/data.h (original)
+++ trunk/src/lib/cc/cpp/data.h Sun Feb 28 20:33:42 2010
@@ -455,12 +455,22 @@
 
 ///
 /// \brief Remove all values from the first ElementPtr that are
-/// also present in the second. Both ElementPtrs MUST be MapElements
+/// equal in the second. Both ElementPtrs MUST be MapElements
 /// The use for this function is to end up with a MapElement that
 /// only contains new and changed values (for ModuleCCSession and
 /// configuration update handlers)
 /// Raises a TypeError if a or b are not MapElements
 void removeIdentical(ElementPtr a, const ElementPtr b);
+
+/// \brief Merges the data from other into element.
+/// (on the first level). Both elements must be
+/// MapElements.
+/// Every string,value pair in other is copied into element
+/// (the ElementPtr of value is copied, this is not a new object)
+/// Unless the value is an empty ElementPtr, in which case the
+/// whole key is removed from element.
+/// Raises a TypeError if either ElementPtr is not a MapElement
+void merge(ElementPtr element, const ElementPtr other);
 
 } }
 

Modified: trunk/src/lib/cc/cpp/data_unittests.cc
==============================================================================
--- trunk/src/lib/cc/cpp/data_unittests.cc (original)
+++ trunk/src/lib/cc/cpp/data_unittests.cc Sun Feb 28 20:33:42 2010
@@ -380,3 +380,35 @@
     removeIdentical(a, b);
     EXPECT_TRUE(a == c);
 }
+
+TEST(Element, merge)
+{
+    ElementPtr a = Element::createFromString("{}");
+    ElementPtr b = Element::createFromString("{}");
+    ElementPtr c = Element::createFromString("{}");
+    merge(a, b);
+    EXPECT_TRUE(a == c);
+
+    a = Element::createFromString("1");
+    b = Element::createFromString("{}");
+    EXPECT_THROW(merge(a, b), TypeError);
+
+    a = Element::createFromString("{}");
+    b = Element::createFromString("{ \"a\": 1 }");
+    c = Element::createFromString("{ \"a\": 1 }");
+    merge(a, b);
+    EXPECT_TRUE(a == c);
+
+    a = Element::createFromString("{ \"a\": 1 }");
+    b = Element::createFromString("{ \"a\": 2 }");
+    c = Element::createFromString("{ \"a\": 2 }");
+    merge(a, b);
+    EXPECT_TRUE(a == c);
+
+    a = Element::createFromString("{ \"a\": { \"b\": \"c\" } }");
+    b = Element::createFromString("{ \"a\": { \"b\": \"d\" } }");
+    c = Element::createFromString("{ \"a\": { \"b\": \"d\" } }");
+    merge(a, b);
+    EXPECT_TRUE(a == c);
+
+}

Modified: trunk/src/lib/config/cpp/ccsession.cc
==============================================================================
--- trunk/src/lib/config/cpp/ccsession.cc (original)
+++ trunk/src/lib/config/cpp/ccsession.cc Sun Feb 28 20:33:42 2010
@@ -189,7 +189,8 @@
     ElementPtr spec_msg = createCommand("module_spec", module_specification_.getFullSpec());
     session_.group_sendmsg(spec_msg, "ConfigManager");
     session_.group_recvmsg(env, answer, false);
-    
+
+    config_ = Element::createFromString("{}");
     // get any stored configuration from the manager
     if (config_handler_) {
         ElementPtr cmd = Element::createFromString("{ \"command\": [\"get_config\", {\"module_name\":\"" + module_name_ + "\"} ] }");
@@ -202,7 +203,7 @@
 }
 
 /// Validates the new config values, if they are correct,
-/// call the config handler
+/// call the config handler with the values that have changed
 /// If that results in success, store the new config
 ElementPtr
 ModuleCCSession::handleConfigUpdate(ElementPtr new_config)
@@ -220,13 +221,15 @@
         }
         answer = createAnswer(2, ss.str());
     } else {
+        // remove the values that have not changed
+        isc::data::removeIdentical(new_config, getConfig());
         // handle config update
         std::cout << "handleConfigUpdate " << new_config << std::endl;
         answer = config_handler_(new_config);
         int rcode;
         parseAnswer(rcode, answer);
         if (rcode == 0) {
-            config_ = new_config;
+            isc::data::merge(config_, new_config);
         }
     }
     std::cout << "end handleConfigUpdate " << new_config << std::endl;




More information about the bind10-changes mailing list