Parcourir la source

[2268] Sort oft-used RRTypes to be in front of RdataSet lists

Mukund Sivaraman il y a 12 ans
Parent
commit
b3d273056f

+ 70 - 5
src/lib/datasrc/memory/zone_data_updater.cc

@@ -24,6 +24,54 @@ namespace isc {
 namespace datasrc {
 namespace memory {
 
+namespace { // anonymous namespace
+
+// Returns a value-less than, or greater-than zero if 'a' is less-than
+// or greater-than 'b'. If they are equal, it returns 0. The comparison
+// function is such that often-used types such as A, AAAA, NS, SOA, MX,
+// etc.  are less than other types. See the code for the ordering.
+int
+compareTypes(const RdataSet* a,
+             const RdataSet* b) {
+    // First RRType::A()
+    if (a->type == RRType::A()) {
+        return (-1);
+    } else if (b->type == RRType::A()) {
+        return (1);
+    }
+
+    // Then, RRType::AAAA(), etc.
+    if (a->type == RRType::AAAA()) {
+        return (-1);
+    } else if (b->type == RRType::AAAA()) {
+        return (1);
+    }
+
+    if (a->type == RRType::NS()) {
+        return (-1);
+    } else if (b->type == RRType::NS()) {
+        return (1);
+    }
+
+    if (a->type == RRType::SOA()) {
+        return (-1);
+    } else if (b->type == RRType::SOA()) {
+        return (1);
+    }
+
+    if (a->type == RRType::MX()) {
+        return (-1);
+    } else if (b->type == RRType::MX()) {
+        return (1);
+    }
+
+    // Everything else comes in front of the rest of the list, so that
+    // we can insert quickly.
+    return (-1);
+}
+
+} // end of anonymous namespace
+
 void
 ZoneDataUpdater::addWildcards(const Name& name) {
     Name wname(name);
@@ -249,12 +297,29 @@ ZoneDataUpdater::addRdataSet(const ConstRRsetPtr rrset,
                       << rrset->getType() << ")");
         }
 
-        RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_,
-                                              rrset, rrsig);
-        rdataset->next = rdataset_head;
-        node->setData(rdataset);
+        RdataSet* rdataset_new = RdataSet::create(mem_sgmt_, encoder_,
+                                                  rrset, rrsig);
+
+        // Insertion sort the new RdataSet into place in the list.
+        RdataSet* prev = NULL;
+        RdataSet* current = rdataset_head;
+        for (; current != NULL; current = current->getNext())
+        {
+            if (compareTypes(rdataset_new, current) < 0) {
+                break;
+            }
+
+            prev = current;
+        }
+
+        rdataset_new->next = current;
+        if (prev != NULL) {
+             prev->next = rdataset_new;
+        } else {
+             node->setData(rdataset_new);
+        }
 
-        // Ok, we just put it in
+        // Ok, we just put it in.
 
         // If this RRset creates a zone cut at this node, mark the node
         // indicating the need for callback in find().

+ 6 - 6
src/lib/datasrc/tests/memory/memory_client_unittest.cc

@@ -222,13 +222,13 @@ TEST_F(MemoryClientTest, loadFromIterator) {
     // RRType::MX() RRset
     rrset = iterator->getNextRRset();
     EXPECT_TRUE(rrset);
-    EXPECT_EQ(RRType::MX(), rrset->getType());
+    EXPECT_EQ(RRType::A(), rrset->getType());
     EXPECT_EQ(1, rrset->getRRsigDataCount()); // this RRset is signed
 
     // RRType::A() RRset
     rrset = iterator->getNextRRset();
     EXPECT_TRUE(rrset);
-    EXPECT_EQ(RRType::A(), rrset->getType());
+    EXPECT_EQ(RRType::MX(), rrset->getType());
     EXPECT_EQ(1, rrset->getRRsigDataCount()); // also signed
 
     // There's nothing else in this iterator
@@ -364,11 +364,11 @@ TEST_F(MemoryClientTest, loadReloadZone) {
 
     set = node->getData();
     EXPECT_NE(static_cast<const RdataSet*>(NULL), set);
-    EXPECT_EQ(RRType::AAAA(), set->type);
+    EXPECT_EQ(RRType::A(), set->type);
 
     set = set->getNext();
     EXPECT_NE(static_cast<const RdataSet*>(NULL), set);
-    EXPECT_EQ(RRType::A(), set->type);
+    EXPECT_EQ(RRType::AAAA(), set->type);
 
     set = set->getNext();
     EXPECT_EQ(static_cast<const RdataSet*>(NULL), set);
@@ -754,11 +754,11 @@ TEST_F(MemoryClientTest, findZoneData) {
 
     set = node->getData();
     EXPECT_NE(static_cast<const RdataSet*>(NULL), set);
-    EXPECT_EQ(RRType::AAAA(), set->type);
+    EXPECT_EQ(RRType::A(), set->type);
 
     set = set->getNext();
     EXPECT_NE(static_cast<const RdataSet*>(NULL), set);
-    EXPECT_EQ(RRType::A(), set->type);
+    EXPECT_EQ(RRType::AAAA(), set->type);
 
     set = set->getNext();
     EXPECT_EQ(static_cast<const RdataSet*>(NULL), set);