Commit b77e7ed3 authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[2209] Merge trac2208

Compiles, but tests don't pass. There's something rotten in there.

Conflicts:
	src/lib/datasrc/memory/memory_client.cc
	src/lib/datasrc/memory/memory_client.h
	src/lib/datasrc/memory/zone_table_segment_local.h
	src/lib/datasrc/tests/memory/memory_client_unittest.cc
	src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc
parents 7900248a 503a7b06
......@@ -15,7 +15,6 @@
#include <config.h>
#include <util/io/sockaddr_util.h>
#include <util/memory_segment_local.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
......@@ -74,6 +73,7 @@ using namespace isc::asiodns;
using namespace isc::asiolink;
using namespace isc::testutils;
using namespace isc::server_common::portconfig;
using isc::datasrc::memory::ZoneTableSegment;
using isc::UnitTestUtil;
using boost::scoped_ptr;
......@@ -1401,7 +1401,9 @@ public:
real_list, ThrowWhen throw_when, bool isc_exception,
ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
ConfigurableClientList(RRClass::IN()),
real_(real_list)
real_(real_list),
config_(Element::fromJSON("{}")),
ztable_segment_(ZoneTableSegment::create(*config_, RRClass::IN()))
{
BOOST_FOREACH(const DataSourceInfo& info, real_->getDataSources()) {
const isc::datasrc::DataSourceClientPtr
......@@ -1413,13 +1415,14 @@ public:
data_sources_.push_back(
DataSourceInfo(client.get(),
isc::datasrc::DataSourceClientContainerPtr(),
false, RRClass::IN(), mem_sgmt_));
false, RRClass::IN(), ztable_segment_));
}
}
private:
const boost::shared_ptr<isc::datasrc::ConfigurableClientList> real_;
const ConstElementPtr config_;
boost::shared_ptr<ZoneTableSegment> ztable_segment_;
vector<isc::datasrc::DataSourceClientPtr> clients_;
MemorySegmentLocal mem_sgmt_;
};
} // end anonymous namespace for throwing proxy classes
......
......@@ -36,6 +36,7 @@ using boost::lexical_cast;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
using isc::datasrc::memory::InMemoryClient;
using isc::datasrc::memory::ZoneTableSegment;
namespace isc {
namespace datasrc {
......@@ -43,21 +44,22 @@ namespace datasrc {
ConfigurableClientList::DataSourceInfo::DataSourceInfo(
DataSourceClient* data_src_client,
const DataSourceClientContainerPtr& container, bool has_cache,
const RRClass& rrclass, MemorySegment& mem_sgmt) :
const RRClass& rrclass, shared_ptr<ZoneTableSegment>& segment) :
data_src_client_(data_src_client),
container_(container)
{
if (has_cache) {
cache_.reset(new InMemoryClient(mem_sgmt, rrclass));
cache_.reset(new InMemoryClient(segment, rrclass));
}
}
ConfigurableClientList::DataSourceInfo::DataSourceInfo(
const RRClass& rrclass, MemorySegment& mem_sgmt, bool has_cache) :
const RRClass& rrclass, shared_ptr<ZoneTableSegment>& segment,
bool has_cache) :
data_src_client_(NULL)
{
if (has_cache) {
cache_.reset(new InMemoryClient(mem_sgmt, rrclass));
cache_.reset(new InMemoryClient(segment, rrclass));
}
}
......@@ -94,6 +96,8 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
size_t i(0); // Outside of the try to be able to access it in the catch
try {
vector<DataSourceInfo> new_data_sources;
shared_ptr<ZoneTableSegment> ztable_segment(
ZoneTableSegment::create(*config, rrclass_));
for (; i < config->size(); ++i) {
// Extract the parameters
const ConstElementPtr dconf(config->get(i));
......@@ -130,7 +134,8 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
isc_throw(ConfigurationError, "The cache must be enabled "
"for the MasterFiles type");
}
new_data_sources.push_back(DataSourceInfo(rrclass_, *mem_sgmt_,
new_data_sources.push_back(DataSourceInfo(rrclass_,
ztable_segment,
true));
} else {
// Ask the factory to create the data source for us
......@@ -139,7 +144,7 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
// And put it into the vector
new_data_sources.push_back(DataSourceInfo(ds.first, ds.second,
want_cache, rrclass_,
*mem_sgmt_));
ztable_segment));
}
if (want_cache) {
......
......@@ -21,6 +21,7 @@
#include <dns/rrclass.h>
#include <cc/data.h>
#include <exceptions/exceptions.h>
#include "memory/zone_table_segment.h"
#include <vector>
#include <boost/shared_ptr.hpp>
......@@ -332,12 +333,16 @@ public:
struct DataSourceInfo {
// Plays a role of default constructor too (for vector)
DataSourceInfo(const dns::RRClass& rrclass,
util::MemorySegment& mem_sgmt,
boost::shared_ptr
<isc::datasrc::memory::ZoneTableSegment>&
ztable_segment,
bool has_cache = false);
DataSourceInfo(DataSourceClient* data_src_client,
const DataSourceClientContainerPtr& container,
bool has_cache, const dns::RRClass& rrclass,
util::MemorySegment& mem_sgmt);
boost::shared_ptr
<isc::datasrc::memory::ZoneTableSegment>&
ztable_segment);
DataSourceClient* data_src_client_;
DataSourceClientContainerPtr container_;
......
......@@ -43,12 +43,14 @@ using namespace std;
using namespace isc::dns;
using namespace isc::dns::rdata;
using namespace isc::datasrc::memory;
using namespace isc::util;
namespace isc {
namespace datasrc {
namespace memory {
using detail::SegmentObjectHolder;
using boost::shared_ptr;
namespace { // unnamed namespace
......@@ -65,38 +67,19 @@ public:
} // end of unnamed namespace
InMemoryClient::InMemoryClient(util::MemorySegment& mem_sgmt,
InMemoryClient::InMemoryClient(shared_ptr<ZoneTableSegment> ztable_segment,
RRClass rrclass) :
// FIXME: We currently use the temporary and "unsupported"
// constructor of the zone table segment. Once we clarify
// how the config thing, we want to change it.
zone_table_segment_(ZoneTableSegment::create(mem_sgmt)),
// Use the memory segment from the zone table segment. Currently,
// it is the same one as the one in parameter, but that will
// probably change.
mem_sgmt_(zone_table_segment_->getMemorySegment()),
ztable_segment_(ztable_segment),
rrclass_(rrclass),
zone_count_(0)
{
SegmentObjectHolder<ZoneTable, RRClass> holder(
mem_sgmt_, ZoneTable::create(mem_sgmt_, rrclass), rrclass_);
file_name_tree_ = FileNameTree::create(mem_sgmt_, false);
zone_table_ = holder.release();
// TODO: Once the table is created inside the zone table segment, use that
// one.
zone_table_segment_->getHeader().setTable(zone_table_);
}
zone_count_(0),
file_name_tree_(FileNameTree::create(
ztable_segment_->getMemorySegment(), false))
{}
InMemoryClient::~InMemoryClient() {
MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
FileNameDeleter deleter;
FileNameTree::destroy(mem_sgmt_, file_name_tree_, deleter);
// TODO: Once the table is created inside the zone table segment, do not
// destroy it here.
ZoneTable::destroy(mem_sgmt_, zone_table_, rrclass_);
ZoneTableSegment::destroy(zone_table_segment_);
FileNameTree::destroy(mem_sgmt, file_name_tree_, deleter);
}
result::Result
......@@ -104,8 +87,9 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
const std::string& filename,
ZoneData* zone_data)
{
MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
SegmentObjectHolder<ZoneData, RRClass> holder(
mem_sgmt_, zone_data, rrclass_);
mem_sgmt, zone_data, rrclass_);
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEMORY_MEM_ADD_ZONE).
arg(zone_name).arg(rrclass_);
......@@ -113,7 +97,7 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
// Set the filename in file_name_tree_ now, so that getFileName()
// can use it (during zone reloading).
FileNameNode* node(NULL);
switch (file_name_tree_->insert(mem_sgmt_, zone_name, &node)) {
switch (file_name_tree_->insert(mem_sgmt, zone_name, &node)) {
case FileNameTree::SUCCESS:
case FileNameTree::ALREADYEXISTS:
// These are OK
......@@ -128,9 +112,10 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
const std::string* tstr = node->setData(new std::string(filename));
delete tstr;
const ZoneTable::AddResult result(zone_table_->addZone(mem_sgmt_, rrclass_,
zone_name,
holder.release()));
ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
const ZoneTable::AddResult result(zone_table->addZone(mem_sgmt, rrclass_,
zone_name,
holder.release()));
if (result.code == result::SUCCESS) {
// Only increment the zone count if the zone doesn't already
// exist.
......@@ -138,7 +123,7 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
}
// Destroy the old instance of the zone if there was any
if (result.zone_data != NULL) {
ZoneData::destroy(mem_sgmt_, result.zone_data, rrclass_);
ZoneData::destroy(mem_sgmt, result.zone_data, rrclass_);
}
return (result.code);
......@@ -159,7 +144,8 @@ InMemoryClient::findZone(const isc::dns::Name& zone_name) const {
LOG_DEBUG(logger, DBG_TRACE_DATA,
DATASRC_MEMORY_MEM_FIND_ZONE).arg(zone_name);
ZoneTable::FindResult result(zone_table_->findZone(zone_name));
const ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
const ZoneTable::FindResult result(zone_table->findZone(zone_name));
ZoneFinderPtr finder;
if (result.code != result::NOTFOUND) {
......@@ -171,7 +157,8 @@ InMemoryClient::findZone(const isc::dns::Name& zone_name) const {
const ZoneData*
InMemoryClient::findZoneData(const isc::dns::Name& zone_name) {
ZoneTable::FindResult result(zone_table_->findZone(zone_name));
const ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
const ZoneTable::FindResult result(zone_table->findZone(zone_name));
return (result.zone_data);
}
......@@ -182,14 +169,16 @@ InMemoryClient::load(const isc::dns::Name& zone_name,
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEMORY_MEM_LOAD).arg(zone_name).
arg(filename);
ZoneData* zone_data = loadZoneData(mem_sgmt_, rrclass_, zone_name,
MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
ZoneData* zone_data = loadZoneData(mem_sgmt, rrclass_, zone_name,
filename);
return (loadInternal(zone_name, filename, zone_data));
}
result::Result
InMemoryClient::load(const isc::dns::Name& zone_name, ZoneIterator& iterator) {
ZoneData* zone_data = loadZoneData(mem_sgmt_, rrclass_, zone_name,
MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
ZoneData* zone_data = loadZoneData(mem_sgmt, rrclass_, zone_name,
iterator);
return (loadInternal(zone_name, string(), zone_data));
}
......@@ -320,7 +309,8 @@ public:
ZoneIteratorPtr
InMemoryClient::getIterator(const Name& name, bool separate_rrs) const {
ZoneTable::FindResult result(zone_table_->findZone(name));
const ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
const ZoneTable::FindResult result(zone_table->findZone(name));
if (result.code != result::SUCCESS) {
isc_throw(DataSourceError, "No such zone: " + name.toText());
}
......
......@@ -22,6 +22,8 @@
#include <datasrc/memory/zone_table.h>
#include <datasrc/memory/zone_data.h>
#include <boost/shared_ptr.hpp>
#include <string>
namespace isc {
......@@ -62,7 +64,7 @@ public:
/// This constructor internally involves resource allocation, and if
/// it fails, a corresponding standard exception will be thrown.
/// It never throws an exception otherwise.
InMemoryClient(util::MemorySegment& mem_sgmt,
InMemoryClient(boost::shared_ptr<ZoneTableSegment> ztable_segment,
isc::dns::RRClass rrclass);
/// The destructor.
......@@ -186,7 +188,7 @@ public:
/// \todo Consider making this private and add a friend declaration
/// for the ClientList.
ZoneTableSegment& getZoneTableSegment() {
return (*zone_table_segment_);
return (*ztable_segment_);
}
private:
......@@ -200,11 +202,9 @@ private:
const std::string& filename,
ZoneData* zone_data);
ZoneTableSegment* zone_table_segment_;
util::MemorySegment& mem_sgmt_;
boost::shared_ptr<ZoneTableSegment> ztable_segment_;
const isc::dns::RRClass rrclass_;
unsigned int zone_count_;
ZoneTable* zone_table_;
FileNameTree* file_name_tree_;
};
......
......@@ -47,23 +47,22 @@ typedef boost::function<void(ZoneData*)> ZoneDataDeleterType;
}
ZoneTable*
ZoneTable::create(util::MemorySegment& mem_sgmt, RRClass zone_class) {
ZoneTable::create(util::MemorySegment& mem_sgmt, const RRClass& zone_class) {
SegmentObjectHolder<ZoneTableTree, ZoneDataDeleterType> holder(
mem_sgmt, ZoneTableTree::create(mem_sgmt),
boost::bind(deleteZoneData, &mem_sgmt, _1, zone_class));
void* p = mem_sgmt.allocate(sizeof(ZoneTable));
ZoneTable* zone_table = new(p) ZoneTable(holder.get());
ZoneTable* zone_table = new(p) ZoneTable(zone_class, holder.get());
holder.release();
return (zone_table);
}
void
ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable,
RRClass zone_class)
ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable)
{
ZoneTableTree::destroy(mem_sgmt, ztable->zones_.get(),
boost::bind(deleteZoneData, &mem_sgmt, _1,
zone_class));
ztable->rrclass_));
mem_sgmt.deallocate(ztable, sizeof(ZoneTable));
}
......
......@@ -102,7 +102,9 @@ private:
/// This constructor internally involves resource allocation, and if
/// it fails, a corresponding standard exception will be thrown.
/// It never throws an exception otherwise.
ZoneTable(ZoneTableTree* zones) : zones_(zones)
ZoneTable(const dns::RRClass& rrclass, ZoneTableTree* zones) :
rrclass_(rrclass),
zones_(zones)
{}
public:
......@@ -119,7 +121,7 @@ public:
/// \param zone_class The RR class of the zone. It must be the RR class
/// that is supposed to be associated to the zone table.
static ZoneTable* create(util::MemorySegment& mem_sgmt,
dns::RRClass zone_class);
const dns::RRClass& zone_class);
/// \brief Destruct and deallocate \c ZoneTable
///
......@@ -135,8 +137,7 @@ public:
/// \param ztable A non NULL pointer to a valid \c ZoneTable object
/// that was originally created by the \c create() method (the behavior
/// is undefined if this condition isn't met).
static void destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable,
dns::RRClass zone_class);
static void destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable);
/// Add a new zone to the \c ZoneTable.
///
......@@ -185,6 +186,7 @@ public:
FindResult findZone(const isc::dns::Name& name) const;
private:
const dns::RRClass rrclass_;
boost::interprocess::offset_ptr<ZoneTableTree> zones_;
};
}
......
......@@ -15,22 +15,20 @@
#include <datasrc/memory/zone_table_segment.h>
#include <datasrc/memory/zone_table_segment_local.h>
using namespace isc::dns;
namespace isc {
namespace datasrc {
namespace memory {
ZoneTableSegment*
ZoneTableSegment::create(const isc::data::Element&) {
ZoneTableSegment::create(const isc::data::Element&, const RRClass& rrclass) {
/// FIXME: For now, we always return ZoneTableSegmentLocal. This
/// should be updated eventually to parse the passed Element
/// argument and construct a corresponding ZoneTableSegment
/// implementation.
return (new ZoneTableSegmentLocal);
}
ZoneTableSegment*
ZoneTableSegment::create(isc::util::MemorySegment& segment) {
return (new ZoneTableSegmentLocal(segment));
return (new ZoneTableSegmentLocal(rrclass));
}
void
......
......@@ -15,6 +15,7 @@
#ifndef __ZONE_TABLE_SEGMENT_H__
#define __ZONE_TABLE_SEGMENT_H__
#include <dns/rrclass.h>
#include <datasrc/memory/zone_table.h>
#include "load_action.h"
#include <cc/data.h>
......@@ -42,38 +43,21 @@ class ZoneWriter;
/// map from domain names to zone locators) in memory.
struct ZoneTableHeader {
public:
ZoneTableHeader(ZoneTable* zone_table) :
table_(zone_table)
{}
/// \brief Returns a pointer to the underlying zone table.
ZoneTable* getTable() {
return (table.get());
return (table_.get());
}
/// \brief const version of \c getTable().
const ZoneTable* getTable() const {
return (table.get());
}
/// \brief Method to set the internal table
///
/// The interface is tentative, we don't know if this is the correct place
/// and way to set the data. But for now, we need something to be there
/// at least for the tests. So we have this. For this reason, there are
/// no tests for this method directly. Do not use in actual
/// implementation.
///
/// It can be used only once, to initially set it. It can't replace the
/// one already there.
///
/// \param table Pointer to the table to use.
/// \throw isc::Unexpected if called the second time.
void setTable(ZoneTable* table) {
if (this->table.get() != NULL) {
isc_throw(isc::Unexpected, "Replacing table");
}
this->table = table;
return (table_.get());
}
private:
boost::interprocess::offset_ptr<ZoneTable> table;
boost::interprocess::offset_ptr<ZoneTable> table_;
};
/// \brief Manages a ZoneTableHeader, an entry point into a table of
......@@ -91,7 +75,7 @@ protected:
/// An instance implementing this interface is expected to be
/// created by the factory method (\c create()), so this constructor
/// is protected.
ZoneTableSegment()
ZoneTableSegment(isc::dns::RRClass)
{}
public:
/// \brief Destructor
......@@ -119,7 +103,8 @@ public:
/// \param config The configuration based on which a derived object
/// is returned.
/// \return Returns a ZoneTableSegment object
static ZoneTableSegment* create(const isc::data::Element& config);
static ZoneTableSegment* create(const isc::data::Element& config,
const isc::dns::RRClass& rrclass);
/// \brief Temporary/Testing version of create.
///
......
......@@ -15,12 +15,23 @@
#include <datasrc/memory/zone_table_segment_local.h>
#include "zone_writer_local.h"
using namespace isc::dns;
using namespace isc::util;
namespace isc {
namespace datasrc {
namespace memory {
ZoneTableSegmentLocal::ZoneTableSegmentLocal(const RRClass& rrclass) :
ZoneTableSegment(rrclass),
header_(ZoneTable::create(mem_sgmt_, rrclass))
{
}
ZoneTableSegmentLocal::~ZoneTableSegmentLocal() {
ZoneTable::destroy(mem_sgmt_, header_.getTable());
}
// After more methods' definitions are added here, it would be a good
// idea to move getHeader() and getMemorySegment() definitions to the
// header file.
......
......@@ -37,17 +37,10 @@ protected:
/// Instances are expected to be created by the factory method
/// (\c ZoneTableSegment::create()), so this constructor is
/// protected.
ZoneTableSegmentLocal() :
mem_sgmt_(mem_sgmt_local_)
{}
// TODO: A temporary constructor, for tests for now. Needs to
// be removed.
ZoneTableSegmentLocal(isc::util::MemorySegment& segment) :
mem_sgmt_(segment)
{}
ZoneTableSegmentLocal(const isc::dns::RRClass& rrclass);
public:
/// \brief Destructor
virtual ~ZoneTableSegmentLocal() {}
virtual ~ZoneTableSegmentLocal();
/// \brief Return the ZoneTableHeader for the local zone table
/// segment implementation.
......@@ -65,9 +58,8 @@ public:
const dns::Name& origin,
const dns::RRClass& rrclass);
private:
isc::util::MemorySegmentLocal mem_sgmt_;
ZoneTableHeader header_;
isc::util::MemorySegmentLocal mem_sgmt_local_;
isc::util::MemorySegment& mem_sgmt_;
};
} // namespace memory
......
......@@ -12,13 +12,12 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <util/memory_segment_local.h>
#include <datasrc/client_list.h>
#include <datasrc/client.h>
#include <datasrc/iterator.h>
#include <datasrc/data_source.h>
#include <datasrc/memory/memory_client.h>
#include <datasrc/memory/zone_table_segment.h>
#include <datasrc/memory/zone_finder.h>
#include <datasrc/memory/zone_writer.h>
......@@ -33,6 +32,7 @@
using namespace isc::datasrc;
using isc::datasrc::memory::InMemoryClient;
using isc::datasrc::memory::ZoneTableSegment;
using isc::datasrc::memory::InMemoryZoneFinder;
using namespace isc::data;
using namespace isc::dns;
......@@ -256,7 +256,9 @@ public:
" \"type\": \"test_type\","
" \"params\": [\"example.org\", \"example.com\", "
" \"noiter.org\", \"null.org\"]"
"}]"))
"}]")),
config_(Element::fromJSON("{}")),
ztable_segment_(ZoneTableSegment::create(*config_, rrclass_))
{
for (size_t i(0); i < ds_count; ++ i) {
shared_ptr<MockDataSourceClient>
......@@ -264,7 +266,7 @@ public:
ds_.push_back(ds);
ds_info_.push_back(ConfigurableClientList::DataSourceInfo(
ds.get(), DataSourceClientContainerPtr(),
false, rrclass_, mem_sgmt_));
false, rrclass_, ztable_segment_));
}
}
......@@ -284,8 +286,8 @@ public:
// Create cache from the temporary data source, and push it to the
// client list.
const shared_ptr<InMemoryClient> cache(new InMemoryClient(mem_sgmt_,
rrclass_));
const shared_ptr<InMemoryClient> cache(
new InMemoryClient(ztable_segment_, rrclass_));
cache->load(zone, *mock_client.getIterator(zone, false));
ConfigurableClientList::DataSourceInfo& dsrc_info =
......@@ -363,12 +365,12 @@ public:
shared_ptr<InMemoryClient>());
}
const RRClass rrclass_;
isc::util::MemorySegmentLocal mem_sgmt_;
shared_ptr<TestedList> list_;
const ClientList::FindResult negative_result_;
vector<shared_ptr<MockDataSourceClient> > ds_;
vector<ConfigurableClientList::DataSourceInfo> ds_info_;
const ConstElementPtr config_elem_, config_elem_zones_;
const ConstElementPtr config_elem_, config_elem_zones_, config_;
shared_ptr<ZoneTableSegment> ztable_segment_;
};