示例#1
0
/*
 * __wt_block_discard --
 *	Discard blocks from the system buffer cache.
 */
int
__wt_block_discard(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t added_size)
{
	WT_DECL_RET;
	WT_FILE_HANDLE *handle;

	/* The file may not support this call. */
	handle = block->fh->handle;
	if (handle->fh_advise == NULL)
		return (0);

	/* The call may not be configured. */
	if (block->os_cache_max == 0)
		return (0);

	/*
	 * We're racing on the addition, but I'm not willing to serialize on it
	 * in the standard read path without evidence it's needed.
	 */
	if ((block->os_cache += added_size) <= block->os_cache_max)
		return (0);

	block->os_cache = 0;
	ret = handle->fh_advise(handle, (WT_SESSION *)session,
	    (wt_off_t)0, (wt_off_t)0, WT_FILE_HANDLE_DONTNEED);
	return (ret == EBUSY || ret == ENOTSUP ? 0 : ret);
}
示例#2
0
文件: block_map.c 项目: Machyne/mongo
/*
 * __wt_block_unmap --
 *	Unmap any mapped-in segment of the file.
 */
int
__wt_block_unmap(WT_SESSION_IMPL *session,
    WT_BLOCK *block, void *mapped_region, size_t length, void *mapped_cookie)
{
	WT_FILE_HANDLE *handle;

	/* Unmap the file from memory. */
	handle = block->fh->handle;
	return (handle->fh_unmap(handle,
	    (WT_SESSION *)session, mapped_region, length, mapped_cookie));
}
示例#3
0
/*
 * __wt_bm_read --
 *	Map or read address cookie referenced block into a buffer.
 */
int
__wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session,
    WT_ITEM *buf, const uint8_t *addr, size_t addr_size)
{
	WT_BLOCK *block;
	WT_DECL_RET;
	WT_FILE_HANDLE *handle;
	wt_off_t offset;
	uint32_t checksum, size;
	bool mapped;

	WT_UNUSED(addr_size);
	block = bm->block;

	/* Crack the cookie. */
	WT_RET(
	    __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum));

	/*
	 * Map the block if it's possible.
	 */
	handle = block->fh->handle;
	mapped = bm->map != NULL && offset + size <= (wt_off_t)bm->maplen;
	if (mapped && handle->fh_map_preload != NULL) {
		buf->data = (uint8_t *)bm->map + offset;
		buf->size = size;
		ret = handle->fh_map_preload(handle, (WT_SESSION *)session,
		    buf->data, buf->size,bm->mapped_cookie);

		WT_STAT_CONN_INCR(session, block_map_read);
		WT_STAT_CONN_INCRV(session, block_byte_map_read, size);
		return (ret);
	}

#ifdef HAVE_DIAGNOSTIC
	/*
	 * In diagnostic mode, verify the block we're about to read isn't on
	 * the available list, or for live systems, the discard list.
	 */
	WT_RET(__wt_block_misplaced(session,
	    block, "read", offset, size, bm->is_live, __func__, __LINE__));
#endif
	/* Read the block. */
	__wt_capacity_throttle(session, size, WT_THROTTLE_READ);
	WT_RET(
	    __wt_block_read_off(session, block, buf, offset, size, checksum));

	/* Optionally discard blocks from the system's buffer cache. */
	WT_RET(__wt_block_discard(session, block, (size_t)size));

	return (0);
}
示例#4
0
文件: block_map.c 项目: Machyne/mongo
/*
 * __wt_block_map --
 *	Map a segment of the file in, if possible.
 */
int
__wt_block_map(WT_SESSION_IMPL *session, WT_BLOCK *block,
    void *mapped_regionp, size_t *lengthp, void *mapped_cookiep)
{
	WT_DECL_RET;
	WT_FILE_HANDLE *handle;

	*(void **)mapped_regionp = NULL;
	*lengthp = 0;
	*(void **)mapped_cookiep = NULL;

	/* Map support is configurable. */
	if (!S2C(session)->mmap)
		return (0);

	/*
	 * Turn off mapping when verifying the file, because we can't perform
	 * checksum validation of mapped segments, and verify has to checksum
	 * pages.
	 */
	if (block->verify)
		return (0);

	/*
	 * Turn off mapping if the application configured a cache size maximum,
	 * we can't control how much of the cache size we use in that case.
	 */
	if (block->os_cache_max != 0)
		return (0);

	/*
	 * There may be no underlying functionality.
	 */
	handle = block->fh->handle;
	if (handle->fh_map == NULL)
		return (0);

	/*
	 * Map the file into memory.
	 * Ignore not-supported errors, we'll read the file through the cache
	 * if map fails.
	 */
	ret = handle->fh_map(handle,
	    (WT_SESSION *)session, mapped_regionp, lengthp, mapped_cookiep);
	if (ret == EBUSY || ret == ENOTSUP) {
		*(void **)mapped_regionp = NULL;
		ret = 0;
	}

	return (ret);
}
示例#5
0
文件: block_read.c 项目: mikety/mongo
/*
 * __wt_bm_preload --
 *	Pre-load a page.
 */
int
__wt_bm_preload(
    WT_BM *bm, WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size)
{
	WT_BLOCK *block;
	WT_DECL_ITEM(tmp);
	WT_DECL_RET;
	WT_FILE_HANDLE *handle;
	wt_off_t offset;
	uint32_t cksum, size;
	bool mapped;

	WT_UNUSED(addr_size);

	block = bm->block;

	WT_STAT_FAST_CONN_INCR(session, block_preload);

	/* Crack the cookie. */
	WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum));

	handle = block->fh->handle;
	mapped = bm->map != NULL && offset + size <= (wt_off_t)bm->maplen;
	if (mapped && handle->fh_map_preload != NULL)
		ret = handle->fh_map_preload(handle, (WT_SESSION *)session,
		    (uint8_t *)bm->map + offset, size, bm->mapped_cookie);
	if (!mapped && handle->fh_advise != NULL)
		ret = handle->fh_advise(handle, (WT_SESSION *)session,
		    (wt_off_t)offset, (wt_off_t)size, WT_FILE_HANDLE_WILLNEED);
	if (ret != EBUSY && ret != ENOTSUP)
		return (ret);

	/* If preload isn't supported, do it the slow way. */
	WT_RET(__wt_scr_alloc(session, 0, &tmp));
	ret = __wt_bm_read(bm, session, tmp, addr, addr_size);
	__wt_scr_free(session, &tmp);

	return (ret);
}