Ejemplo n.º 1
0
/**
 * Allocate a single block in the file, without extending it.
 *
 * @param db		the sdbm database
 * @param first		first block to consider
 *
 * @return the block number if found, 0 otherwise.
 */
static size_t
big_falloc(DBM *db, size_t first)
{
	DBMBIG *dbg = db->big;
	long max_bitmap = dbg->bitmaps;
	long i;
	long bmap;
	size_t first_bit;

	bmap = first / BIG_BITCOUNT;			/* Bitmap handling this block */
	first_bit = first & (BIG_BITCOUNT - 1);	/* Index within bitmap */

	g_assert(first_bit != 0);				/* Bit 0 is the bitmap itself */

	/*
	 * Loop through all the currently existing bitmaps.
	 */

	for (i = bmap; i < max_bitmap; i++) {
		size_t bno;

		if (!fetch_bitbuf(db, i))
			return 0;
		
		bno = bit_field_first_clear(dbg->bitbuf, first_bit, BIG_BITCOUNT - 1);
		if ((size_t) -1 == bno)
			continue;

		/*
		 * Found a free block.
		 */

		bit_field_set(dbg->bitbuf, bno);
		dbg->bitbuf_dirty = TRUE;

		/*
		 * Correct the block number corresponding to "bno", if we did
		 * not find it in bitmap #0.
		 */

		bno = size_saturate_add(bno, size_saturate_mult(BIG_BITCOUNT, i));

		/* Make sure we can represent the block number in 32 bits */
		g_assert(bno <= MAX_INT_VAL(guint32));

		return bno;		/* Allocated block number */
	}

	return 0;		/* No free block found */
}
Ejemplo n.º 2
0
/**
 * Shrink .dat file on disk to remove needlessly allocated blocks.
 *
 * @return TRUE if we were able to successfully shrink the file.
 */
gboolean
big_shrink(DBM *db)
{
	DBMBIG *dbg = db->big;
	long i;
	filesize_t offset = 0;

	if (-1 == dbg->fd) {
		/*
		 * We do not want to call big_open() unless the .dat file already
		 * exists because that would create it and it was not needed so far.
		 */

		if (-1 == big_open_lazy(dbg, TRUE))
			return 0 == errno;
	}

	g_assert(dbg->fd != -1);

	/*
	 * Loop through all the currently existing bitmaps, starting from the last
	 * one, looking for the last set bit indicating the last used page.
	 */

	for (i = dbg->bitmaps - 1; i >= 0; i--) {
		size_t bno;

		if (!fetch_bitbuf(db, i))
			return FALSE;

		bno = bit_field_last_set(dbg->bitbuf, 0, BIG_BITCOUNT - 1);

		if ((size_t) -1 == bno) {
			g_warning("sdbm: \"%s\": corrupted bitmap #%ld, considered empty",
				sdbm_name(db), i);
		} else if (bno != 0) {
			bno = size_saturate_add(bno, size_saturate_mult(BIG_BITCOUNT, i));
			offset = OFF_DAT(bno + 1);
			break;
		}
	}

	if (-1 == ftruncate(dbg->fd, offset))
		return FALSE;

	dbg->bitmaps = i + 1;	/* Possibly reduced the amount of bitmaps */

	return TRUE;
}
Ejemplo n.º 3
0
/**
 * HTTP async callback, invoked when new HTTP data is read.
 * The EOF condition is indicated by data being NULL.
 */
static void
soap_data_ind(http_async_t *ha, char *data, int len)
{
	soap_rpc_t *sr = http_async_get_opaque(ha);
	size_t new_length;

	soap_rpc_check(sr);

	/*
	 * When data is NULL, we reached EOF and we're done.  Time to process
	 * the data we got back.
	 *
	 * The HTTP asynchronous handle is nullified since it is about to be
	 * closed by the HTTP layer upon return.
	 */

	if (NULL == data) {
		sr->ha = NULL;
		soap_process_reply(sr);
		return;
	}

	/*
	 * Ensure we don't get too much and resize the memory buffer where
	 * we store the reply if needed.
	 */

	new_length = size_saturate_add(sr->reply_len, len);

	if (new_length > sr->content_len) {
		http_async_error(ha, HTTP_ASYNC_DATA2BIG);
		return;
	}

	if (new_length > sr->reply_size) {
		size_t new_size = size_saturate_mult(sr->reply_size, 2);

		sr->reply_data = hrealloc(sr->reply_data, new_size);
		sr->reply_size = new_size;
	}

	/*
	 * Append new data.
	 */

	memcpy(&sr->reply_data[sr->reply_len], data, len);
	sr->reply_len = new_length;
}
Ejemplo n.º 4
0
/**
 * Extend token buffer.
 */
static void
extend_token(strtok_t *s)
{
	size_t len;

	strtok_check(s);

	if (s->len > 0) {
		if (s->len > STRTOK_GROW)
			len = size_saturate_add(s->len, STRTOK_GROW);
		else
			len = size_saturate_mult(s->len, 2);
	} else {
		len = STRTOK_FIRST_LEN;
	}

	grow_token(s, len);
}
Ejemplo n.º 5
0
/**
 * Allocate "n" consecutive (sequential) blocks in the file, without
 * attempting to extend it.
 *
 * @param db		the sdbm database
 * @param bmap		bitmap number from which we need to start looking
 * @param n			amount of consecutive blocks we want
 *
 * @return the block number of the first "n" blocks if found, 0 if nothing
 * was found.
 */
static size_t
big_falloc_seq(DBM *db, int bmap, int n)
{
	DBMBIG *dbg = db->big;
	long max_bitmap = dbg->bitmaps;
	long i;

	g_assert(bmap >= 0);
	g_assert(n > 0);

	/*
	 * Loop through all the currently existing bitmaps, starting at the
	 * specified bitmap number.
	 */

	for (i = bmap; i < max_bitmap; i++) {
		size_t first;
		size_t j;
		int r;			/* Remaining blocks to allocate consecutively */

		if (!fetch_bitbuf(db, i))
			return 0;

		/*
		 * We start at bit #1 since bit #0 is the bitmap itself.
		 *
		 * Bit #0 should always be set but in case the file is corrupted,
		 * we don't want to start allocating data in the bitmap itself!.
		 */
		
		first = bit_field_first_clear(dbg->bitbuf, 1, BIG_BITCOUNT - 1);
		if ((size_t) -1 == first)
			continue;

		for (j = first + 1, r = n - 1; r > 0 && j < BIG_BITCOUNT; r--, j++) {
			if (bit_field_get(dbg->bitbuf, j))
				break;
		}

		/*
		 * If "r" is 0, we have no remaining page to allocate: we found our
		 * "n" consecutive free blocks.
		 */

		if (0 == r) {
			/*
			 * Mark the "n" consecutive blocks as busy.
			 */

			for (j = first, r = n; r > 0; r--, j++) {
				bit_field_set(dbg->bitbuf, j);
			}
			dbg->bitbuf_dirty = TRUE;

			/*
			 * Correct the block number corresponding to "first", if we did
			 * not find it in bitmap #0.
			 */

			first = size_saturate_add(first,
				size_saturate_mult(BIG_BITCOUNT, i));

			/* Make sure we can represent all block numbers in 32 bits */
			g_assert(size_saturate_add(first, n - 1) <= MAX_INT_VAL(guint32));

			return first;	/* "n" consecutive free blocks found */
		}
	}

	return 0;		/* No free block found */
}