File mem_block.cpp¶
File List > base > mem_block.cpp
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* mem_block.cpp - Memory Block Functionality
*/
#include "mem_block.hpp"
#include <functional>
#include <cstring>
// XXX: SHOULD BE THE LAST INCLUDE HEADER
#include "memory_wrapper.hpp"
namespace cubmem
{
void
standard_alloc (block &b, size_t size)
{
if (b.ptr == NULL || b.dim == 0)
{
b.ptr = new char[size];
b.dim = size;
}
else if (size <= b.dim)
{
// do not reduce
}
else
{
char *new_ptr = new char[size];
std::memcpy (new_ptr, b.ptr, b.dim);
delete[] b.ptr;
b.ptr = new_ptr;
b.dim = size;
}
}
void
standard_dealloc (block &b)
{
delete [] b.ptr;
b.ptr = NULL;
b.dim = 0;
}
const block_allocator STANDARD_BLOCK_ALLOCATOR { standard_alloc, standard_dealloc };
void
exponential_standard_alloc (block &b, size_t size)
{
if (b.ptr == NULL || b.dim == 0)
{
b.ptr = new char[size];
b.dim = size;
}
else if (size <= b.dim)
{
// do not reduce
}
else
{
size_t new_size;
for (new_size = b.dim; new_size < size; new_size *= 2)
;
char *new_ptr = new char[new_size];
std::memcpy (new_ptr, b.ptr, b.dim);
delete[] b.ptr;
b.ptr = new_ptr;
b.dim = new_size;
}
}
const block_allocator EXPONENTIAL_STANDARD_BLOCK_ALLOCATOR
{
std::bind (exponential_standard_alloc, std::placeholders::_1, std::placeholders::_2),
std::bind (standard_dealloc, std::placeholders::_1)
};
void
cstyle_alloc (block &b, size_t size)
{
if (b.ptr == NULL)
{
b.ptr = (char *) malloc (size);
b.dim = size;
assert (b.ptr != NULL);
}
else
{
b.ptr = (char *) realloc (b.ptr, size);
b.dim = size;
assert (b.ptr != NULL);
}
}
void
cstyle_dealloc (block &b)
{
if (b.ptr != NULL)
{
free (b.ptr);
}
b.ptr = NULL;
b.dim = 0;
}
const block_allocator CSTYLE_BLOCK_ALLOCATOR { cstyle_alloc, cstyle_dealloc };
//
// block_allocator
//
block_allocator::block_allocator (const alloc_func &alloc_f, const dealloc_func &dealloc_f)
: m_alloc_f (alloc_f)
, m_dealloc_f (dealloc_f)
{
}
block_allocator &
block_allocator::operator= (const block_allocator &other)
{
m_alloc_f = other.m_alloc_f;
m_dealloc_f = other.m_dealloc_f;
return *this;
}
//
// single_block_allocator
//
single_block_allocator::single_block_allocator (const block_allocator &base_alloc)
: m_base_allocator (base_alloc)
, m_block {}
, m_allocator { std::bind (&single_block_allocator::allocate, this, std::placeholders::_1, std::placeholders::_2),
std::bind (&single_block_allocator::deallocate, this, std::placeholders::_1) }
{
}
single_block_allocator::~single_block_allocator ()
{
m_base_allocator.m_dealloc_f (m_block);
}
void
single_block_allocator::allocate (block &b, size_t size)
{
// argument should be uninitialized or should be same as m_block; giving a different block may be a logical error
assert (b.ptr == NULL || (b.ptr == m_block.ptr && b.dim == m_block.dim));
m_base_allocator.m_alloc_f (m_block, size);
b.ptr = m_block.ptr;
b.dim = m_block.dim;
}
void
single_block_allocator::deallocate (block &b)
{
// local block remains
b.ptr = NULL;
b.dim = 0;
}
const block_allocator &
single_block_allocator::get_block_allocator () const
{
return m_allocator;
}
const block &
single_block_allocator::get_block() const
{
return m_block;
}
char *
single_block_allocator::get_ptr () const
{
return m_block.ptr;
}
size_t
single_block_allocator::get_size () const
{
return m_block.dim;
}
void
single_block_allocator::reserve (size_t size)
{
m_base_allocator.m_alloc_f (m_block, size);
}
} // namespace cubmem