Beispiel #1
0
/**
 * btree_sync(T, callback, cookie):
 * Serialize and write dirty nodes from the B+Tree ${T}; mark said nodes as
 * clean; free the shadow tree; and invoke the provided callback.
 */
int
btree_sync(struct btree * T, int (* callback)(void *), void * cookie)
{
	struct write_cookie * WC;
	size_t npages;
	const uint8_t ** bufv;
	uint64_t pn = 0;

	/* Bake a cookie. */
	if ((WC = malloc(sizeof(struct write_cookie))) == NULL)
		goto err0;
	WC->T = T;
	WC->callback = callback;
	WC->cookie = cookie;

	/* Figure out how many pages we need to write. */
	npages = ndirty(T->root_dirty);

	/* Allocate a vector to hold pointers to pages. */
	if (IMALLOC(bufv, npages, const uint8_t *))
		goto err1;

	/* Serialize pages and record pointers into the vector. */
	if (serializetree(T, T->root_dirty, T->pagelen, T->nextblk,
	    bufv, &pn))
		goto err2;

	/* Sanity check the number of pages serialized. */
	assert(pn == npages);

	/* Write pages out. */
	if (proto_lbs_request_append_blks(T->LBS, npages, T->nextblk,
	    T->pagelen, bufv, callback_append, WC)) {
		warnp("Error writing pages");
		goto err2;
	}

	/* Free the page pointers vector. */
	free(bufv);

	/* Success! */
	return (0);

err2:
	free(bufv);
err1:
	free(WC);
err0:
	/* Failure! */
	return (-1);
}
Beispiel #2
0
/* Compile a compressed dictionary file from the words in the given
 * files.
 */
int makedictfile(int filecount, char *files[])
{
    if (!filecount) {
	filecount = 1;
	files = &defwordlist;
    }

    nodecount = 1;
    if (!readwordlists(filecount, files, grabnewtreearc(0, nodecount)))
	return EXIT_FAILURE;
    computefrequencies();
    serializetree();
    writetreetofile(partitiontree());

    report("Dictionary saved to %s\n", dictfilename);
    return EXIT_SUCCESS;
}
Beispiel #3
0
/* Serialize the dirty nodes in a (sub)tree. */
static int
serializetree(struct btree * T, struct node * N, size_t pagelen,
    uint64_t nextblk, const uint8_t ** bufv, uint64_t * pn)
{
	size_t i;

	/* If this node is not dirty, return immediately. */
	if (N->state != NODE_STATE_DIRTY)
		return (0);

	/* If this node has children, serialize them first. */
	if (N->type == NODE_TYPE_PARENT) {
		for (i = 0; i <= N->nkeys; i++)
			if (serializetree(T, N->v.children[i], pagelen,
			    nextblk, bufv, pn))
				goto err0;
	}

	/* Record this node's page number. */
	N->pagenum = nextblk + *pn;

	/*
	 * Figure out what the oldest leaf number under this node is.  The
	 * oldest not-being-cleaned leaf is computed in makeclean.
	 */
	N->oldestleaf = N->pagenum;
	if (N->type == NODE_TYPE_PARENT) {
		for (i = 0; i <= N->nkeys; i++) {
			if (N->v.children[i]->oldestleaf < N->oldestleaf)
				N->oldestleaf = N->v.children[i]->oldestleaf;
		}
	}

	/* Serialize the page and record the page pointer. */
	if (serialize(T, N, pagelen))
		goto err0;
	bufv[(*pn)++] = N->pagebuf;

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}