Browse Source

[2573] added getXXX methods to datasrc ZoneLoader.

JINMEI Tatuya 12 years ago
parent
commit
38439b178e

+ 57 - 0
src/lib/datasrc/tests/zone_loader_unittest.cc

@@ -186,6 +186,12 @@ TEST_F(ZoneLoaderTest, copyUnsigned) {
     // It gets the updater directly in the constructor
     ASSERT_EQ(1, destination_client_.provided_updaters_.size());
     EXPECT_EQ(Name::ROOT_NAME(), destination_client_.provided_updaters_[0]);
+
+    // Counters are initialized to 0.
+    EXPECT_EQ(0, loader.getRRCount());
+    EXPECT_EQ(0, loader.getSize());
+    EXPECT_EQ(0, loader.getPosition());
+
     // Now load the whole zone
     loader.load();
     EXPECT_TRUE(destination_client_.commit_called_);
@@ -194,6 +200,13 @@ TEST_F(ZoneLoaderTest, copyUnsigned) {
 
     // The count is 34 because we expect the RRs to be separated.
     EXPECT_EQ(34, destination_client_.rrsets_.size());
+
+    // Check various counters.  getRRCount should be identical of the RRs
+    // we've seen.  size and position should be still 0 in the copy operation.
+    EXPECT_EQ(destination_client_.rrsets_.size(), loader.getRRCount());
+    EXPECT_EQ(0, loader.getSize());
+    EXPECT_EQ(0, loader.getPosition());
+
     // Ensure known order.
     std::sort(destination_client_.rrsets_.begin(),
               destination_client_.rrsets_.end());
@@ -221,6 +234,12 @@ TEST_F(ZoneLoaderTest, copyUnsignedIncremental) {
     // Not committed yet, we didn't complete the loading
     EXPECT_FALSE(destination_client_.commit_called_);
 
+    // Check we can get intermediate counters.  size/position are always 0
+    // in case of copy.
+    EXPECT_EQ(destination_client_.rrsets_.size(), loader.getRRCount());
+    EXPECT_EQ(0, loader.getSize());
+    EXPECT_EQ(0, loader.getPosition());
+
     // This is unusual, but allowed. Check it doesn't do anything
     loader.loadIncremental(0);
     EXPECT_EQ(10, destination_client_.rrsets_.size());
@@ -289,6 +308,12 @@ TEST_F(ZoneLoaderTest, classMismatch) {
 TEST_F(ZoneLoaderTest, loadUnsigned) {
     ZoneLoader loader(destination_client_, Name::ROOT_NAME(),
                       TEST_DATA_DIR "/root.zone");
+
+    // Counters are initialized to 0.
+    EXPECT_EQ(0, loader.getRRCount());
+    EXPECT_EQ(0, loader.getSize());
+    EXPECT_EQ(0, loader.getPosition());
+
     // It gets the updater directly in the constructor
     ASSERT_EQ(1, destination_client_.provided_updaters_.size());
     EXPECT_EQ(Name::ROOT_NAME(), destination_client_.provided_updaters_[0]);
@@ -300,6 +325,14 @@ TEST_F(ZoneLoaderTest, loadUnsigned) {
 
     // The count is 34 because we expect the RRs to be separated.
     EXPECT_EQ(34, destination_client_.rrsets_.size());
+
+    // Check various counters.  getRRCount should be identical of the RRs
+    // we've seen.  size and position should be identical of the RRs
+    // file (hardcoded, assuming we won't change it so often).
+    EXPECT_EQ(destination_client_.rrsets_.size(), loader.getRRCount());
+    EXPECT_EQ(1541, loader.getSize());
+    EXPECT_EQ(1541, loader.getPosition());
+
     // Ensure known order.
     std::sort(destination_client_.rrsets_.begin(),
               destination_client_.rrsets_.end());
@@ -308,6 +341,13 @@ TEST_F(ZoneLoaderTest, loadUnsigned) {
     EXPECT_EQ("m.root-servers.net. 3600000 IN AAAA 2001:dc3::35\n",
               destination_client_.rrsets_.back());
 
+    // Check various counters.  getRRCount should be identical of the RRs
+    // we've seen.  size and position should be equal to the size of the zone
+    // file (hardcoded assuming we won't change it so often).
+    EXPECT_EQ(destination_client_.rrsets_.size(), loader.getRRCount());
+    EXPECT_EQ(1541, loader.getSize());
+    EXPECT_EQ(1541, loader.getPosition());
+
     // It isn't possible to try again now
     EXPECT_THROW(loader.load(), isc::InvalidOperation);
     EXPECT_THROW(loader.loadIncremental(1), isc::InvalidOperation);
@@ -320,6 +360,11 @@ TEST_F(ZoneLoaderTest, loadUnsignedIncremental) {
     ZoneLoader loader(destination_client_, Name::ROOT_NAME(),
                       TEST_DATA_DIR "/root.zone");
 
+    // Counters are initialized to 0.
+    EXPECT_EQ(0, loader.getRRCount());
+    EXPECT_EQ(0, loader.getSize());
+    EXPECT_EQ(0, loader.getPosition());
+
     // Try loading few RRs first.
     loader.loadIncremental(10);
     // We should get the 10 we asked for
@@ -330,11 +375,23 @@ TEST_F(ZoneLoaderTest, loadUnsignedIncremental) {
     EXPECT_EQ(10, destination_client_.rrsets_.size());
     EXPECT_FALSE(destination_client_.commit_called_);
 
+    // Check we can get intermediate counters.  size is the size of the
+    // zone file; position is the offset to the end of 10th RR (both
+    // hardcoded).
+    EXPECT_EQ(destination_client_.rrsets_.size(), loader.getRRCount());
+    EXPECT_EQ(1541, loader.getSize());
+    EXPECT_EQ(428, loader.getPosition());
+
     // We can finish the rest
     loader.loadIncremental(30);
     EXPECT_EQ(34, destination_client_.rrsets_.size());
     EXPECT_TRUE(destination_client_.commit_called_);
 
+    // Counters are updated accordingly.  size and position are now identical.
+    EXPECT_EQ(destination_client_.rrsets_.size(), loader.getRRCount());
+    EXPECT_EQ(1541, loader.getSize());
+    EXPECT_EQ(1541, loader.getPosition());
+
     // No more loading now
     EXPECT_THROW(loader.load(), isc::InvalidOperation);
     EXPECT_THROW(loader.loadIncremental(1), isc::InvalidOperation);

+ 27 - 5
src/lib/datasrc/zone_loader.cc

@@ -35,7 +35,7 @@ ZoneLoader::ZoneLoader(DataSourceClient& destination, const Name& zone_name,
     // have to aggregate them) and also because our limit semantics.
     iterator_(source.getIterator(zone_name, true)),
     updater_(destination.getUpdater(zone_name, true, false)),
-    complete_(false)
+    complete_(false), rr_count_(0)
 {
     // The getIterator should never return NULL. So we check it.
     // Or should we throw instead?
@@ -59,8 +59,7 @@ ZoneLoader::ZoneLoader(DataSourceClient& destination, const Name& zone_name,
 ZoneLoader::ZoneLoader(DataSourceClient& destination, const Name& zone_name,
                        const char* filename) :
     updater_(destination.getUpdater(zone_name, true, false)),
-    complete_(false),
-    loaded_ok_(true)
+    complete_(false), loaded_ok_(true), rr_count_(0)
 {
     if (updater_ == ZoneUpdaterPtr()) {
         isc_throw(DataSourceError, "Zone " << zone_name << " not found in "
@@ -83,7 +82,7 @@ namespace {
 // Copy up to limit RRsets from source to destination
 bool
 copyRRsets(const ZoneUpdaterPtr& destination, const ZoneIteratorPtr& source,
-           size_t limit)
+           size_t limit, size_t& rr_count_)
 {
     size_t loaded = 0;
     while (loaded < limit) {
@@ -95,6 +94,7 @@ copyRRsets(const ZoneUpdaterPtr& destination, const ZoneIteratorPtr& source,
             destination->addRRset(*rrset);
         }
         ++loaded;
+        rr_count_ += rrset->getRdataCount();
     }
     return (false); // Not yet, there may be more
 }
@@ -118,8 +118,9 @@ ZoneLoader::loadIncremental(size_t limit) {
         if (complete_ && !loaded_ok_) {
             isc_throw(MasterFileError, "Error while loading master file");
         }
+        rr_count_ = loader_->getRRCount();
     } else {
-        complete_ = copyRRsets(updater_, iterator_, limit);
+        complete_ = copyRRsets(updater_, iterator_, limit, rr_count_);
     }
 
     if (complete_) {
@@ -128,5 +129,26 @@ ZoneLoader::loadIncremental(size_t limit) {
     return (complete_);
 }
 
+size_t
+ZoneLoader::getRRCount() const {
+    return (rr_count_);
+}
+
+size_t
+ZoneLoader::getSize() const {
+    if (!loader_) {
+        return (0);
+    }
+    return (loader_->getSize());
+}
+
+size_t
+ZoneLoader::getPosition() const {
+    if (!loader_) {
+        return (0);
+    }
+    return (loader_->getPosition());
+}
+
 } // end namespace datasrc
 } // end namespace isc

+ 75 - 4
src/lib/datasrc/zone_loader.h

@@ -135,10 +135,76 @@ public:
     ///     similar problem is found when loading the master file.
     /// \note If the limit is exactly the number of RRs available to be loaded,
     ///     the method still returns false and true'll be returned on the next
-    ///     call (which will load 0 RRs). This is because the end of iterator or
-    ///     master file is detected when reading past the end, not when the last
-    ///     one is read.
+    ///     call (which will load 0 RRs). This is because the end of iterator
+    ///     or master file is detected when reading past the end, not when the
+    ///     last one is read.
     bool loadIncremental(size_t limit);
+
+    /// \brief Return the number of RRs loaded.
+    ///
+    /// This method returns the number of RRs loaded via this loader by the
+    /// time of the call.  Before starting the load it will return 0.
+    /// It will return the total number of RRs of the zone on and after
+    /// completing the load.
+    ///
+    /// \throw None
+    size_t getRRCount() const;
+
+    /// \brief Return the (estimated) total size of the entire zone.
+    ///
+    /// This method returns some hint on how large the zone will be when
+    /// completing the load.  The returned size is a conceptual value that
+    /// can internally mean anything.  The intended usage of the value is
+    /// to compare it to the return value of \c getPosition() to estimate
+    /// the progress of the load at the time of the call.
+    ///
+    /// In this implementation, if the loader is constructed with a file
+    /// name, the returned size is the size of the zone file.  If it includes
+    /// other files via the $INCLUDE directive, it will be the sum of the
+    /// file sizes of all such files that the loader has handled.
+    /// Note that it may be smaller than the final size if there are more
+    /// files to be included which the loader has not seen by the time of
+    /// the call.
+    ///
+    /// Currently, if the loader is constructed with another data source
+    /// client, this method always returns 0.  In future, it may be possible
+    /// to return something more effective, e.g, the total number of RRs
+    /// if the underlying data source can provide that information efficiently.
+    ///
+    /// In any case, the caller shouldn't assume anything specific about the
+    /// meaning of the value other than for comparing it to the result of
+    /// \c getPosition().
+    ///
+    /// \throw None
+    size_t getSize() const;
+
+    /// \brief Return the current position of the loader in the zone being
+    /// loaded.
+    ///
+    /// This method returns a conceptual "position" of this loader in the
+    /// loader relative to the return value of \c getSize().  Before starting
+    /// the load the position is set to 0; on successful completion,
+    /// it will be equal to the \c getSize() value; in the middle of the load,
+    /// it's expected to be between these values, which would give some
+    /// hint about the progress of the loader.
+    ///
+    /// In the current implementation, if the loader is constructed with a
+    /// file name, the returned value is the number of characters from the
+    /// zone file (and any included files) recognized by the underlying zone
+    /// file parser.
+    ///
+    /// If it's constructed with another data source client, it's always
+    /// 0 for now; however, if \c getPosition() is extended in this case
+    /// as documented (see the method description), the result of
+    /// \c getRRCount() could be used for the current position.
+    ///
+    /// Like \c getSize(), the value is conceptual and the caller shouldn't
+    /// assume any specific meaning of the value except for comparing it
+    /// to \c getSize() results.
+    ///
+    /// \throw None
+    size_t getPosition() const;
+
 private:
     /// \brief The iterator used as source of data in case of the copy mode.
     const ZoneIteratorPtr iterator_;
@@ -150,9 +216,14 @@ private:
     bool complete_;
     /// \brief Was the loading successful?
     bool loaded_ok_;
+    size_t rr_count_;
 };
 
 }
 }
 
-#endif
+#endif  // DATASRC_ZONE_LOADER_H
+
+// Local Variables:
+// mode: c++
+// End: