IODA Bundle
Column.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2012 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 #ifndef odc_core_Column_H
12 #define odc_core_Column_H
13 
14 #include <memory>
15 
16 #include "odc/core/Codec.h"
17 #include "odc/api/ColumnType.h"
18 #include "eckit/sql/SQLTypedefs.h"
19 #include "eckit/os/BackTrace.h"
20 
21 namespace eckit { class DataHandle; }
22 
23 namespace odc {
24 namespace core {
25 
26 //----------------------------------------------------------------------------------------------------------------------
27 
28 class MetaData;
29 
30 class Column {
31 
32 public:
33  Column(MetaData &);
34  Column(const Column&);
35 
36  static const char *columnTypeName(api::ColumnType type);
37 
38  static api::ColumnType type(const std::string&);
39 
40  Column& operator=(const Column&);
41 
42  bool operator==(const Column&) const;
43  bool operator!=(const Column& other) const { return ! (*this == other); }
44  bool equals(const Column& other, bool compareDataSizes=true) const;
45 
46  virtual ~Column();
47 
48  template<typename ByteOrder> void load(DataStream<ByteOrder>& ds);
49  template<typename ByteOrder> void save(DataStream<ByteOrder>& ds);
50 
51  Codec& coder() const { return *coder_; }
52  void coder(std::unique_ptr<Codec> c) { std::swap(coder_, c); }
53 
54  size_t dataSizeDoubles() const { return coder_->dataSizeDoubles(); }
55  void dataSizeDoubles(size_t count) { coder_->dataSizeDoubles(count); }
56 
57  void name(const std::string name) { name_ = name; }
58  const std::string &name() const { return name_; }
59 
60  template <typename ByteOrder> void type(api::ColumnType t);
61  template <typename ByteOrder> void resetCodec();
62 
63  void type(api::ColumnType t) { type_ = t; }
65 
66  bool hasInitialisedCoder() const { return coder_ != 0; }
67  bool isConstant();
68 
69  /// Delegations to Codec:
70 
71  void hasMissing(bool h) { coder_->hasMissing(h); }
72  int32_t hasMissing() const { return coder_->hasMissing(); }
73 
74  void min(double m) { coder_->min(m); }
75  double min() const { return coder_->min(); }
76 
77  void max(double m) { coder_->max(m); }
78  double max() const { return coder_->max(); }
79 
80  void missingValue(double v) { coder_->missingValue(v); }
81  double missingValue() const { return coder_->missingValue(); }
82 
83  void resetStats() { ASSERT(coder_); coder_->resetStats(); }
84 
85  void bitfieldDef(const eckit::sql::BitfieldDef& b) { bitfieldDef_ = b; }
86  const eckit::sql::BitfieldDef& bitfieldDef() const { return bitfieldDef_; }
87 
88  virtual void print(std::ostream& s) const;
89 
90 #ifdef SWIGPYTHON
91  const std::string __repr__()
92  {
93  return //std::string("<") +
95  //+ ">"
96  ;
97  }
98  const std::string __str__() { return name_; }
99 #endif
100 
101  friend std::ostream& operator<<(std::ostream& s, const Column& p)
102  { p.print(s); return s; }
103 
104 private:
105 
107  std::string name_;
108  /// Note: type_ should be ColumnType, but it is saved on file so must be of a fixed size type.
109  int32_t type_;
110  std::unique_ptr<Codec> coder_;
111  /// bitfieldDef_ is not empty if type_ == BITFIELD.
112  eckit::sql::BitfieldDef bitfieldDef_;
113  //std::string typeSignature_;
114 
115 };
116 
117 //----------------------------------------------------------------------------------------------------------------------
118 
119 template <typename ByteOrder>
121 {
122  ds.read(name_);
123  ds.read(type_);
124  if (type_ == api::BITFIELD)
125  {
126  eckit::sql::FieldNames& names(bitfieldDef_.first);
127  eckit::sql::Sizes& sizes(bitfieldDef_.second);
128 
129  static_assert(std::is_same<std::remove_reference<decltype(names)>::type::value_type, std::string>::value, "Format sanity check");
130  static_assert(std::is_same<std::remove_reference<decltype(sizes)>::type::value_type, int32_t>::value, "Format sanity check");
131 
132  names.clear();
133  sizes.clear();
134 
135  ds.read(names);
136  ds.read(sizes);
137  ASSERT(names.size() == sizes.size());
138  }
139 
141 }
142 
143 template <typename ByteOrder>
145 
146  ds.write(name_);
147  ds.write(static_cast<int32_t>(type_));
148 
149  if (type_ == api::BITFIELD) {
150  eckit::sql::FieldNames& names(bitfieldDef_.first);
151  eckit::sql::Sizes& sizes(bitfieldDef_.second);
152 
153  static_assert(std::is_same<std::remove_reference<decltype(names)>::type::value_type, std::string>::value, "Format sanity check");
154  static_assert(std::is_same<std::remove_reference<decltype(sizes)>::type::value_type, int32_t>::value, "Format sanity check");
155  ASSERT(names.size() == sizes.size());
156 
157  ds.write(names);
158  ds.write(sizes);
159  }
160 
161  // And write the coder name
162  ds.write(coder_->name());
163 
164  coder_->save(ds);
165 }
166 
167 template <typename ByteOrder>
169 {
170  using namespace odc::api;
171  type_ = t;
172  std::string codecName;
173  switch (type_)
174  {
175  case INTEGER: codecName = "int32"; break;
176  case BITFIELD:
177  // TODO: 'unsigned_int64'
178  codecName = "int32"; break;
179  case REAL: codecName = "long_real"; break;
180  case DOUBLE: codecName = "long_real"; break;
181  case STRING: codecName = "chars"; break;
182  default:
183  ASSERT(!"Type not supported");
184  break;
185  }
186 
187  coder(CodecFactory::instance().build<ByteOrder>(codecName, t));
188 
189  // TODO: when we have codec unsigned_int64 it will have 0 as
191 }
192 
193 template <typename ByteOrder>
195  int ds = dataSizeDoubles(); // Preserve byte size (part of type information)
196  type<ByteOrder>(static_cast<api::ColumnType>(type_));
197  dataSizeDoubles(ds);
198 }
199 
200 //----------------------------------------------------------------------------------------------------------------------
201 
202 } // namespace core
203 } // namespace odc
204 
205 #endif
static void count(void *counter, const double *data, size_t n)
Definition: UnitTests.cc:531
static double bitfieldMDI()
We always use 0 as MDI of Bitfield columns.
Definition: MDI.h:25
static CodecFactory & instance()
Definition: CodecFactory.cc:25
std::unique_ptr< Codec > load(DataStream< ByteOrder > &ds, api::ColumnType type) const
Definition: CodecFactory.h:154
void bitfieldDef(const eckit::sql::BitfieldDef &b)
Definition: Column.h:85
void resetStats()
Definition: Column.h:83
std::unique_ptr< Codec > coder_
Definition: Column.h:110
Codec & coder() const
Definition: Column.h:51
std::string name_
Definition: Column.h:107
double missingValue() const
Definition: Column.h:81
virtual ~Column()
Definition: Column.cc:40
void hasMissing(bool h)
Delegations to Codec:
Definition: Column.h:71
bool equals(const Column &other, bool compareDataSizes=true) const
Definition: Column.cc:104
size_t dataSizeDoubles() const
Definition: Column.h:54
void load(DataStream< ByteOrder > &ds)
Definition: Column.h:120
virtual void print(std::ostream &s) const
Definition: Column.cc:115
void missingValue(double v)
Definition: Column.h:80
const eckit::sql::BitfieldDef & bitfieldDef() const
Definition: Column.h:86
double min() const
Definition: Column.h:75
MetaData & owner_
Definition: Column.h:106
Column(MetaData &)
Definition: Column.cc:24
static const char * columnTypeName(api::ColumnType type)
Definition: Column.cc:61
api::ColumnType type() const
Definition: Column.h:64
void name(const std::string name)
Definition: Column.h:57
double max() const
Definition: Column.h:78
bool hasInitialisedCoder() const
Definition: Column.h:66
void type(api::ColumnType t)
Definition: Column.h:63
void coder(std::unique_ptr< Codec > c)
Definition: Column.h:52
bool operator!=(const Column &other) const
Definition: Column.h:43
void max(double m)
Definition: Column.h:77
void dataSizeDoubles(size_t count)
Definition: Column.h:55
Column & operator=(const Column &)
Definition: Column.cc:42
bool isConstant()
Definition: Column.cc:89
bool operator==(const Column &) const
return true if names and types are the same; do not compare codecs.
Definition: Column.cc:100
const std::string & name() const
Definition: Column.h:58
eckit::sql::BitfieldDef bitfieldDef_
bitfieldDef_ is not empty if type_ == BITFIELD.
Definition: Column.h:112
int32_t type_
Note: type_ should be ColumnType, but it is saved on file so must be of a fixed size type.
Definition: Column.h:109
friend std::ostream & operator<<(std::ostream &s, const Column &p)
Definition: Column.h:101
void min(double m)
Definition: Column.h:74
void resetCodec()
Definition: Column.h:194
void save(DataStream< ByteOrder > &ds)
Definition: Column.h:144
int32_t hasMissing() const
Definition: Column.h:72
void read(T &elem)
Definition: DataStream.h:205
void write(const T &elem)
Definition: DataStream.h:276
@ BITFIELD
Definition: ColumnType.h:27
Definition: ColumnInfo.h:23