|
@@ -12,14 +12,12 @@
|
|
|
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
// PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
|
-// Note: map and utility (for 'pair') are for temporary workaround.
|
|
|
-// we'll soon replace them with built-in intelligent backend structure.
|
|
|
-#include <map>
|
|
|
-#include <utility>
|
|
|
+#include <cassert>
|
|
|
|
|
|
#include <dns/name.h>
|
|
|
|
|
|
#include <datasrc/zonetable.h>
|
|
|
+#include <datasrc/rbtree.h>
|
|
|
|
|
|
using namespace std;
|
|
|
using namespace isc::dns;
|
|
@@ -27,13 +25,77 @@ using namespace isc::dns;
|
|
|
namespace isc {
|
|
|
namespace datasrc {
|
|
|
|
|
|
-// This is a temporary, inefficient implementation using std::map and handmade
|
|
|
-// iteration to realize longest match.
|
|
|
-
|
|
|
+/// \short Private data and implementation of ZoneTable
|
|
|
struct ZoneTable::ZoneTableImpl {
|
|
|
- typedef map<Name, ZonePtr> ZoneMap;
|
|
|
- typedef pair<Name, ZonePtr> NameAndZone;
|
|
|
- ZoneMap zones;
|
|
|
+ // Type aliases to make it shorter
|
|
|
+ typedef RBTree<Zone> ZoneTree;
|
|
|
+ typedef RBNode<Zone> ZoneNode;
|
|
|
+ // The actual storage
|
|
|
+ ZoneTree zones_;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The implementation methods are here and just wrap-called in the
|
|
|
+ * ZoneTable. We have variables locally (without impl_->), have
|
|
|
+ * type aliases, etc. And they will get inlined anyway.
|
|
|
+ */
|
|
|
+
|
|
|
+ // Implementation of ZoneTable::addZone
|
|
|
+ result::Result addZone(ZonePtr zone) {
|
|
|
+ // Sanity check
|
|
|
+ if (!zone) {
|
|
|
+ isc_throw(InvalidParameter,
|
|
|
+ "Null pointer is passed to ZoneTable::addZone()");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the node where we put the zone
|
|
|
+ ZoneNode* node(NULL);
|
|
|
+ switch (zones_.insert(zone->getOrigin(), &node)) {
|
|
|
+ // This is OK
|
|
|
+ case ZoneTree::SUCCEED:
|
|
|
+ case ZoneTree::ALREADYEXIST:
|
|
|
+ break;
|
|
|
+ // Can Not Happen
|
|
|
+ default:
|
|
|
+ assert(0);
|
|
|
+ }
|
|
|
+ // Can Not Happen
|
|
|
+ assert(node);
|
|
|
+
|
|
|
+ // Is it empty? We either just created it or it might be nonterminal
|
|
|
+ if (node->isEmpty()) {
|
|
|
+ node->setData(zone);
|
|
|
+ return (result::SUCCESS);
|
|
|
+ } else { // There's something there already
|
|
|
+ return (result::EXIST);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Implementation of ZoneTable::findZone
|
|
|
+ ZoneTable::FindResult findZone(const Name& name) const {
|
|
|
+ ZoneNode *node(NULL);
|
|
|
+ result::Result my_result;
|
|
|
+
|
|
|
+ // Translate the return codes
|
|
|
+ switch (zones_.find(name, &node)) {
|
|
|
+ case ZoneTree::EXACTMATCH:
|
|
|
+ my_result = result::SUCCESS;
|
|
|
+ break;
|
|
|
+ case ZoneTree::PARTIALMATCH:
|
|
|
+ my_result = result::PARTIALMATCH;
|
|
|
+ break;
|
|
|
+ // We have no data there, so translate the pointer to NULL as well
|
|
|
+ case ZoneTree::NOTFOUND:
|
|
|
+ return (FindResult(result::NOTFOUND, ConstZonePtr()));
|
|
|
+ // Can Not Happen
|
|
|
+ default:
|
|
|
+ assert(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Can Not Happen (remember, NOTFOUND is handled)
|
|
|
+ assert(node);
|
|
|
+
|
|
|
+ return (FindResult(my_result, node->getData()));
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
ZoneTable::ZoneTable() : impl_(new ZoneTableImpl)
|
|
@@ -45,40 +107,19 @@ ZoneTable::~ZoneTable() {
|
|
|
|
|
|
result::Result
|
|
|
ZoneTable::addZone(ZonePtr zone) {
|
|
|
- if (!zone) {
|
|
|
- isc_throw(InvalidParameter,
|
|
|
- "Null pointer is passed to ZoneTable::addZone()");
|
|
|
- }
|
|
|
-
|
|
|
- if (impl_->zones.insert(
|
|
|
- ZoneTableImpl::NameAndZone(zone->getOrigin(), zone)).second
|
|
|
- == true) {
|
|
|
- return (result::SUCCESS);
|
|
|
- } else {
|
|
|
- return (result::EXIST);
|
|
|
- }
|
|
|
+ return (impl_->addZone(zone));
|
|
|
}
|
|
|
|
|
|
result::Result
|
|
|
-ZoneTable::removeZone(const Name& origin) {
|
|
|
- return (impl_->zones.erase(origin) == 1 ? result::SUCCESS :
|
|
|
- result::NOTFOUND);
|
|
|
+ZoneTable::removeZone(const Name&) {
|
|
|
+ // TODO Implement
|
|
|
+ assert(0);
|
|
|
}
|
|
|
|
|
|
ZoneTable::FindResult
|
|
|
ZoneTable::findZone(const Name& name) const {
|
|
|
- // Inefficient internal loop to find a longest match.
|
|
|
- // This will be replaced with a single call to more intelligent backend.
|
|
|
- for (int i = 0; i < name.getLabelCount(); ++i) {
|
|
|
- Name matchname(name.split(i));
|
|
|
- ZoneTableImpl::ZoneMap::const_iterator found =
|
|
|
- impl_->zones.find(matchname);
|
|
|
- if (found != impl_->zones.end()) {
|
|
|
- return (FindResult(i == 0 ? result::SUCCESS :
|
|
|
- result::PARTIALMATCH, (*found).second));
|
|
|
- }
|
|
|
- }
|
|
|
- return (FindResult(result::NOTFOUND, ConstZonePtr()));
|
|
|
+ return (impl_->findZone(name));
|
|
|
}
|
|
|
+
|
|
|
} // end of namespace datasrc
|
|
|
} // end of namespace isc
|