IODA Bundle
CodecOptimizer.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 ///
12 /// \file CodecOptimizer.h
13 ///
14 /// @author Piotr Kuchta, Jan 2010
15 
16 #ifndef odc_core_CodecOptimizer_H
17 #define odc_core_CodecOptimizer_H
18 
19 #include "odc/api/ColumnType.h"
20 #include "odc/codec/Real.h"
21 #include "odc/core/CodecFactory.h"
22 #include "odc/core/MetaData.h"
23 
24 namespace odc {
25 namespace codec {
26 
27 //----------------------------------------------------------------------------------------------------------------------
28 
30 {
31 public:
33  template <typename DATASTREAM>
35 private:
36  static std::map<api::ColumnType, std::string> defaultCodec_;
37 };
38 
39 template <typename ByteOrder>
41 {
42  //std::ostream &LOG = eckit::Log::error();
43  for (size_t i = 0; i < columns.size(); i++) {
44  core::Column& col = *columns[i];
45  long long n;
46  double min = col.min();
47  double max = col.max();
48  bool hasMissing = col.hasMissing();
49  double missing = col.missingValue();
50  //LOG << "CodecOptimizer::setOptimalCodecs: " << i << " " << col.name() << ", min=" << min << ", max=" << max << std::endl;
51  std::string codec(defaultCodec_[col.type()]);
52  switch(col.type())
53  {
54  case api::REAL: {
55 
56  // Currently the real data is (whist in the column) encoded using the LongReal codec.
57  // n.b. CodecOptimizer doesn't currently support OtherByteOrder.
59  ASSERT(codec_long != 0);
60 
61  if (max == min) {
62  codec = col.hasMissing() ? "real_constant_or_missing" : "constant";
63  } else if (codec_long->hasShortReal2InternalMissing()) {
64  ASSERT(!codec_long->hasShortRealInternalMissing());
65  codec = "short_real";
66  } else if (codec_long->hasShortRealInternalMissing()) {
67  codec = "short_real2";
68  }
69 
70  col.coder(core::CodecFactory::instance().build<ByteOrder>(codec, col.type()));
71  col.hasMissing(hasMissing);
72  col.missingValue(missing);
73  col.min(min);
74  col.max(max);
75  //LOG << " REAL has values in range <" << col.min() << ", " << col.max()
76  // << ">. Codec: " << col.coder()
77  // << std::endl;
78  break;
79  }
80 
81  case api::DOUBLE:
82  if(max == min)
83  codec = col.hasMissing() ? "real_constant_or_missing" : "constant";
84  col.coder(core::CodecFactory::instance().build<ByteOrder>(codec, col.type()));
85  col.hasMissing(hasMissing);
86  col.missingValue(missing);
87  col.min(min);
88  col.max(max);
89  //LOG << " DOUBLE has values in range <" << col.min() << ", " << col.max()
90  // << ">. Codec: " << col.coder()
91  // << std::endl;
92  break;
93 
94  case api::STRING:
95  {
96  n = col.coder().numStrings();
97  if (n == 1 && col.coder().dataSizeDoubles() == 1)
98  codec = "constant_string";
99  else if(n < 256)
100  codec = "int8_string";
101  else if(n < 65536)
102  codec = "int16_string";
103 
104 
105  std::unique_ptr<core::Codec> newCodec = core::CodecFactory::instance().build<ByteOrder>(codec, col.type());
106  if (codec == "constant_string") {
107  ASSERT(col.coder().dataSizeDoubles() == 1);
108  } else {
109  newCodec->dataSizeDoubles(col.coder().dataSizeDoubles());
110  newCodec->copyStrings(col.coder());
111  }
112  col.coder(std::move(newCodec));
113  col.hasMissing(hasMissing);
114  col.missingValue(missing);
115  col.min(min);
116  col.max(max);
117  //LOG << " STRING has " << n << " different value(s). Codec: " << codec
118  // << std::endl;
119  }
120  break;
121 
122  case api::BITFIELD:
123  case api::INTEGER:
124  n = max - min;
125  //LOG << " { min=" << min << ", max=" << max << ", n=" << n << "} ";
126  if(col.hasMissing())
127  {
128  if(n == 0) codec = "constant_or_missing";
129  else if(n < 0xff) codec = "int8_missing";
130  else if(n < 0xffff) codec = "int16_missing";
131  }
132  else
133  {
134  if(n == 0) codec = "constant";
135  else if(n <= 0xff) codec = "int8";
136  else if(n <= 0xffff) codec = "int16";
137  }
138  col.coder(core::CodecFactory::instance().build<ByteOrder>(codec, col.type()));
139  col.hasMissing(hasMissing);
140  col.missingValue(missing);
141  col.min(min);
142  col.max(max);
143  //LOG << (col.type() == BITFIELD ? " BITFIELD" : " INTEGER")
144  // << " has " << n + 1 << " different value(s)"
145  // << (col.hasMissing() ? " and has missing value. " : ". ")
146  // << "Codec: " << col.coder() << "."
147  // << std::endl;
148  break;
149 
150  default: eckit::Log::error() << "Unsupported type: [" << col.type() << "]" << std::endl;
151  break;
152  }
153 
154  //if (odc::ODBAPISettings::debug && i == 28) eckit::Log::info() << ": AFTER " << col << " -> " << col.coder() << std::endl;
155  }
156  return 0;
157 }
158 
159 //----------------------------------------------------------------------------------------------------------------------
160 
161 } // namespace codec
162 } // namespace odc
163 
164 #endif
bool hasShortReal2InternalMissing() const
Definition: Real.h:45
bool hasShortRealInternalMissing() const
Definition: Real.h:44
int setOptimalCodecs(core::MetaData &columns)
static std::map< api::ColumnType, std::string > defaultCodec_
std::unique_ptr< Codec > build(const std::string &name, api::ColumnType type) const
Definition: CodecFactory.h:145
static CodecFactory & instance()
Definition: CodecFactory.cc:25
virtual size_t numStrings() const
Definition: Codec.h:76
virtual size_t dataSizeDoubles() const
Definition: Codec.h:79
Codec & coder() const
Definition: Column.h:51
void hasMissing(bool h)
Delegations to Codec:
Definition: Column.h:71
void missingValue(double v)
Definition: Column.h:80
void max(double m)
Definition: Column.h:77
static api::ColumnType type(const std::string &)
Definition: Column.cc:74
void min(double m)
Definition: Column.h:74
@ BITFIELD
Definition: ColumnType.h:27
Definition: ColumnInfo.h:23