mirror of
https://github.com/MariaDB/server.git
synced 2025-02-02 03:51:50 +01:00
close[t:5054] Fix #5054. Improve spec for block_allocator.
git-svn-id: file:///svn/toku/tokudb@44417 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
810b6b645a
commit
7716bfc49f
2 changed files with 36 additions and 42 deletions
|
@ -94,12 +94,6 @@ grow_blocks_array (BLOCK_ALLOCATOR ba) {
|
|||
void
|
||||
block_allocator_merge_blockpairs_into (u_int64_t d, struct block_allocator_blockpair dst[/*d*/],
|
||||
u_int64_t s, const struct block_allocator_blockpair src[/*s*/])
|
||||
// Effect: Merge dst[d] and src[s] into dst[d+s], merging in place.
|
||||
// Initially dst and src hold sorted arrays (sorted by increasing offset).
|
||||
// Finally dst contains all d+s elements sorted in order.
|
||||
// dst must be large enough.
|
||||
// Requires no overlaps.
|
||||
// This is not static so that we can write a unit test for it. (Otherwise, this is static only to be used from inside the block allocator)
|
||||
{
|
||||
u_int64_t tail = d+s;
|
||||
while (d>0 && s>0) {
|
||||
|
|
|
@ -22,9 +22,8 @@ extern "C" {
|
|||
#error
|
||||
#endif
|
||||
|
||||
#define BLOCK_ALLOCATOR_TOTAL_HEADER_RESERVE (2*BLOCK_ALLOCATOR_HEADER_RESERVE)
|
||||
|
||||
// A block allocator manages the allocation of variable-sized blocks.
|
||||
// Block allocator.
|
||||
// Overview: A block allocator manages the allocation of variable-sized blocks.
|
||||
// The translation of block numbers to addresses is handled elsewhere.
|
||||
// The allocation of block numbers is handled elsewhere.
|
||||
|
||||
|
@ -38,10 +37,12 @@ extern "C" {
|
|||
// We can free blocks.
|
||||
// We can determine the size of a block.
|
||||
|
||||
|
||||
#define BLOCK_ALLOCATOR_TOTAL_HEADER_RESERVE (2*BLOCK_ALLOCATOR_HEADER_RESERVE)
|
||||
|
||||
typedef struct block_allocator *BLOCK_ALLOCATOR;
|
||||
|
||||
void
|
||||
create_block_allocator (BLOCK_ALLOCATOR * ba, u_int64_t reserve_at_beginning, u_int64_t alignment);
|
||||
void create_block_allocator (BLOCK_ALLOCATOR * ba, u_int64_t reserve_at_beginning, u_int64_t alignment);
|
||||
// Effect: Create a block allocator, in which the first RESERVE_AT_BEGINNING bytes are not put into a block.
|
||||
// All blocks be start on a multiple of ALIGNMENT.
|
||||
// Aborts if we run out of memory.
|
||||
|
@ -50,8 +51,7 @@ create_block_allocator (BLOCK_ALLOCATOR * ba, u_int64_t reserve_at_beginning, u_
|
|||
// reserve_at_beginning (IN) Size of reserved block at beginning. This size does not have to be aligned.
|
||||
// alignment (IN) Block alignment.
|
||||
|
||||
void
|
||||
destroy_block_allocator (BLOCK_ALLOCATOR *ba);
|
||||
void destroy_block_allocator (BLOCK_ALLOCATOR *ba);
|
||||
// Effect: Destroy a block allocator at *ba.
|
||||
// Also, set *ba=NULL.
|
||||
// Rationale: If there was only one copy of the pointer, this kills that copy too.
|
||||
|
@ -59,8 +59,7 @@ destroy_block_allocator (BLOCK_ALLOCATOR *ba);
|
|||
// ba (IN/OUT):
|
||||
|
||||
|
||||
void
|
||||
block_allocator_alloc_block_at (BLOCK_ALLOCATOR ba, u_int64_t size, u_int64_t offset);
|
||||
void block_allocator_alloc_block_at (BLOCK_ALLOCATOR ba, u_int64_t size, u_int64_t offset);
|
||||
// Effect: Allocate a block of the specified size at a particular offset.
|
||||
// Aborts if anything goes wrong.
|
||||
// The performance of this function may be as bad as Theta(N), where N is the number of blocks currently in use.
|
||||
|
@ -77,14 +76,12 @@ struct block_allocator_blockpair {
|
|||
u_int64_t offset;
|
||||
u_int64_t size;
|
||||
};
|
||||
void
|
||||
block_allocator_alloc_blocks_at (BLOCK_ALLOCATOR ba, u_int64_t n_blocks, struct block_allocator_blockpair *pairs);
|
||||
void block_allocator_alloc_blocks_at (BLOCK_ALLOCATOR ba, u_int64_t n_blocks, struct block_allocator_blockpair *pairs);
|
||||
// Effect: Take pairs in any order, and add them all, as if we did block_allocator_alloc_block() on each pair.
|
||||
// This should run in time O(N + M log M) where N is the number of blocks in ba, and M is the number of new blocks.
|
||||
// Modifies: pairs (sorts them).
|
||||
|
||||
void
|
||||
block_allocator_alloc_block (BLOCK_ALLOCATOR ba, u_int64_t size, u_int64_t *offset);
|
||||
void block_allocator_alloc_block (BLOCK_ALLOCATOR ba, u_int64_t size, u_int64_t *offset);
|
||||
// Effect: Allocate a block of the specified size at an address chosen by the allocator.
|
||||
// Aborts if anything goes wrong.
|
||||
// The block address will be a multiple of the alignment.
|
||||
|
@ -93,8 +90,7 @@ block_allocator_alloc_block (BLOCK_ALLOCATOR ba, u_int64_t size, u_int64_t *offs
|
|||
// size (IN): The size of the block. (The size does not have to be aligned.)
|
||||
// offset (OUT): The location of the block.
|
||||
|
||||
void
|
||||
block_allocator_free_block (BLOCK_ALLOCATOR ba, u_int64_t offset);
|
||||
void block_allocator_free_block (BLOCK_ALLOCATOR ba, u_int64_t offset);
|
||||
// Effect: Free the block at offset.
|
||||
// Requires: There must be a block currently allocated at that offset.
|
||||
// Parameters:
|
||||
|
@ -102,47 +98,51 @@ block_allocator_free_block (BLOCK_ALLOCATOR ba, u_int64_t offset);
|
|||
// offset (IN): The offset of the block.
|
||||
|
||||
|
||||
u_int64_t
|
||||
block_allocator_block_size (BLOCK_ALLOCATOR ba, u_int64_t offset);
|
||||
u_int64_t block_allocator_block_size (BLOCK_ALLOCATOR ba, u_int64_t offset);
|
||||
// Effect: Return the size of the block that starts at offset.
|
||||
// Requires: There must be a block currently allocated at that offset.
|
||||
// Parameters:
|
||||
// ba (IN/OUT): The block allocator. (Modifies ba.)
|
||||
// offset (IN): The offset of the block.
|
||||
|
||||
void
|
||||
block_allocator_validate (BLOCK_ALLOCATOR ba);
|
||||
void block_allocator_validate (BLOCK_ALLOCATOR ba);
|
||||
// Effect: Check to see if the block allocator is OK. This may take a long time.
|
||||
// Usage Hints: Probably only use this for unit tests.
|
||||
|
||||
void
|
||||
block_allocator_print (BLOCK_ALLOCATOR ba);
|
||||
void block_allocator_print (BLOCK_ALLOCATOR ba);
|
||||
// Effect: Print information about the block allocator.
|
||||
// Rationale: This is probably useful only for debugging.
|
||||
|
||||
u_int64_t
|
||||
block_allocator_allocated_limit (BLOCK_ALLOCATOR ba);
|
||||
u_int64_t block_allocator_allocated_limit (BLOCK_ALLOCATOR ba);
|
||||
// Effect: Return the unallocated block address of "infinite" size.
|
||||
// That is, return the smallest address that is above all the allocated blocks.
|
||||
// Rationale: When writing the root FIFO we don't know how big the block is.
|
||||
// So we start at the "infinite" block, write the fifo, and then
|
||||
// allocate_block_at of the correct size and offset to account for the root FIFO.
|
||||
|
||||
int
|
||||
block_allocator_get_nth_block_in_layout_order (BLOCK_ALLOCATOR ba, u_int64_t b, u_int64_t *offset, u_int64_t *size);
|
||||
int block_allocator_get_nth_block_in_layout_order (BLOCK_ALLOCATOR ba, u_int64_t b, u_int64_t *offset, u_int64_t *size);
|
||||
// Effect: Consider the blocks in sorted order. The reserved block at the beginning is number 0. The next one is number 1 and so forth.
|
||||
// Return the offset and size of the block with that number.
|
||||
// Return 0 if there is a block that big, return nonzero if b is too big.
|
||||
// This is probably only useful for tests.
|
||||
// Return the offset and size of the block with that number.
|
||||
// Return 0 if there is a block that big, return nonzero if b is too big.
|
||||
// Rationale: This is probably useful only for tests.
|
||||
|
||||
void
|
||||
block_allocator_get_unused_statistics(BLOCK_ALLOCATOR ba, TOKU_DB_FRAGMENTATION report);
|
||||
//Requires: report->file_size_bytes is filled in
|
||||
//Requires: report->data_bytes is filled in
|
||||
//Requires: report->checkpoint_bytes_additional is filled in
|
||||
void block_allocator_get_unused_statistics(BLOCK_ALLOCATOR ba, TOKU_DB_FRAGMENTATION report);
|
||||
// Effect: Fill in report to indicate how the file is used.
|
||||
// Requires:
|
||||
// report->file_size_bytes is filled in
|
||||
// report->data_bytes is filled in
|
||||
// report->checkpoint_bytes_additional is filled in
|
||||
|
||||
void
|
||||
block_allocator_merge_blockpairs_into (u_int64_t d, struct block_allocator_blockpair dst[/*d*/],
|
||||
void block_allocator_merge_blockpairs_into (u_int64_t d, struct block_allocator_blockpair dst[/*d*/],
|
||||
u_int64_t s, const struct block_allocator_blockpair src[/*s*/]);
|
||||
// This is exposed so it can be tested.
|
||||
// Effect: Merge dst[d] and src[s] into dst[d+s], merging in place.
|
||||
// Initially dst and src hold sorted arrays (sorted by increasing offset).
|
||||
// Finally dst contains all d+s elements sorted in order.
|
||||
// Requires:
|
||||
// dst and src are sorted.
|
||||
// dst must be large enough.
|
||||
// No blocks may overlap.
|
||||
// Rationale: This is exposed so it can be tested by a glass box tester. Otherwise it would be static (file-scope) function inside block_allocator.c
|
||||
|
||||
#if defined(__cplusplus) || defined(__cilkplusplus)
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue