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);
83 int remainder = schema.getRecordSize() % MIN_RECORD_ALIGN;
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);
150 Block::padSchema(_schema);
161 struct RecordInitializer {
162 template <
typename T>
163 static void fill(T *
element,
int size) {}
165 static void fill(
float *element,
int size) {
169 static void fill(
double *element,
int size) {
174 fill(reinterpret_cast<double *>(element), size);
177 template <
typename T>
180 item.
key.getElementCount());
183 template <
typename T>
185 if (item.
key.isVariableLength()) {
187 new (data + item.
key.getOffset()) ndarray::Array<T, 1, 1>();
190 item.
key.getElementCount());
210 struct RecordDestroyer {
211 template <
typename T>
212 void operator()(SchemaItem<T>
const &item)
const {}
214 template <
typename T>
215 void operator()(SchemaItem<Array<T> >
const &item)
const {
216 typedef ndarray::Array<T, 1, 1> Element;
217 if (item.key.isVariableLength()) {
218 (*
reinterpret_cast<Element *
>(data + item.key.getOffset())).~Element();
222 void operator()(SchemaItem<std::string>
const &item)
const {
223 if (item.key.isVariableLength()) {
226 (*
reinterpret_cast<string *
>(data + item.key.getOffset())).~string();
235 void BaseTable::_initialize(
BaseRecord &record) {
236 record._data = Block::get(_schema.getRecordSize(), _manager);
237 RecordInitializer f = {
reinterpret_cast<char *
>(record._data)};
239 record._manager = _manager;
242 void BaseTable::_destroy(
BaseRecord &record) {
243 assert(record._table.get() ==
this);
244 RecordDestroyer f = {
reinterpret_cast<char *
>(record._data)};
246 if (record._manager == _manager) Block::reclaim(_schema.getRecordSize(), record._data, _manager);
259 template class CatalogT<BaseRecord>;
260 template class CatalogT<BaseRecord const>;
Defines the fields and offsets for a table.
static void padSchema(Schema &schema, int bytes)
int getOffset() const noexcept
Return the offset (in bytes) of this field within a record.
bool isVariableLength() const noexcept
Return true if the field is variable-length (each record can have a different size array)...
A mapping between the keys of two Schemas, used to copy data between them.
void disconnectAliases()
Sever the connection between this schema and any others with which it shares aliases.
virtual std::shared_ptr< BaseRecord > _makeRecord()
Default-construct an associated record (protected implementation).
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
std::shared_ptr< BaseRecord > copyRecord(BaseRecord const &input)
Deep-copy a record, requiring that it have the same schema as this table.
A class representing an angle.
void preallocate(std::size_t nRecords)
Allocate contiguous space for new records in advance.
static int nRecordsPerBlock
Number of records in each memory block.
A base class for image defects.
Tag types used to declare specialized field types.
BaseTable(Schema const &schema)
Construct from a schema.
std::shared_ptr< AliasMap > getAliasMap() const
Return the map of aliases.
Base class for all records.
static std::shared_ptr< BaseTable > make(Schema const &schema)
Construct a new table.
FieldBase< T >::Element Element
Type used to store field data in the table (a field may have multiple elements).
virtual std::shared_ptr< BaseTable > _clone() const
Clone implementation with noncovariant return types.
std::size_t getBufferSize() const
Return the number of additional records space has been already been allocated for.
int getElementCount() const noexcept
Return the number of subfield elements (equal to the size of the string, including a null terminator)...
Base class for all tables.
A simple pair-like struct for mapping a Field (name and description) with a Key (used for actual data...