casacore
Loading...
Searching...
No Matches
SimpleColumnarFile.h
Go to the documentation of this file.
1#ifndef CASACORE_COLUMNAR_FILE_H_
2#define CASACORE_COLUMNAR_FILE_H_
3
4#include <cassert>
5#include <complex>
6#include <cstdint>
7#include <string>
8#include <vector>
9
10#include "BitPacking.h"
11#include "RowBasedFile.h"
12
13namespace casacore {
14
25 public:
35
36 SimpleColumnarFile() noexcept = default;
37
41
42 ~SimpleColumnarFile() noexcept = default;
43
45 RowBasedFile::operator=(std::move(rhs));
46 std::swap(packed_buffer_, rhs.packed_buffer_);
47 return *this;
48 }
49
50 static SimpleColumnarFile CreateNew(const std::string& filename,
51 uint64_t header_size, uint64_t stride) {
52 return SimpleColumnarFile(filename, header_size, stride);
53 }
54
55 static SimpleColumnarFile OpenExisting(const std::string& filename,
56 size_t header_size) {
57 return SimpleColumnarFile(filename, header_size);
58 }
59
60 void Read(uint64_t row, uint64_t column_offset, std::complex<float>* data,
61 uint64_t n) {
62 ReadImplementation(row, column_offset, data, n);
63 }
64 void Read(uint64_t row, uint64_t column_offset, float* data, uint64_t n) {
65 ReadImplementation(row, column_offset, data, n);
66 }
67 void Read(uint64_t row, uint64_t column_offset, double* data, uint64_t n) {
68 ReadImplementation(row, column_offset, data, n);
69 }
70 void Read(uint64_t row, uint64_t column_offset, int32_t* data, uint64_t n) {
71 ReadImplementation(row, column_offset, data, n);
72 }
73 void Read(uint64_t row, uint64_t column_offset, bool* data, uint64_t n) {
74 const size_t byte_size = (n + 7) / 8;
75 assert(column_offset + byte_size <= Stride());
76 if (row >= NRows()) {
77 std::fill_n(data, n, false);
78 } else {
79 Seek(row * Stride() + column_offset + DataLocation(), SEEK_SET);
80 ReadData(packed_buffer_.data(), byte_size);
81 UnpackBoolArray(data, packed_buffer_.data(), n);
82 }
83 }
84 void Write(uint64_t row, uint64_t column_offset,
85 const std::complex<float>* data, uint64_t n) {
86 WriteImplementation(row, column_offset, data, n);
87 }
88 void Write(uint64_t row, uint64_t column_offset,
89 const std::complex<double>* data, uint64_t n) {
90 WriteImplementation(row, column_offset, data, n);
91 }
92 void Write(uint64_t row, uint64_t column_offset, const float* data,
93 uint64_t n) {
94 WriteImplementation(row, column_offset, data, n);
95 }
96 void Write(uint64_t row, uint64_t column_offset, const double* data,
97 uint64_t n) {
98 WriteImplementation(row, column_offset, data, n);
99 }
100 void Write(uint64_t row, uint64_t column_offset, const int32_t* data,
101 uint64_t n) {
102 WriteImplementation(row, column_offset, data, n);
103 }
104 void Write(uint64_t row, uint64_t column_offset, const bool* data,
105 uint64_t n) {
106 const size_t byte_size = (n + 7) / 8;
107 assert(column_offset + byte_size <= Stride());
108 PackBoolArray(packed_buffer_.data(), data, n);
109 Seek(row * Stride() + column_offset + DataLocation(), SEEK_SET);
110 WriteData(packed_buffer_.data(), byte_size);
111 SetNRows(std::max(row + 1, NRows()));
112 }
113
118 void SetStride(uint64_t new_stride) {
119 RowBasedFile::SetStride(new_stride);
120 packed_buffer_.resize((new_stride + 7) / 8);
121 }
122
123 private:
124 // Create or overwrite a new columnar file on disk
125 SimpleColumnarFile(const std::string& filename, uint64_t header_size,
126 uint64_t stride)
127 : RowBasedFile(filename, header_size, stride),
128 packed_buffer_((stride + 7) / 8) {}
129
130 // Open an existing columnar file
131 SimpleColumnarFile(const std::string& filename, size_t header_size)
132 : RowBasedFile(filename, header_size) {
133 packed_buffer_.resize((Stride() + 7) / 8);
134 }
135
136 template <typename ValueType>
137 void ReadImplementation(uint64_t row, uint64_t column_offset, ValueType* data,
138 uint64_t n) {
139 assert(column_offset + n * sizeof(ValueType) <= Stride());
140 if (row >= NRows()) {
141 std::fill_n(data, n, ValueType());
142 } else {
143 Seek(row * Stride() + column_offset + DataLocation(), SEEK_SET);
144 ReadData(reinterpret_cast<unsigned char*>(data), n * sizeof(ValueType));
145 }
146 }
147
148 template <typename ValueType>
149 void WriteImplementation(uint64_t row, uint64_t column_offset,
150 const ValueType* data, uint64_t n) {
151 assert(column_offset + n * sizeof(ValueType) <= Stride());
152 Seek(row * Stride() + column_offset + DataLocation(), SEEK_SET);
153 WriteData(reinterpret_cast<const unsigned char*>(data),
154 n * sizeof(ValueType));
155 SetNRows(std::max(row + 1, NRows()));
156 }
157
162 std::vector<unsigned char> packed_buffer_;
163};
164
165} // namespace casacore
166
167#endif
void UnpackBoolArray(bool *output, const unsigned char *packed_input, size_t n)
Definition BitPacking.h:29
void PackBoolArray(unsigned char *packed_buffer, const bool *input, size_t n)
Definition BitPacking.h:6
void WriteData(const unsigned char *data, uint64_t size)
void Seek(off_t pos, int seek_direction)
uint64_t DataLocation() const
Offset of the first row in the file.
void SetStride(uint64_t new_stride)
Set the number of bytes per row for this file.
void ReadHeader(unsigned char *data)
Read an optional extra header to the file.
const std::string & Filename() const
RowBasedFile & operator=(RowBasedFile &&rhs)
void WriteHeader(const unsigned char *data)
Write an optional extra header to the file.
void AddRows(uint64_t n_rows)
Adds a given number of rows to the back of the file.
uint64_t NRows() const
Total number of rows stored in this file.
void ReadData(unsigned char *data, uint64_t size)
void DeleteRow()
Deletes the last row.
uint64_t Stride() const
Total number of bytes in one row.
void SetNRows(uint64_t new_n_rows)
void Close()
Close the file.
Class that provides binary table I/O.
void Write(uint64_t row, uint64_t column_offset, const bool *data, uint64_t n)
void ReadImplementation(uint64_t row, uint64_t column_offset, ValueType *data, uint64_t n)
void Read(uint64_t row, uint64_t column_offset, std::complex< float > *data, uint64_t n)
void Read(uint64_t row, uint64_t column_offset, bool *data, uint64_t n)
void Read(uint64_t row, uint64_t column_offset, int32_t *data, uint64_t n)
static SimpleColumnarFile OpenExisting(const std::string &filename, size_t header_size)
void Read(uint64_t row, uint64_t column_offset, double *data, uint64_t n)
void WriteImplementation(uint64_t row, uint64_t column_offset, const ValueType *data, uint64_t n)
SimpleColumnarFile(const std::string &filename, size_t header_size)
Open an existing columnar file.
void Write(uint64_t row, uint64_t column_offset, const std::complex< float > *data, uint64_t n)
std::vector< unsigned char > packed_buffer_
This buffer is used temporarily for (un)packing booleans.
void Write(uint64_t row, uint64_t column_offset, const std::complex< double > *data, uint64_t n)
void Write(uint64_t row, uint64_t column_offset, const float *data, uint64_t n)
SimpleColumnarFile() noexcept=default
void Read(uint64_t row, uint64_t column_offset, float *data, uint64_t n)
static SimpleColumnarFile CreateNew(const std::string &filename, uint64_t header_size, uint64_t stride)
uint64_t NRows() const
Total number of rows stored in this file.
void SetStride(uint64_t new_stride)
Set the number of bytes per row for this file.
void Write(uint64_t row, uint64_t column_offset, const int32_t *data, uint64_t n)
void Write(uint64_t row, uint64_t column_offset, const double *data, uint64_t n)
SimpleColumnarFile(const std::string &filename, uint64_t header_size, uint64_t stride)
Create or overwrite a new columnar file on disk.
~SimpleColumnarFile() noexcept=default
uint64_t Stride() const
Total number of bytes in one row.
this file contains all the compiler specific defines
Definition mainpage.dox:28
Define real & complex conjugation for non-complex types and put comparisons into std namespace.
Definition Complex.h:350