Commit c6b91c2e authored by Michal Vaner's avatar Michal Vaner
Browse files

Simplify load without help class

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac451@4039 e5f2f494-b856-4b98-b285-d166d9295462
parent 40d5e80d
......@@ -67,7 +67,8 @@ struct MemoryZone::MemoryZoneImpl {
* access is without the impl_-> and it will get inlined anyway.
*/
// Implementation of MemoryZone::add
result::Result add(const ConstRRsetPtr& rrset) {
result::Result add(const ConstRRsetPtr& rrset, DomainTree* domains)
{
// Sanitize input
if (!rrset) {
isc_throw(NullRRset, "The rrset provided is NULL");
......@@ -82,7 +83,7 @@ struct MemoryZone::MemoryZoneImpl {
}
// Get the node
DomainNode* node;
switch (domains_.insert(name, &node)) {
switch (domains->insert(name, &node)) {
// Just check it returns reasonable results
case DomainTree::SUCCEED:
case DomainTree::ALREADYEXIST:
......@@ -113,6 +114,22 @@ struct MemoryZone::MemoryZoneImpl {
}
}
/*
* Same as above, but it checks the return value and if it already exists,
* it throws.
*/
void addFromLoad(const ConstRRsetPtr& set, DomainTree* domains) {
switch (add(set, domains)) {
case result::EXIST:
isc_throw(dns::MasterLoadError, "Duplicate rrset: " <<
set->toText());
case result::SUCCESS:
return;
default:
assert(0);
}
}
// Implementation of MemoryZone::find
FindResult find(const Name& name, RRType type) const {
// Get the node
......@@ -146,65 +163,6 @@ struct MemoryZone::MemoryZoneImpl {
return (FindResult(NXRRSET, ConstRRsetPtr()));
}
}
/*
* Help class used to load data from masterfile. The real work
* is done in the load method. We need this to be exception safe -
* we store the old content and in case of exception we need to
* put it back. But C++ does not have any way of catching everything
* and being able to throw it again and does not have a finally
* keywoard, so we emulate one by a destructor.
*
* When we finish the loading sucessfully, we mark that the destructor
* should not put back the original data.
*/
struct Load {
// Takes the original data out and preserves it for a while
Load(MemoryZone* zone) :
zone_(zone),
swap_(true)
{
tmp_tree_.swap(zone_->impl_->domains_);
}
~ Load() {
/*
* Emulate the finally - if we should put original back (loading
* didn't finish sucessfully), we swap the not-completely-loaded
* one with the stored.
*/
if (swap_) {
tmp_tree_.swap(zone_->impl_->domains_);
}
}
// The actual loading function
void load(const string &filename) {
masterLoad(filename.c_str(), zone_->getOrigin(), zone_->getClass(),
boost::bind(&Load::add, this, _1));
// Everything OK, so don't put the original back
swap_ = false;
}
// Add one rrset there
void add(RRsetPtr set) {
switch (zone_->add(set)) {
case result::EXIST:
isc_throw(dns::MasterLoadError, "Duplicate rrset: " <<
set->toText());
case result::SUCCESS:
return;
default:
isc_throw(AssertError,
"Unexpected result of MemoryZone::add");
}
}
// State while loading in progress
// Just the zone where we put the data
MemoryZone *zone_;
// Preserved original of the zone
DomainTree tmp_tree_;
// Should we restore the original if we end now?
bool swap_;
};
};
MemoryZone::MemoryZone(const RRClass& zone_class, const Name& origin) :
......@@ -233,15 +191,19 @@ MemoryZone::find(const Name& name, const RRType& type) const {
result::Result
MemoryZone::add(const ConstRRsetPtr& rrset) {
return (impl_->add(rrset));
return (impl_->add(rrset, &impl_->domains_));
}
void
MemoryZone::load(const string& filename) {
// This uses a class to emulate finally. See comment near it.
MemoryZoneImpl::Load load(this);
load.load(filename);
// Load it into a temporary tree
MemoryZoneImpl::DomainTree tmp;
masterLoad(filename.c_str(), getOrigin(), getClass(),
boost::bind(&MemoryZoneImpl::addFromLoad, impl_, _1, &tmp));
// If it went well, put it inside
tmp.swap(impl_->domains_);
// And let the old data die with tmp
}
/// Implementation details for \c MemoryDataSrc hidden from the public
......
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