Commit 2a25f556 authored by marko's avatar marko

branches/zip: Add the first bits of the binary buddy system for allocating

compressed pages from the buffer pool.

Makefile.am: Add buf0buddy.h, buf0buddy.ic.

buf/Makefile.am: Add buf0buddy.c.

Introduce the constants BUF_BUDDY_LOW and BUF_BUDDY_SIZES.

buf_pool_t: Add zip_mutex and the lists zip_clean and zip_free[].

buf_page_get_mutex(): Return &buf_pool->zip_mutex instead of NULL.

buf_buddy_get_offset(), buf_buddy_get(), buf_buddy_get_slot(),
buf_buddy_alloc_free(), buf_buddy_alloc_free_low(): New functions.
parent ca02e145
......@@ -40,6 +40,7 @@ SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \
EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr0cur.ic \
include/btr0pcur.h include/btr0pcur.ic include/btr0sea.h include/btr0sea.ic \
include/btr0types.h \
include/buf0buddy.h include/buf0buddy.ic \
include/buf0buf.h include/buf0buf.ic include/buf0flu.h include/buf0flu.ic \
include/buf0lru.h include/buf0lru.ic include/buf0rea.h include/buf0types.h \
include/data0data.h include/data0data.ic include/data0type.h include/data0type.ic \
......
......@@ -19,6 +19,6 @@ include ../include/Makefile.i
noinst_LIBRARIES = libbuf.a
libbuf_a_SOURCES = buf0buf.c buf0flu.c buf0lru.c buf0rea.c
libbuf_a_SOURCES = buf0buf.c buf0buddy.c buf0flu.c buf0lru.c buf0rea.c
EXTRA_PROGRAMS =
/******************************************************
Binary buddy allocator for compressed pages
(c) 2006 Innobase Oy
Created December 2006 by Marko Makela
*******************************************************/
#define THIS_MODULE
#include "buf0buddy.h"
#ifdef UNIV_NONINL
# include "buf0buddy.ic"
#endif
#undef THIS_MODULE
#include "buf0buf.h"
/**************************************************************************
Try to allocate a block from buf_pool->zip_free[]. */
void*
buf_buddy_alloc_free_low(
/*=====================*/
/* out: allocated block, or NULL
if buf_pool->zip_free[] was empty */
ulint i) /* in: index of buf_pool->zip_free[] */
{
buf_page_t* bpage;
#ifdef UNIV_SYNC_DEBUG
ut_a(mutex_own(&buf_pool->mutex));
#endif /* UNIV_SYNC_DEBUG */
ut_a(i < BUF_BUDDY_SIZES);
bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
if (bpage) {
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
}
return(bpage);
}
......@@ -826,6 +826,8 @@ buf_pool_init(void)
mutex_enter(&(buf_pool->mutex));
mutex_create(&buf_pool->zip_mutex, SYNC_BUF_BLOCK);
buf_pool->n_chunks = 1;
buf_pool->chunks = chunk = mem_alloc(sizeof *chunk);
......@@ -884,6 +886,14 @@ buf_pool_init(void)
btr_search_sys_create(buf_pool->curr_size
* UNIV_PAGE_SIZE / sizeof(void*) / 64);
/* 4. Initialize the buddy allocator fields */
UT_LIST_INIT(buf_pool->zip_clean);
for (i = 0; i < BUF_BUDDY_SIZES; i++) {
UT_LIST_INIT(buf_pool->zip_free[i]);
}
return(buf_pool);
}
......
/******************************************************
Binary buddy allocator for compressed pages
(c) 2006 Innobase Oy
Created December 2006 by Marko Makela
*******************************************************/
#ifndef buf0buddy_h
#define buf0buddy_h
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE
#endif
#include "univ.i"
#include "buf0types.h"
/**************************************************************************
Get the offset of the buddy of a compressed page frame. */
UNIV_INLINE
lint
buf_buddy_get_offset(
/*=================*/
/* out: offset of the buddy relative to page */
const void* page, /* in: compressed page */
ulint size) /* in: page size in bytes */
__attribute__((nonnull));
/**************************************************************************
Get the buddy of a compressed page frame. */
#define buf_buddy_get(page,size) ((page) + buf_buddy_get_offset((page),(size)))
/**************************************************************************
Get the index of buf_pool->zip_free[] for a given block size. */
UNIV_INLINE
ulint
buf_buddy_get_slot(
/*===============*/
/* out: index of buf_pool->zip_free[] */
ulint size); /* in: block size */
/**************************************************************************
Try to allocate a block from buf_pool->zip_free[]. */
UNIV_INLINE
void*
buf_buddy_alloc_free(
/*=================*/
ulint size) /* in: block size, up to UNIV_PAGE_SIZE / 2 */
__attribute__((malloc));
#ifndef UNIV_NONINL
# include "buf0buddy.ic"
#endif
#endif /* buf0buddy_h */
/******************************************************
Binary buddy allocator for compressed pages
(c) 2006 Innobase Oy
Created December 2006 by Marko Makela
*******************************************************/
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE
#endif
#include "buf0buddy.h"
#include "ut0ut.h"
/**************************************************************************
Try to allocate a block from buf_pool->zip_free[]. */
void*
buf_buddy_alloc_free_low(
/*=====================*/
/* out: allocated block, or NULL
if buf_pool->zip_free[] was empty */
ulint i) /* in: index of buf_pool->zip_free[] */
__attribute__((malloc));
/**************************************************************************
Get the offset of the buddy of a compressed page frame. */
UNIV_INLINE
lint
buf_buddy_get_offset(
/*=================*/
/* out: offset of the buddy relative to page */
const void* page, /* in: compressed page */
ulint size) /* in: page size in bytes */
{
ut_ad(ut_is_2pow(size));
ut_ad(size >= BUF_BUDDY_LOW);
ut_ad(size < BUF_BUDDY_LOW << BUF_BUDDY_SIZES);
if (((ulint) page) & size) {
return(-(lint) size);
} else {
return((lint) size);
}
}
/**************************************************************************
Get the index of buf_pool->zip_free[] for a given block size. */
UNIV_INLINE
ulint
buf_buddy_get_slot(
/*===============*/
/* out: index of buf_pool->zip_free[] */
ulint size) /* in: block size */
{
ulint i;
ulint s;
for (i = 0, s = BUF_BUDDY_LOW; s < size; i++, s <<= 1);
ut_ad(i < BUF_BUDDY_SIZES);
return(i);
}
/**************************************************************************
Try to allocate a block from buf_pool->zip_free[]. */
UNIV_INLINE
void*
buf_buddy_alloc_free(
/*=================*/
ulint size) /* in: block size, up to UNIV_PAGE_SIZE / 2 */
{
#ifdef UNIV_SYNC_DEBUG
ut_a(mutex_own(&buf_pool->mutex));
#endif /* UNIV_SYNC_DEBUG */
return(buf_buddy_alloc_free_low(buf_buddy_get_slot(size)));
}
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE UNIV_INLINE_ORIGINAL
#endif
......@@ -1089,6 +1089,9 @@ struct buf_pool_struct{
mutex_t mutex; /* mutex protecting the buffer pool
struct and control blocks, except the
read-write lock in them */
mutex_t zip_mutex; /* mutex protecting the control blocks
of compressed-only pages (of type
buf_page_t, not buf_block_t) */
ulint n_chunks; /* number of buffer pool chunks */
buf_chunk_t* chunks; /* buffer pool chunks */
ulint curr_size; /* current pool size in pages */
......@@ -1162,6 +1165,18 @@ struct buf_pool_struct{
see buf0lru.c for the restrictions
on this value; not defined if
LRU_old == NULL */
/* 4. Fields for the buddy allocator of compressed pages */
UT_LIST_BASE_NODE_T(buf_page_t) zip_clean;
/* unmodified compressed pages */
UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES];
/* buddy free lists */
#if BUF_BUDDY_LOW << BUF_BUDDY_SIZES != UNIV_PAGE_SIZE
# error "BUF_BUDDY_LOW << BUF_BUDDY_SIZES != UNIV_PAGE_SIZE"
#endif
#if BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE
# error "BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE"
#endif
};
/************************************************************************
......
......@@ -261,7 +261,7 @@ buf_page_get_mutex(
break;
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
return(NULL); /* TODO: return common mutex for page_zip */
return(&buf_pool->zip_mutex);
default:
return(&((buf_block_t*) bpage)->mutex);
}
......
......@@ -32,5 +32,16 @@ enum buf_io_fix {
BUF_IO_WRITE /**< write pending */
};
/* Parameters of binary buddy system for compressed pages (buf0buddy.h) */
#if UNIV_WORD_SIZE <= 4 /* 32-bit system */
# define BUF_BUDDY_LOW 64 /* minimum block size in the binary
buddy system; must be at least
sizeof(buf_page_t) */
# define BUF_BUDDY_SIZES 8 /* number of buddy sizes */
#else /* 64-bit system */
# define BUF_BUDDY_LOW 128 /* sizeof(buf_page_t) > 64 */
# define BUF_BUDDY_SIZES 7
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment