5 #include "boost/shared_ptr.hpp"
36 class Block :
public ndarray::Manager {
38 typedef boost::intrusive_ptr<Block> Ptr;
43 static void reclaim(
std::size_t recordSize,
void *
data, ndarray::Manager::Ptr
const &manager) {
44 Ptr block = boost::static_pointer_cast<Block>(manager);
45 if (
reinterpret_cast<char *
>(
data) + recordSize == block->_next) {
46 block->_next -= recordSize;
53 Ptr block = boost::static_pointer_cast<Block>(manager);
54 if (!block ||
static_cast<std::size_t>(block->_end - block->_next) < recordSize * recordCount) {
55 block = Ptr(
new Block(recordSize, recordCount));
61 Ptr block = boost::static_pointer_cast<Block>(manager);
62 return static_cast<std::size_t>(block->_end - block->_next) / recordSize;
67 static void *get(
std::size_t recordSize, ndarray::Manager::Ptr &manager) {
68 Ptr block = boost::static_pointer_cast<Block>(manager);
69 if (!block || block->_next == block->_end) {
73 void *r = block->_next;
74 block->_next += recordSize;
81 static void padSchema(Schema &
schema) {
82 static int const MIN_RECORD_ALIGN =
sizeof(AllocType);
95 : _mem(new AllocType[(recordSize * recordCount) / sizeof(AllocType)]),
96 _next(reinterpret_cast<char *>(_mem.get())),
97 _end(_next + recordSize * recordCount) {
98 assert((recordSize * recordCount) %
sizeof(AllocType) == 0);
115 return Block::getBufferSize(_schema.
getRecordSize(), _manager);
127 output->assign(input);
133 output->assign(input,
mapper);
138 return std::make_shared<io::FitsWriter>(fitsfile, flags);
146 return constructRecord<BaseRecord>();
150 Block::padSchema(_schema);
161 struct RecordDestroyer {
162 template <
typename T>
165 template <
typename T>
166 void operator()(SchemaItem<Array<T> >
const &item)
const {
167 typedef ndarray::Array<T, 1, 1> Element;
168 if (item.key.isVariableLength()) {
169 (*
reinterpret_cast<Element *
>(
data + item.key.getOffset())).~Element();
173 void operator()(SchemaItem<std::string>
const &item)
const {
174 if (item.key.isVariableLength()) {
177 (*
reinterpret_cast<string *
>(
data + item.key.getOffset())).~string();
186 detail::RecordData BaseTable::_makeNewRecordData() {
188 return detail::RecordData{
195 void BaseTable::_destroy(BaseRecord &record) {
196 assert(record._table.get() ==
this);
197 RecordDestroyer f = {
reinterpret_cast<char *
>(record._data)};
199 if (record._manager == _manager) Block::reclaim(_schema.
getRecordSize(), record._data, _manager);
212 template class CatalogT<BaseRecord>;
213 template class CatalogT<BaseRecord const>;