MySQL 9.1.0
Source Code Documentation
|
Binary buddy allocator for compressed pages. More...
#include "buf0buddy.h"
#include "buf0buf.h"
#include "buf0flu.h"
#include "buf0lru.h"
#include "dict0dict.h"
#include "page0zip.h"
Classes | |
struct | CheckZipFree |
Validate a given zip_free list. More... | |
Enumerations | |
enum | buf_buddy_state_t { BUF_BUDDY_STATE_FREE , BUF_BUDDY_STATE_USED , BUF_BUDDY_STATE_PARTIALLY_USED } |
Return type of buf_buddy_is_free() More... | |
Functions | |
static void | buf_buddy_mem_invalid (buf_buddy_free_t *, ulint i) |
static bool | buf_buddy_stamp_is_free (const buf_buddy_free_t *buf) |
Check if a buddy is stamped free. More... | |
static void | buf_buddy_stamp_free (buf_buddy_free_t *buf, ulint i) |
Stamps a buddy free. More... | |
static void | buf_buddy_stamp_nonfree (buf_buddy_free_t *buf, ulint i) |
Stamps a buddy nonfree. More... | |
static void * | buf_buddy_get (byte *page, ulint size) |
Get the offset of the buddy of a compressed page frame. More... | |
static void | buf_buddy_list_validate (const buf_pool_t *buf_pool, ulint i) |
Validate a buddy list. More... | |
static bool | buf_buddy_check_free (buf_pool_t *buf_pool, const buf_buddy_free_t *buf, ulint i) |
Debug function to validate that a buffer is indeed free i.e. More... | |
static buf_buddy_state_t | buf_buddy_is_free (buf_buddy_free_t *buf, ulint i) |
Checks if a buf is free i.e. More... | |
static void | buf_buddy_add_to_free (buf_pool_t *buf_pool, buf_buddy_free_t *buf, ulint i) |
Add a block to the head of the appropriate buddy free list. More... | |
static void | buf_buddy_remove_from_free (buf_pool_t *buf_pool, buf_buddy_free_t *buf, ulint i) |
Remove a block from the appropriate buddy free list. More... | |
static buf_buddy_free_t * | buf_buddy_alloc_zip (buf_pool_t *buf_pool, ulint i) |
Try to allocate a block from buf_pool->zip_free[]. More... | |
static void | buf_buddy_block_free (buf_pool_t *buf_pool, void *buf) |
Deallocate a buffer frame of UNIV_PAGE_SIZE. More... | |
static void | buf_buddy_block_register (buf_block_t *block) |
Allocate a buffer block to the buddy allocator. More... | |
static void * | buf_buddy_alloc_from (buf_pool_t *buf_pool, void *buf, ulint i, ulint j) |
Allocate a block from a bigger object. More... | |
void * | buf_buddy_alloc_low (buf_pool_t *buf_pool, ulint i) |
Allocate a block. More... | |
static bool | buf_buddy_relocate (buf_pool_t *buf_pool, void *src, void *dst, ulint i, bool force) |
Try to relocate a block. More... | |
void | buf_buddy_free_low (buf_pool_t *buf_pool, void *buf, ulint i, bool has_zip_free) |
Deallocate a block. More... | |
bool | buf_buddy_realloc (buf_pool_t *buf_pool, void *buf, ulint size) |
Try to reallocate a block. More... | |
void | buf_buddy_condense_free (buf_pool_t *buf_pool) |
Combine all pairs of free buddies. More... | |
Variables | |
constexpr uint32_t | BUF_BUDDY_STAMP_OFFSET = FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID |
When freeing a buf we attempt to coalesce by looking at its buddy and deciding whether it is free or not. More... | |
constexpr uint64_t | BUF_BUDDY_STAMP_FREE = dict_sys_t::s_log_space_id |
Value that we stamp on all buffers that are currently on the zip_free list. More... | |
constexpr uint64_t | BUF_BUDDY_STAMP_NONFREE = 0XFFFFFFFFUL |
Stamp value for non-free buffers. More... | |
Binary buddy allocator for compressed pages.
Created December 2006 by Marko Makela
enum buf_buddy_state_t |
|
inlinestatic |
Add a block to the head of the appropriate buddy free list.
[in] | buf_pool | buffer pool instance |
[in,out] | buf | block to be freed |
[in] | i | index of buf_pool->zip_free[] |
|
static |
Allocate a block from a bigger object.
[in] | buf_pool | buffer pool instance |
[in] | buf | a block that is free to use |
[in] | i | index of buf_pool->zip_free[] |
[in] | j | size of buf as an index of buf_pool->zip_free[] |
void * buf_buddy_alloc_low | ( | buf_pool_t * | buf_pool, |
ulint | i | ||
) |
Allocate a block.
[in,out] | buf_pool | buffer pool instance |
[in] | i | index of buf_pool->zip_free[] or BUF_BUDDY_SIZES |
|
static |
Try to allocate a block from buf_pool->zip_free[].
[in] | buf_pool | buffer pool instance |
[in] | i | index of buf_pool->zip_free[] |
|
static |
Deallocate a buffer frame of UNIV_PAGE_SIZE.
[in] | buf_pool | buffer pool instance |
[in] | buf | buffer frame to deallocate |
|
static |
Allocate a buffer block to the buddy allocator.
[in] | block | buffer frame to allocate |
|
inlinestatic |
Debug function to validate that a buffer is indeed free i.e.
: in the zip_free[].
[in] | buf_pool | buffer pool instance |
[in] | buf | block to check |
[in] | i | index of buf_pool->zip_free[] |
void buf_buddy_condense_free | ( | buf_pool_t * | buf_pool | ) |
Combine all pairs of free buddies.
[in] | buf_pool | buffer pool instance |
void buf_buddy_free_low | ( | buf_pool_t * | buf_pool, |
void * | buf, | ||
ulint | i, | ||
bool | has_zip_free | ||
) |
Deallocate a block.
[in] | buf_pool | buffer pool instance |
[in] | buf | block to be freed, must not be pointed to by the buffer pool |
[in] | i | index of buf_pool->zip_free[], or BUF_BUDDY_SIZES |
[in] | has_zip_free | whether has zip_free_mutex |
Get the offset of the buddy of a compressed page frame.
page | in: compressed page |
size | in: page size in bytes |
|
static |
Checks if a buf is free i.e.
: in the zip_free[].
BUF_BUDDY_STATE_FREE | if fully free |
BUF_BUDDY_STATE_USED | if currently in use |
BUF_BUDDY_STATE_PARTIALLY_USED | if partially in use. |
buf | in: block to check |
i | in: index of buf_pool->zip_free[] |
|
static |
Validate a buddy list.
[in] | buf_pool | buffer pool instance |
[in] | i | buddy size to validate |
|
inlinestatic |
bool buf_buddy_realloc | ( | buf_pool_t * | buf_pool, |
void * | buf, | ||
ulint | size | ||
) |
Try to reallocate a block.
[in] | buf_pool | buffer pool instance |
[in] | buf | block to be reallocated, must be pointed to by the buffer pool |
[in] | size | block size, up to UNIV_PAGE_SIZE |
true | if succeeded or if failed because the block was fixed |
false | if failed because of no free blocks. |
|
static |
Try to relocate a block.
The caller must hold zip_free_mutex, and this function will release and lock it again.
[in] | buf_pool | buffer pool instance |
[in] | src | block to relocate |
[in] | dst | free block to relocated to |
[in] | i | index of buf_pool->zip_free[] |
[in] | force | true if we must relocated always |
|
inlinestatic |
Remove a block from the appropriate buddy free list.
[in] | buf_pool | buffer pool instance |
[in,out] | buf | block to be freed |
[in] | i | index of buf_pool->zip_free[] |
|
inlinestatic |
Stamps a buddy free.
buf | in/out: block to stamp |
i | in: block size |
|
inlinestatic |
Check if a buddy is stamped free.
buf | in: block to check |
|
inlinestatic |
Stamps a buddy nonfree.
[in,out] | buf | block to stamp |
[in] | i | block size |
|
constexpr |
Value that we stamp on all buffers that are currently on the zip_free list.
This value is stamped at BUF_BUDDY_STAMP_OFFSET offset
|
constexpr |
Stamp value for non-free buffers.
Will be overwritten by a non-zero value by the consumer of the block
|
constexpr |
When freeing a buf we attempt to coalesce by looking at its buddy and deciding whether it is free or not.
To ascertain if the buddy is free we look for BUF_BUDDY_STAMP_FREE at BUF_BUDDY_STAMP_OFFSET within the buddy. The question is how we can be sure that it is safe to look at BUF_BUDDY_STAMP_OFFSET. The answer lies in following invariants: All blocks allocated by buddy allocator are used for compressed page frame. A compressed table always have space_id < dict_sys_t::s_log_space_id BUF_BUDDY_STAMP_OFFSET always points to the space_id field in a frame. – The above is true because we look at these fields when the corresponding buddy block is free which implies that: