Commit 18619517 authored by Mukund Sivaraman's avatar Mukund Sivaraman
Browse files

[2850] Add the ZoneTableSegment::clear() method

parent 6548cfed
......@@ -197,6 +197,15 @@ public:
/// config (see the description).
virtual void reset(MemorySegmentOpenMode mode,
isc::data::ConstElementPtr params) = 0;
/// \brief Unload the current memory store (if loaded).
///
/// Implementations of this method should unload any current memory
/// store and reset the `ZoneTableSegment` to a freshly constructed
/// state.
///
/// \throw none
virtual void clear() = 0;
};
} // namespace memory
......
......@@ -46,6 +46,14 @@ ZoneTableSegmentLocal::reset(MemorySegmentOpenMode,
"should not be used.");
}
void
ZoneTableSegmentLocal::clear()
{
isc_throw(isc::NotImplemented,
"ZoneTableSegmentLocal::clear() is not implemented and "
"should not be used.");
}
// After more methods' definitions are added here, it would be a good
// idea to move getHeader() and getMemorySegment() definitions to the
// header file.
......
......@@ -67,6 +67,11 @@ public:
virtual void reset(MemorySegmentOpenMode mode,
isc::data::ConstElementPtr params);
/// \brief This method is not implemented.
///
/// \throw isc::NotImplemented
virtual void clear();
private:
isc::util::MemorySegmentLocal mem_sgmt_;
ZoneTableHeader header_;
......
......@@ -165,28 +165,7 @@ void
ZoneTableSegmentMapped::reset(MemorySegmentOpenMode mode,
isc::data::ConstElementPtr params)
{
if (mem_sgmt_) {
if (isWritable()) {
// If there is a previously opened segment, and it was
// opened in read-write mode, update its checksum.
mem_sgmt_->shrinkToFit();
const MemorySegment::NamedAddressResult result =
mem_sgmt_->getNamedAddress(ZONE_TABLE_CHECKSUM_NAME);
assert(result.first);
assert(result.second);
uint32_t* checksum = static_cast<uint32_t*>(result.second);
// First, clear the checksum so that getCheckSum() returns
// a consistent value.
*checksum = 0;
const uint32_t new_checksum = mem_sgmt_->getCheckSum();
// Now, update it into place.
*checksum = new_checksum;
}
// Close the segment here in case the code further below
// doesn't complete successfully.
header_ = NULL;
mem_sgmt_.reset();
}
clear();
if (!params || params->getType() != Element::map) {
isc_throw(isc::InvalidParameter,
......@@ -222,6 +201,33 @@ ZoneTableSegmentMapped::reset(MemorySegmentOpenMode mode,
current_mode_ = mode;
}
void
ZoneTableSegmentMapped::clear()
{
if (mem_sgmt_) {
if (isWritable()) {
// If there is a previously opened segment, and it was
// opened in read-write mode, update its checksum.
mem_sgmt_->shrinkToFit();
const MemorySegment::NamedAddressResult result =
mem_sgmt_->getNamedAddress(ZONE_TABLE_CHECKSUM_NAME);
assert(result.first);
assert(result.second);
uint32_t* checksum = static_cast<uint32_t*>(result.second);
// First, clear the checksum so that getCheckSum() returns
// a consistent value.
*checksum = 0;
const uint32_t new_checksum = mem_sgmt_->getCheckSum();
// Now, update it into place.
*checksum = new_checksum;
}
// Close the segment here in case the code further below
// doesn't complete successfully.
header_ = NULL;
mem_sgmt_.reset();
}
}
// After more methods' definitions are added here, it would be a good
// idea to move getHeader() and getMemorySegment() definitions to the
// header file.
......
......@@ -97,6 +97,9 @@ public:
virtual void reset(MemorySegmentOpenMode mode,
isc::data::ConstElementPtr params);
/// \brief Unmap the current file (if mapped).
virtual void clear();
private:
void processChecksum(isc::util::MemorySegmentMapped& segment, bool create);
void processHeader(isc::util::MemorySegmentMapped& segment, bool create);
......
......@@ -171,4 +171,23 @@ TEST_F(ZoneTableSegmentMappedTest, reset) {
EXPECT_TRUE(ztable_segment_->isWritable());
}
TEST_F(ZoneTableSegmentMappedTest, clear) {
// First, load an underlying mapped file
ztable_segment_->reset(ZoneTableSegment::READ_WRITE,
config_params_);
EXPECT_TRUE(ztable_segment_->isWritable());
// The following method calls should no longer throw:
EXPECT_NO_THROW(ztable_segment_->getHeader());
EXPECT_NO_THROW(ztable_segment_->getMemorySegment());
// Now, clear the segment.
ztable_segment_->clear();
EXPECT_FALSE(ztable_segment_->isWritable());
// The following method calls should now throw.
EXPECT_THROW(ztable_segment_->getHeader(), isc::InvalidOperation);
EXPECT_THROW(ztable_segment_->getMemorySegment(), isc::InvalidOperation);
}
} // anonymous namespace
......@@ -42,7 +42,11 @@ public:
}
virtual void reset(MemorySegmentOpenMode, isc::data::ConstElementPtr) {
// This method doesn't do anything.
isc_throw(isc::NotImplemented, "reset() is not implemented");
}
virtual void clear() {
isc_throw(isc::NotImplemented, "clear() is not implemented");
}
virtual ZoneTableHeader& getHeader() {
......
......@@ -60,6 +60,12 @@ TEST_F(ZoneTableSegmentTest, reset) {
}, isc::NotImplemented);
}
TEST_F(ZoneTableSegmentTest, clear) {
// clear() should throw that it's not implemented so that any
// accidental calls are found out.
EXPECT_THROW(ztable_segment_->clear(), isc::NotImplemented);
}
// Helper function to check const and non-const methods.
template <typename TS, typename TH, typename TT>
void
......
Markdown is supported
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