Commit 3ebd4b03 authored by Mukund Sivaraman's avatar Mukund Sivaraman
Browse files

[2850] Add resetHeader() method

parent 299f1f5f
......@@ -262,6 +262,9 @@ public:
///
/// \throw none
virtual void clear() = 0;
/// \brief Reset the table header address.
virtual void resetHeader() = 0;
};
} // namespace memory
......
......@@ -54,6 +54,11 @@ ZoneTableSegmentLocal::clear()
"should not be used.");
}
void
ZoneTableSegmentLocal::resetHeader() {
// This method does not have to do anything in this implementation.
}
// After more methods' definitions are added here, it would be a good
// idea to move getHeader() and getMemorySegment() definitions to the
// header file.
......
......@@ -42,6 +42,9 @@ public:
/// \brief Destructor
virtual ~ZoneTableSegmentLocal();
/// \brief This method has an empty definition.
virtual void resetHeader();
/// \brief Return the ZoneTableHeader for the local zone table
/// segment implementation.
virtual ZoneTableHeader& getHeader();
......
......@@ -36,7 +36,8 @@ const char* const ZONE_TABLE_HEADER_NAME = "zone_table_header";
ZoneTableSegmentMapped::ZoneTableSegmentMapped(const RRClass& rrclass) :
ZoneTableSegment(rrclass),
rrclass_(rrclass)
rrclass_(rrclass),
cached_header_(NULL)
{
}
......@@ -283,6 +284,10 @@ ZoneTableSegmentMapped::reset(MemorySegmentOpenMode mode,
current_filename_ = filename;
current_mode_ = mode;
mem_sgmt_.reset(segment.release());
// Given what we setup above, resetHeader() must not throw at this
// point. If it does, all bets are off.
resetHeader();
}
void
......@@ -314,12 +319,15 @@ ZoneTableSegmentMapped::clear() {
}
}
template<typename T>
T*
ZoneTableSegmentMapped::getHeaderHelper() const {
void
ZoneTableSegmentMapped::resetHeader() {
// We cannot perform resetHeader() lazily during getHeader() as
// getHeader() has to work on const objects too. So we do it here
// now.
if (!mem_sgmt_) {
isc_throw(isc::InvalidOperation,
"getHeader() called without calling reset() first");
"resetHeader() called without calling reset() first");
}
const MemorySegment::NamedAddressResult result =
......@@ -330,7 +338,19 @@ ZoneTableSegmentMapped::getHeaderHelper() const {
"getHeader()");
}
return (static_cast<T*>(result.second));
cached_header_ = static_cast<ZoneTableHeader*>(result.second);
}
template<typename T>
T*
ZoneTableSegmentMapped::getHeaderHelper() const {
if (!mem_sgmt_) {
isc_throw(isc::InvalidOperation,
"getHeader() called without calling reset() first");
}
assert(cached_header_);
return (cached_header_);
}
ZoneTableHeader&
......
......@@ -46,6 +46,10 @@ public:
/// \brief Destructor
virtual ~ZoneTableSegmentMapped();
/// \brief Reset the table header address from the named address in
/// the mapped file.
virtual void resetHeader();
/// \brief Return the ZoneTableHeader for the mapped zone table
/// segment implementation.
///
......@@ -128,6 +132,7 @@ private:
// Internally holds a MemorySegmentMapped. This is NULL on
// construction, and is set by the \c reset() method.
boost::scoped_ptr<isc::util::MemorySegmentMapped> mem_sgmt_;
ZoneTableHeader* cached_header_;
};
} // namespace memory
......
......@@ -59,6 +59,8 @@ ZoneWriter::load() {
isc_throw(isc::InvalidOperation, "No data returned from load action");
}
segment_.resetHeader();
state_ = ZW_LOADED;
}
......@@ -78,6 +80,8 @@ ZoneWriter::install() {
state_ = ZW_INSTALLED;
zone_data_ = result.zone_data;
segment_.resetHeader();
}
void
......
......@@ -454,4 +454,36 @@ TEST_F(ZoneTableSegmentMappedTest, resetFailedMissingHeader) {
}, ResetFailed);
}
TEST_F(ZoneTableSegmentMappedTest, resetHeaderUninitialized) {
// This should throw as we haven't called reset() yet.
EXPECT_THROW(ztable_segment_->resetHeader(), isc::InvalidOperation);
}
TEST_F(ZoneTableSegmentMappedTest, resetHeader) {
// First, open an underlying mapped file in read+write mode (doesn't
// exist yet)
ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
// Check if a valid ZoneTable is found.
{
const ZoneTableHeader& header = ztable_segment_->getHeader();
const ZoneTable* table = header.getTable();
EXPECT_EQ(0, table->getZoneCount());
}
// Grow the segment by allocating something large.
EXPECT_THROW(ztable_segment_->getMemorySegment().allocate(1<<16),
MemorySegmentGrown);
// Reset the header address. This should not throw now.
EXPECT_NO_THROW(ztable_segment_->resetHeader());
// Check if a valid ZoneTable is found.
{
const ZoneTableHeader& header = ztable_segment_->getHeader();
const ZoneTable* table = header.getTable();
EXPECT_EQ(0, table->getZoneCount());
}
}
} // anonymous namespace
......@@ -49,6 +49,11 @@ public:
isc_throw(isc::NotImplemented, "clear() is not implemented");
}
virtual void resetHeader() {
// This method does not have to do anything in this
// implementation.
}
virtual ZoneTableHeader& getHeader() {
return (header_);
}
......
......@@ -85,6 +85,19 @@ TEST_F(ZoneTableSegmentTest, getHeader) {
// const version.
testGetHeader<const ZoneTableSegment, const ZoneTableHeader,
const ZoneTable>(ztable_segment_);
// This is a nop for local segments.
ztable_segment_->resetHeader();
// The following still behave as before after resetHeader().
// non-const version.
testGetHeader<ZoneTableSegment, ZoneTableHeader, ZoneTable>
(ztable_segment_);
// const version.
testGetHeader<const ZoneTableSegment, const ZoneTableHeader,
const ZoneTable>(ztable_segment_);
}
TEST_F(ZoneTableSegmentTest, getMemorySegment) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment