// 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_);
// 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());
// 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());
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]);
// 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());
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);
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
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);
// 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?
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 "
// 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) {
destination->addRRset(*rrset);
}
++loaded;
+ rr_count_ += rrset->getRdataCount();
}
return (false); // Not yet, there may be more
}
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_) {
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
/// 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_;
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: