struct file_header {
char version1[32];
isc_uint64_t first_node_offset; /* usually 1024 */
- /*
+ /*
* information about the system on which the fast file was generated
* will be used to tell if we can load the fast file or not
*/
* step one: write out a zeroed header of 1024 bytes
* step two: walk the tree in a depth-first, left-right-down order, writing
* out the nodes, reserving space as we go, correcting addresses to point
- * at the proper offset in the file, and setting a flag for each pointer to
- * indicate that it is a reference to a location in the file, rather than in
+ * at the proper offset in the file, and setting a flag for each pointer to
+ * indicate that it is a reference to a location in the file, rather than in
* memory.
- * step three: write out the header, adding the information that will be
+ * step three: write out the header, adding the information that will be
* needed to re-create the tree object itself.
*
* The RBTDB object will do this three times, once for each of the three
dns_rbtdatawriter_t datawriter, isc_uint32_t serial,
isc_uint64_t *where);
/*
- * The following functions allow you to get the actual address of a pointer
- * without having to use an if statement to check to see if that address is
+ * The following functions allow you to get the actual address of a pointer
+ * without having to use an if statement to check to see if that address is
* relative or not
*/
static inline dns_rbtnode_t *
getparent(dns_rbtnode_t *node, file_header_t *header) {
char *adjusted_address = (char *)(node->parent);
adjusted_address += node->parent_is_relative * (isc_uint64_t)header;
-
+
return ((dns_rbtnode_t *)adjusted_address);
}
getleft(dns_rbtnode_t *node, file_header_t *header) {
char *adjusted_address = (char *)(node->left);
adjusted_address += node->left_is_relative * (isc_uint64_t)header;
-
+
return ((dns_rbtnode_t *)adjusted_address);
}
getright(dns_rbtnode_t *node, file_header_t *header) {
char *adjusted_address = (char *)(node->right);
adjusted_address += node->right_is_relative * (isc_uint64_t)header;
-
+
return ((dns_rbtnode_t *)adjusted_address);
}
getdown(dns_rbtnode_t *node, file_header_t *header) {
char *adjusted_address = (char *)(node->down);
adjusted_address += node->down_is_relative * (isc_uint64_t)header;
-
+
return ((dns_rbtnode_t *)adjusted_address);
}
getdata(dns_rbtnode_t *node, file_header_t *header) {
char *adjusted_address = (char *)(node->data);
adjusted_address += node->data_is_relative * (isc_uint64_t)header;
-
+
return ((dns_rbtnode_t *)adjusted_address);
}
*/
char buffer[HEADER_LENGTH];
isc_result_t result;
-
+
memset(buffer, 0, HEADER_LENGTH);
result = isc_stdio_write(buffer, 1, HEADER_LENGTH, file, NULL);
if (result != ISC_R_SUCCESS)
result = fflush(file);
if (result != ISC_R_SUCCESS)
return (result);
-
+
return (ISC_R_SUCCESS);
}
* Any information stored in the rbt object itself should be stored
* here.
*/
-static isc_result_t
+static isc_result_t
write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset) {
file_header_t header;
isc_result_t result;
-
+
if (FILE_VERSION[0] == '\0') {
memset(FILE_VERSION, 0, sizeof(FILE_VERSION));
snprintf(FILE_VERSION, sizeof(FILE_VERSION),
header.first_node_offset = first_node_offset;
header.ptrsize = (isc_uint32_t) sizeof(void *);
header.bigendian = (1 == htonl(1)) ? 1 : 0;
-
+
#ifdef DNS_RDATASET_FIXED
header.rdataset_fixed = 1;
#else
header.rdataset_fixed = 0;
-#endif
-
+#endif
+
header.nodecount = rbt->nodecount;
CHECK(isc_stdio_seek(file, dns_rbt_serialize_align(ftell(file)),
SEEK_SET));
CHECK(isc_stdio_write(&header, 1, sizeof(file_header_t), file, NULL));
CHECK(fflush(file));
-
+
/* Ensure we are always at the end of the file. */
CHECK(isc_stdio_seek(file, 0, SEEK_END));
return (result);
}
-static isc_result_t
-serialize_node(FILE *file, dns_rbtnode_t *node, isc_uint64_t left,
+static isc_result_t
+serialize_node(FILE *file, dns_rbtnode_t *node, isc_uint64_t left,
isc_uint64_t right, isc_uint64_t down,
isc_uint64_t parent, isc_uint64_t data)
{
temp_node.parent_is_relative = 0;
temp_node.data_is_relative = 0;
temp_node.is_mmapped = 1;
-
+
/*
* If the next node is not NULL, calculate the next node's location
* in the file. Note that this will have to change when the data
isc_uint64_t this_node_location = 0;
isc_uint64_t offset_adjust;
isc_result_t result;
-
+
if (node == NULL) {
if (where != NULL)
*where = 0;
offset_adjust = dns_rbt_serialize_align(this_node_location +
NODE_SIZE(node));
CHECK(isc_stdio_seek(file, offset_adjust, SEEK_SET));
-
+
/* Serialize the rest of the tree */
CHECK(serialize_nodes(file, getleft(node, NULL), this_node_location,
datawriter, serial, &left));
if (node->data != NULL) {
CHECK(isc_stdio_seek(file, dns_rbt_serialize_align(ftell(file)),
- SEEK_SET));
+ SEEK_SET));
data = ftell(file);
datawriter(file, node->data, serial);
}
-
+
/* Seek back to reserved space */
CHECK(isc_stdio_seek(file, this_node_location, SEEK_SET));
return (target + 8 - offset);
}
-isc_result_t
-dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
+isc_result_t
+dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
dns_rbtdatawriter_t datawriter,
isc_uint32_t serial, isc_uint64_t *offset)
{
long header_position, node_position, end_position;
REQUIRE(file != NULL);
-
+
CHECK(isc_file_isplainfilefd(fileno(file)));
header_position = ftell(file);
node_position = ftell(file);
CHECK(serialize_nodes(file, rbt->root, 0, datawriter, serial, NULL));
end_position = ftell(file);
-
+
if (node_position == end_position) {
CHECK(isc_stdio_seek(file, header_position, SEEK_SET));
*offset = 0;
return (ISC_R_SUCCESS);
}
-
+
/* Serialize header */
CHECK(isc_stdio_seek(file, header_position, SEEK_SET));
CHECK(write_header(file, rbt, HEADER_LENGTH));
INSIST(result == ISC_R_SUCCESS);
/* XXX: we need to catch errors better than this */
}
-
+
INSIST(!n->parent_is_relative || n->parent != NULL);
INSIST(!n->right_is_relative || n->right != NULL);
INSIST(!n->left_is_relative || n->left != NULL);
n->data = getdata(n, rbt->mmap_location);
n->data_is_relative = 0;
-
+
hash_node(rbt, n, fullname);
-
+
if (data_fixer != NULL && n->data != NULL)
data_fixer(n);
-
+
if (n->right != NULL)
treefix(rbt, n->right, name, data_fixer);
if (n->left != NULL)
treefix(rbt, n->down, fullname, data_fixer);
}
-isc_result_t
+isc_result_t
dns_rbt_deserialize_tree(void *base_address, off_t header_offset,
isc_mem_t *mctx,
void (*deleter)(void *, void *),
file_header_t *header;
REQUIRE(originp == NULL || *originp == NULL);
-
+
result = dns_rbt_create(mctx, deleter, deleter_arg, rbtp);
if (result != ISC_R_SUCCESS)
return (result);
(*rbtp)->mmap_location = base_address;
header = (file_header_t *)((char *)base_address + header_offset);
-
+
#ifdef DNS_RDATASET_FIXED
if (header->rdataset_fixed != 1) {
return (ISC_R_INVALIDFILE);
}
-
+
#else
if (header->rdataset_fixed != 0) {
return (ISC_R_INVALIDFILE);
if (header->bigendian != (1 == htonl(1)) ? 1 : 0) {
return (ISC_R_INVALIDFILE);
}
-
+
/* Copy other data items from the header into our rbt. */
(*rbtp)->root = (dns_rbtnode_t *)((char *)base_address +
header_offset + header->first_node_offset);
return (ISC_R_QUOTA);
INSIST(rbt->nodecount == 0);
-
+
rbt->mmap_location = NULL;
if (rbt->hashtable != NULL)
node->magic = 0;
#endif
dns_rbtnode_refdestroy(node);
-
+
freenode(rbt, &node);
/*
node->right_is_relative = 0;
node->parent_is_relative = 0;
node->data_is_relative = 0;
-
+
#ifdef DNS_RBT_USEHASH
HASHNEXT(node) = NULL;
HASHVAL(node) = 0;
static void
freenode(dns_rbt_t *rbt, dns_rbtnode_t **nodep) {
dns_rbtnode_t *node = *nodep;
-
+
if (node->is_mmapped == 0) {
isc_mem_put(rbt->mctx, node, NODE_SIZE(node));
}
*nodep = NULL;
-
+
rbt->nodecount--;
}
DOWN(parent) = RIGHT(node);
} else
parent = RIGHT(node);
-
+
freenode(rbt, &node);
-
+
node = parent;
if (quantum != 0 && --quantum == 0) {
*nodep = node;
printf("Node info for nodename: ");
printnodename(n);
printf("\n");
-
+
printf("n = %p\n", n);
- printf("Relative pointers: %s%s%s%s%s\n",
+ printf("Relative pointers: %s%s%s%s%s\n",
(n->parent_is_relative == 1 ? " P" : ""),
(n->right_is_relative == 1 ? " R" : ""),
(n->left_is_relative == 1 ? " L" : ""),
}
printf(")");
-
+
if (root->data != NULL && data_printer != NULL) {
printf(" data@%p: ", root->data);
data_printer(stdout, root->data);
*/
isc_mem_t * hmctx;
isc_heap_t **heaps;
-
+
/*
* Base values for the mmap() code.
*/
rbtdb->common.impmagic = 0;
ondest = rbtdb->common.ondest;
isc_mem_detach(&rbtdb->hmctx);
-
+
if (rbtdb->mmap_location != NULL)
munmap(rbtdb->mmap_location, rbtdb->mmap_size);
-
+
isc_mem_putanddetach(&rbtdb->common.mctx, rbtdb, sizeof(*rbtdb));
isc_ondestroy_notify(&ondest, rbtdb);
}
free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset) {
unsigned int size;
int idx;
-
+
if (EXISTS(rdataset) &&
(rdataset->attributes & RDATASET_ATTR_STATCOUNT) != 0) {
update_rrsetstats(rbtdb, rdataset, ISC_FALSE);
}
serial = rbtversion->serial;
now = 0;
-
+
NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
isc_rwlocktype_read);
char *base;
dns_rbt_t *temporary_rbt = NULL;
int protect, flags;
-
+
REQUIRE(VALID_RBTDB(rbtdb));
-
+
/*
* TODO CKB: since this is read-write (had to be to add nodes later)
* we will need to lock the file or the nodes in it before modifying
#ifdef MAP_FILE
flags |= MAP_FILE;
#endif
-
+
base = mmap(NULL, filesize, protect, flags, fd, 0);
if (base == NULL || base == MAP_FAILED)
return (ISC_R_FAILURE);
rbtdb->mmap_location = base;
rbtdb->mmap_size = filesize;
rbtdb->origin_node = NULL;
-
+
if (header->tree != 0) {
dns_rbt_deserialize_tree(base, header->tree,
rbtdb->common.mctx, delete_callback,
dns_rbt_destroy(&rbtdb->tree);
rbtdb->tree = temporary_rbt;
temporary_rbt = NULL;
-
- rbtdb->origin_node =
+
+ rbtdb->origin_node =
(dns_rbtnode_t *)(header->tree + base + 1024);
}
}
callbacks->deserialize_private = NULL;
isc_mem_put(rbtdb->common.mctx, loadctx, sizeof(*loadctx));
-
+
return (ISC_R_SUCCESS);
}
/*
* helper function to handle writing out the rdataset data pointed to
- * by the void *data pointer in the dns_rbtnode
+ * by the void *data pointer in the dns_rbtnode
*/
static isc_result_t
rbt_datawriter(FILE *rbtfile, unsigned char *data, isc_uint32_t serial) {
memset(buffer, 0, RBTDB_HEADER_LENGTH);
result = isc_stdio_write(buffer, 1, RBTDB_HEADER_LENGTH, rbtfile, NULL);
fflush(rbtfile);
-
+
return (result);
}
rbtdb_version_t *version = (rbtdb_version_t *) ver;
dns_rbtdb_t *rbtdb;
isc_result_t result;
- isc_uint64_t tree_location;
+ isc_uint64_t tree_location;
isc_uint64_t nsec_location;
isc_uint64_t nsec3_location;
isc_uint64_t rbtdb_header_location;
/*
* first, write out a zeroed header to store rbtdb information
*
- * then for each of the three trees, store the current position
+ * then for each of the three trees, store the current position
* in the file and call dns_rbt_serialize_tree
*
- * finally, write out the rbtdb header, storing the locations of the
+ * finally, write out the rbtdb header, storing the locations of the
* rbtheaders
- *
+ *
* NOTE: need to do something better with the return codes, &= will
* not work.
*/