/* * __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); }
/* * __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)); }
/* * __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); }
/* * __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); }
/* * __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); }