rbtdb.c revision 82d05588933a3c765aa8518fe455d6477d640b99
/*
* Copyright (C) 1999 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <stddef.h>
#include <string.h>
#include <isc/assertions.h>
#include <dns/rdataslab.h>
#include "rbtdb.h"
typedef struct rdatasetheader {
/*
* We don't use the LIST macros, because the LIST structure has
* both head and tail pointers. We only have a head pointer in
* the node to save space.
*/
unsigned int version;
struct rdatasetheader *prev;
struct rdatasetheader *next;
typedef struct {
unsigned int references;
} node_lock;
typedef struct {
/* Unlocked */
unsigned int node_lock_count;
/* Locked by lock */
unsigned int references;
/* Locked by tree_lock */
} dns_rbtdb_t;
static dns_rdatasetmethods_t rdataset_methods = {
next,
};
/*
* DB Routines
*/
static void
rbtdb->references++;
}
static void
unsigned int i;
isc_region_t r;
for (i = 0; i < rbtdb->node_lock_count; i++)
}
static void
unsigned int i;
/* XXX check for open versions here */
/*
* Even though there are no external direct references, there still
* may be nodes in use.
*/
for (i = 0; i < rbtdb->node_lock_count; i++) {
}
if (want_free)
}
static void
rbtdb->references--;
if (rbtdb->references == 0)
if (maybe_free)
}
static void
}
static void
}
static dns_result_t
return (DNS_R_NOTIMPLEMENTED);
}
static void
}
static dns_result_t
dns_dbnode_t **nodep) {
unsigned int locknum;
if (node->references == 0)
node->references++;
} else {
if (!create)
return (DNS_R_NOTFOUND);
/*
* It would be nice to try to upgrade the lock instead of
* unlocking then relocking.
*/
return (result);
}
goto again;
}
return (DNS_R_SUCCESS);
}
static void
node->references++;
}
static void
node->references--;
if (node->references == 0) {
/* XXX other detach stuff here */
}
}
static dns_result_t
{
unsigned char *raw;
unsigned int count;
(void)version;
/* XXX version */
break;
}
rbtnode->references++;
raw += 2;
if (count == 0) {
} else {
/*
* The private4 field is the number of rdata beyond
* the cursor position, so we decrement the total
* count by one before storing it.
*/
count--;
}
}
return (DNS_R_NOTFOUND);
return (DNS_R_SUCCESS);
}
static dns_result_t
{
(void)version;
(void)mode;
®ion,
sizeof (rdatasetheader_t));
if (result != DNS_R_SUCCESS)
return (result);
return (DNS_R_SUCCESS);
}
static dns_result_t
type = 0;
return (DNS_R_NOTIMPLEMENTED);
}
static dns_result_t
{
/*
* This routine does no node locking. See comments in
* 'load' below for more information on loading and
* locking.
*/
return (result);
/*
* The following is basically addrdataset(), with no locking.
*/
®ion,
sizeof (rdatasetheader_t));
if (result != DNS_R_SUCCESS)
return (result);
return (DNS_R_SUCCESS);
}
static dns_result_t
/*
* XXX
*
* For now, there is no locking, since database
* loading is assumed to occur before parallel
* access. Clearly the database should be empty
* before trying to load it. Probably need some
* kind of "loaded" flag so we can
*
* REQUIRE(!rbtdb->loaded);
*/
}
static void
unsigned int size;
sizeof (rdatasetheader_t));
}
}
static dns_dbmethods_t methods = {
load,
};
{
int i;
(void)argc;
(void)argv;
return (DNS_R_NOMEMORY);
if (iresult != ISC_R_SUCCESS) {
"isc_mutex_init() failed: %s",
return (DNS_R_UNEXPECTED);
}
if (iresult != ISC_R_SUCCESS) {
"isc_rwlock_init() failed: %s",
return (DNS_R_UNEXPECTED);
}
if (rbtdb->node_lock_count == 0)
sizeof (node_lock));
for (i = 0; i < (int)(rbtdb->node_lock_count); i++) {
if (iresult != ISC_R_SUCCESS) {
i--;
while (i >= 0) {
i--;
}
sizeof (node_lock));
"isc_mutex_init() failed: %s",
return (DNS_R_UNEXPECTED);
}
}
/*
* Make a copy of the base name.
*/
return (DNS_R_NOMEMORY);
}
/*
* Make the Red-Black Tree.
*/
if (dresult != DNS_R_SUCCESS) {
return (dresult);
}
/* XXX Version init here */
return (ISC_R_SUCCESS);
}
/*
* Slabbed Rdataset Methods
*/
static dns_result_t
return (DNS_R_SUCCESS);
}
static dns_result_t
unsigned int count;
if (count == 0) {
return (DNS_R_NOMORE);
}
raw += 2;
/*
* The private4 field is the number of rdata beyond the cursor
* position, so we decrement the total count by one before storing
* it.
*/
count--;
return (DNS_R_SUCCESS);
}
static dns_result_t
unsigned int count;
unsigned int length;
unsigned char *raw;
if (count == 0)
return (DNS_R_NOMORE);
count--;
return (DNS_R_SUCCESS);
}
static void
isc_region_t r;
raw += 2;
}