Browse Source

MemoryZone::add implemented

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac447@3958 e5f2f494-b856-4b98-b285-d166d9295462
Michal Vaner 14 years ago
parent
commit
38b34aa2b7
2 changed files with 83 additions and 0 deletions
  1. 77 0
      src/lib/datasrc/memory_datasrc.cc
  2. 6 0
      src/lib/datasrc/memory_datasrc.h

+ 77 - 0
src/lib/datasrc/memory_datasrc.cc

@@ -51,12 +51,84 @@ struct MemoryZone::MemoryZoneImpl {
      * that.
      */
     typedef map<RRType, ConstRRsetPtr> Domain;
+    typedef Domain::value_type DomainPair;
     typedef boost::shared_ptr<Domain> DomainPtr;
     // The tree stores domains
     typedef RBTree<Domain> DomainTree;
     typedef RBNode<Domain> DomainNode;
     // The actual zone data
     DomainTree domains_;
+
+    /*
+     * Get relative part of the Name. (the result looks like
+     * absolute, but only the part below zone cut is used).
+     *
+     * Therefore, if we pass www.example.org to zone example.org,
+     * it returns "www.". If we give it example.org, it returns
+     * "." (root).
+     */
+    Name getRelativeName(const Name& name) const {
+        // Sanitize output
+        switch (name.compare(origin_).getRelation()) {
+            case NameComparisonResult::SUBDOMAIN:
+                return (name.split(0, name.getLabelCount() -
+                    origin_.getLabelCount()));
+            case NameComparisonResult::EQUAL:
+                return (Name::ROOT_NAME());
+            default:
+                isc_throw(OutOfZone, "The provided name " <<
+                    name.toText() << " is out of the zone " <<
+                    origin_.toText());
+        }
+    }
+
+    /*
+     * Implementation of longer methods. We put them here, because the
+     * access is without the impl_-> and it will get inlined anyway.
+     */
+    // Implementation of MemyroyZone::add
+    result::Result add(const ConstRRsetPtr& rrset) {
+        // Sanitize input
+        if (!rrset) {
+            isc_throw(NullRRset, "The rrset provided is NULL");
+        }
+        Name relative_name(getRelativeName(rrset->getName()));
+        // TODO We do not need to store the part above the zone cut
+        // Get the node
+        DomainNode* node;
+        switch (domains_.insert(rrset->getName(), &node)) {
+            // Just check it returns reasonable results
+            case DomainTree::SUCCEED:
+            case DomainTree::ALREADYEXIST:
+                break;
+            // Something odd got out
+            default:
+                isc_throw(AssertError,
+                    "RBTree<Domain>::insert returned unexpected result");
+        }
+        if (!node) {
+            isc_throw(AssertError, "RBTree<Domain>::insert gave NULL node");
+        }
+
+        // Now get the domain
+        DomainPtr domain;
+        // It didn't exist yet, create it
+        if (node->isEmpty()) {
+            domain.reset(new Domain);
+            node->setData(domain);
+        } else { // Get existing one
+            domain = node->getData();
+        }
+
+        // Try inserting the rrset there
+        if (domain->insert(DomainPair(rrset->getType(), rrset)).second) {
+            // Ok, we just put it in
+            return (result::SUCCESS);
+        } else {
+            // The RRSet of given type was already there
+            return (result::EXIST);
+        }
+    }
 };
 
 MemoryZone::MemoryZone(const RRClass& zone_class, const Name& origin) :
@@ -84,6 +156,11 @@ MemoryZone::find(const Name&, const RRType&) const {
     return (FindResult(NXDOMAIN, RRsetPtr()));
 }
 
+result::Result
+MemoryZone::add(const ConstRRsetPtr& rrset) {
+    return (impl_->add(rrset));
+}
+
 /// Implementation details for \c MemoryDataSrc hidden from the public
 /// interface.
 ///

+ 6 - 0
src/lib/datasrc/memory_datasrc.h

@@ -75,6 +75,12 @@ public:
         { }
     };
 
+    struct AssertError : public Unexpected {
+        AssertError(const char* file, size_t line, const char* what) :
+            Unexpected(file, line, what)
+        { }
+    };
+
 private:
     /// \name Hidden private data
     //@{