http://stxxl.sourceforge.net
<dementiev@mpi-sb.mpg.de>
<beckmann@cs.uni-frankfurt.de>
http://www.boost.org/LICENSE_1_0.txt
#ifndef STXXL_TYPED_BLOCK_HEADER
#define STXXL_TYPED_BLOCK_HEADER
#include <stxxl/bits/io/request.h>
#include <stxxl/bits/common/aligned_alloc.h>
#include <stxxl/bits/mng/bid.h>
#ifndef STXXL_VERBOSE_TYPED_BLOCK
#define STXXL_VERBOSE_TYPED_BLOCK STXXL_VERBOSE2
#endif
__STXXL_BEGIN_NAMESPACE
template <unsigned bytes>
class filler_struct__
{
typedef unsigned char byte_type;
byte_type filler_array_[bytes];
public:
filler_struct__() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] filler_struct__ is constructed"); }
};
template <>
class filler_struct__<0>
{
typedef unsigned char byte_type;
public:
filler_struct__() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] filler_struct__<> is constructed"); }
};
template <class T, unsigned Size_>
class element_block
{
public:
typedef T type;
typedef T value_type;
typedef T & reference;
typedef const T & const_reference;
typedef type * pointer;
typedef pointer iterator;
typedef const type * const_iterator;
enum
{
size = Size_
};
T elem[size];
element_block() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] element_block is constructed"); }
reference operator [] (int i)
{
return elem[i];
}
iterator begin()
{
return elem;
}
const_iterator begin() const
{
return elem;
}
const_iterator cbegin() const
{
return begin();
}
iterator end()
{
return elem + size;
}
const_iterator end() const
{
return elem + size;
}
const_iterator cend() const
{
return end();
}
};
template <class T, unsigned Size_, unsigned RawSize_, unsigned NBids_ = 0>
class block_w_bids : public element_block<T, Size_>
{
public:
enum
{
raw_size = RawSize_,
nbids = NBids_
};
typedef BID<raw_size> bid_type;
bid_type ref[nbids];
bid_type & operator () (int i)
{
return ref[i];
}
block_w_bids() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] block_w_bids is constructed"); }
};
template <class T, unsigned Size_, unsigned RawSize_>
class block_w_bids<T, Size_, RawSize_, 0>: public element_block<T, Size_>
{
public:
enum
{
raw_size = RawSize_,
nbids = 0
};
typedef BID<raw_size> bid_type;
block_w_bids() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] block_w_bids<> is constructed"); }
};
template <class T_, unsigned RawSize_, unsigned NBids_, class InfoType_ = void>
class block_w_info :
public block_w_bids<T_, ((RawSize_ - sizeof(BID<RawSize_>) * NBids_ - sizeof(InfoType_)) / sizeof(T_)), RawSize_, NBids_>
{
public:
typedef InfoType_ info_type;
info_type info;
block_w_info() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] block_w_info is constructed"); }
};
template <class T_, unsigned RawSize_, unsigned NBids_>
class block_w_info<T_, RawSize_, NBids_, void>:
public block_w_bids<T_, ((RawSize_ - sizeof(BID<RawSize_>) * NBids_) / sizeof(T_)), RawSize_, NBids_>
{
public:
typedef void info_type;
block_w_info() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] block_w_info<> is constructed"); }
};
template <typename BaseType_, unsigned FillSize_ = 0>
class add_filler :
public BaseType_
{
private:
filler_struct__<FillSize_> filler;
public:
add_filler() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] add_filler is constructed"); }
};
template <typename BaseType_>
class add_filler<BaseType_, 0>:
public BaseType_
{
public:
add_filler() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] add_filler<> is constructed"); }
};
template <typename Tp_, unsigned RawSize_>
class expand_struct :
public add_filler<Tp_, RawSize_ - sizeof(Tp_)>
{ };
template <unsigned RawSize_, class T_, unsigned NRef_ = 0, class InfoType_ = void>
class typed_block :
public expand_struct<block_w_info<T_, RawSize_, NRef_, InfoType_>, RawSize_>
{
typedef expand_struct<block_w_info<T_, RawSize_, NRef_, InfoType_>, RawSize_> Base;
public:
typedef T_ value_type;
typedef value_type & reference;
typedef const value_type & const_reference;
typedef value_type * pointer;
typedef pointer iterator;
typedef const value_type * const_pointer;
typedef const_pointer const_iterator;
enum constants
{
raw_size = RawSize_,
size = Base::size,
has_only_data = (raw_size == (size * sizeof(value_type)))
};
typedef BID<raw_size> bid_type;
typed_block()
{
STXXL_STATIC_ASSERT(sizeof(typed_block) == raw_size);
STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] typed_block is constructed");
#if 0
assert(((long)this) % BLOCK_ALIGN == 0);
#endif
}
#if 0
typed_block(const typed_block & tb)
{
STXXL_STATIC_ASSERT(sizeof(typed_block) == raw_size);
STXXL_MSG("[" << (void *)this << "] typed_block is copy constructed from [" << (void *)&tb << "]");
STXXL_UNUSED(tb);
}
#endif
request_ptr write(const bid_type & bid,
completion_handler on_cmpl = default_completion_handler())
{
STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:write " << FMT_BID(bid));
return bid.storage->awrite(this, bid.offset, raw_size, on_cmpl);
}
request_ptr read(const bid_type & bid,
completion_handler on_cmpl = default_completion_handler())
{
STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:read " << FMT_BID(bid));
return bid.storage->aread(this, bid.offset, raw_size, on_cmpl);
}
static void * operator new (size_t bytes)
{
unsigned_type meta_info_size = bytes % raw_size;
STXXL_VERBOSE1("typed::block operator new: Meta info size: " << meta_info_size);
void * result = aligned_alloc<BLOCK_ALIGN>(bytes - meta_info_size, meta_info_size);
#ifdef STXXL_VALGRIND_TYPED_BLOCK_INITIALIZE_ZERO
memset(result, 0, bytes);
#endif
char * tmp = (char *)result;
tmp += RawSize_;
while (tmp < ((char *)result) + bytes)
{
tmp += RawSize_;
}
return result;
}
static void * operator new[] (size_t bytes)
{
unsigned_type meta_info_size = bytes % raw_size;
STXXL_VERBOSE1("typed::block operator new[]: Meta info size: " << meta_info_size);
void * result = aligned_alloc<BLOCK_ALIGN>(bytes - meta_info_size, meta_info_size);
#ifdef STXXL_VALGRIND_TYPED_BLOCK_INITIALIZE_ZERO
memset(result, 0, bytes);
#endif
char * tmp = (char *)result;
tmp += RawSize_;
while (tmp < ((char *)result) + bytes)
{
tmp += RawSize_;
}
return result;
}
static void * operator new (size_t , void * ptr)
{
return ptr;
}
static void operator delete (void * ptr)
{
aligned_dealloc<BLOCK_ALIGN>(ptr);
}
static void operator delete[] (void * ptr)
{
aligned_dealloc<BLOCK_ALIGN>(ptr);
}
static void operator delete (void *, void *)
{ }
#if 1
~typed_block()
{
STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] typed_block is destructed");
}
#endif
};
__STXXL_END_NAMESPACE
#endif