IODA
VarAttrStore.hpp
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2020-2021 UCAR
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  */
7 /*! \addtogroup ioda_internals_engines_obsstore
8  *
9  * @{
10  * \file VarAttrStore.hpp
11  * \brief Functions for ObsStore variable and attribute data storage
12  */
13 #pragma once
14 
15 #include <string>
16 #include <vector>
17 
18 #include "gsl/gsl-lite.hpp"
19 
20 #include "./Selection.hpp"
21 #include "./Types.hpp"
22 #include "ioda/Exception.h"
23 
24 namespace ioda {
25 namespace ObsStore {
26 /// \ingroup ioda_internals_engines_obsstore
28 private:
29 public:
31  virtual ~VarAttrStore_Base() {}
32 
33  /// \brief resizes memory allocated for data storage (vector)
34  /// \param newSize new size for allocated memory in number of vector elements
35  virtual void resize(std::size_t newSize) = 0;
36  /// \brief resizes memory allocated for data storage (vector)
37  /// \param newSize new size for allocated memory in number of vector elements
38  /// \param fillvalue new elements get initialized to fillValue
39  virtual void resize(std::size_t newSize, gsl::span<char> &fillValue) = 0;
40  /// \brief transfer data to data storage vector
41  /// \param data contiguous block of data to transfer
42  /// \param m_select Selection ojbect: how to select from data argument
43  /// \param f_select Selection ojbect: how to select to storage vector
44  virtual void write(gsl::span<char> data, Selection &m_select, Selection &f_select) = 0;
45  /// \brief transfer data from data storage vector
46  /// \param data contiguous block of data to transfer
47  /// \param m_select Selection ojbect: how to select to data argument
48  /// \param f_select Selection ojbect: how to select from storage vector
49  virtual void read(gsl::span<char> data, Selection &m_select, Selection &f_select) const = 0;
50 };
51 
52 // Templated versions for each data type
53 /// \ingroup ioda_internals_engines_obsstore
54 template <typename DataType>
56 private:
57  /// \brief data storage mechanism (vector)
58  std::vector<DataType> var_attr_data_;
59 
60 public:
63 
64  /// \brief resizes memory allocated for data storage (vector)
65  /// \param newSize new size for allocated memory in number of vector elements
66  void resize(std::size_t newSize) override { var_attr_data_.resize(newSize); }
67 
68  /// \brief resizes memory allocated for data storage (vector)
69  /// \param newSize new size for allocated memory in number of vector elements
70  /// \param fillvalue new elements get initialized to fillValue
71  void resize(std::size_t newSize, gsl::span<char> &fillValue) override {
72  gsl::span<DataType> fv_span(reinterpret_cast<DataType *>(fillValue.data()), 1);
73  var_attr_data_.resize(newSize, fv_span[0]);
74  }
75 
76  /// \brief transfer data to data storage vector
77  /// \param data contiguous block of data to transfer
78  /// \param m_select Selection ojbect: how to select from data argument
79  /// \param f_select Selection ojbect: how to select to storage vector
80  void write(gsl::span<char> data, Selection &m_select, Selection &f_select) override {
81  std::size_t numObjects = data.size() / sizeof(DataType);
82  gsl::span<DataType> d_span(reinterpret_cast<DataType *>(data.data()), numObjects);
83  // assumes m_select and f_select have same number of points
84  m_select.init_lin_indx();
85  f_select.init_lin_indx();
86  while (!m_select.end_lin_indx()) {
87  std::size_t m_indx = m_select.next_lin_indx();
88  std::size_t f_indx = f_select.next_lin_indx();
89  var_attr_data_[f_indx] = d_span[m_indx];
90  }
91  }
92 
93  /// \brief transfer data from data storage vector
94  /// \param data contiguous block of data to transfer
95  /// \param m_select Selection ojbect: how to select to data argument
96  /// \param f_select Selection ojbect: how to select from storage vector
97  void read(gsl::span<char> data, Selection &m_select, Selection &f_select) const override {
98  std::size_t datumLen = sizeof(DataType);
99  std::size_t numChars = var_attr_data_.size() * datumLen;
100  gsl::span<char> c_span(
101  const_cast<char *>(reinterpret_cast<const char *>(var_attr_data_.data())), numChars);
102  // assumes m_select and f_select have same number of points
103  m_select.init_lin_indx();
104  f_select.init_lin_indx();
105  while (!m_select.end_lin_indx()) {
106  std::size_t m_indx = m_select.next_lin_indx() * datumLen;
107  std::size_t f_indx = f_select.next_lin_indx() * datumLen;
108  for (std::size_t i = 0; i < datumLen; ++i) {
109  data[m_indx + i] = c_span[f_indx + i];
110  }
111  }
112  }
113 };
114 
115 // Specialization for std::string data type
116 /// \ingroup ioda_internals_engines_obsstore
117 template <>
118 class VarAttrStore<std::string> : public VarAttrStore_Base {
119 private:
120  /// \brief data storage mechanism (vector)
121  std::vector<std::string> var_attr_data_;
122 
123 public:
126 
127  /// \brief resizes memory allocated for data storage (vector)
128  /// \param newSize new size for allocated memory in number of vector elements
129  void resize(std::size_t newSize) override { var_attr_data_.resize(newSize); }
130 
131  /// \brief resizes memory allocated for data storage (vector)
132  /// \param newSize new size for allocated memory in number of vector elements
133  /// \param fillvalue new elements get initialized to fillValue
134  void resize(std::size_t newSize, gsl::span<char> &fillValue) override {
135  // At this point, fillValue[0] is a char * pointing to the string
136  // to be used for a fill value.
137  gsl::span<char *> fv_span(reinterpret_cast<char **>(fillValue.data()), 1);
138  var_attr_data_.resize(newSize, fv_span[0]);
139  }
140 
141  /// \brief transfer data to data storage vector
142  /// \param data contiguous block of data to transfer
143  /// \param m_select Selection object: how to select from data argument
144  /// \param f_select Selection object: how to select to storage vector
145  void write(gsl::span<char> data, Selection &m_select, Selection &f_select) override {
146  // data is a series of char * pointing to null terminated strings
147  // first place the char * values in a vector
148  std::size_t numObjects = data.size() / sizeof(char *);
149  gsl::span<char *> d_span(reinterpret_cast<char **>(data.data()), numObjects);
150  std::vector<char *> inStrings(numObjects);
151  for (std::size_t i = 0; i < numObjects; ++i) {
152  inStrings[i] = d_span[i];
153  }
154 
155  // assumes m_select and f_select have same number of points
156  m_select.init_lin_indx();
157  f_select.init_lin_indx();
158  while (!m_select.end_lin_indx()) {
159  std::size_t m_indx = m_select.next_lin_indx();
160  std::size_t f_indx = f_select.next_lin_indx();
161  var_attr_data_[f_indx] = inStrings[m_indx];
162  }
163  }
164 
165  /// \brief transfer data from data storage vector
166  /// \param data contiguous block of data to transfer
167  /// \param m_select Selection ojbect: how to select to data argument
168  /// \param f_select Selection ojbect: how to select from storage vector
169  void read(gsl::span<char> data, Selection &m_select, Selection &f_select) const override {
170  // First create a vector of char * pointers to each item in var_attr_data_.
171  std::size_t numObjects = var_attr_data_.size();
172  std::vector<const char *> outStrings(numObjects);
173  for (std::size_t i = 0; i < numObjects; ++i) {
174  outStrings[i] = var_attr_data_[i].data();
175  }
176 
177  std::size_t datumLen = sizeof(char *);
178  std::size_t numChars = outStrings.size() * datumLen;
179  gsl::span<char> c_span(reinterpret_cast<char *>(outStrings.data()), numChars);
180  // assumes m_select and f_select have same number of points
181  m_select.init_lin_indx();
182  f_select.init_lin_indx();
183  while (!m_select.end_lin_indx()) {
184  std::size_t m_indx = m_select.next_lin_indx() * datumLen;
185  std::size_t f_indx = f_select.next_lin_indx() * datumLen;
186  for (std::size_t i = 0; i < datumLen; ++i) {
187  data[m_indx + i] = c_span[f_indx + i];
188  }
189  }
190  }
191 };
192 
193 /// \brief factory style function to create a new templated object
194 /// \ingroup ioda_internals_engines_obsstore
196  VarAttrStore_Base *newStore = nullptr;
197 
198  // Use the dtype value to determine which templated version of the data store
199  // to instantiate.
200  if (dtype == ObsTypes::FLOAT) {
201  newStore = new VarAttrStore<float>;
202  } else if (dtype == ObsTypes::DOUBLE) {
203  newStore = new VarAttrStore<double>;
204  } else if (dtype == ObsTypes::LDOUBLE) {
205  newStore = new VarAttrStore<long double>;
206  } else if (dtype == ObsTypes::SCHAR) {
207  newStore = new VarAttrStore<signed char>;
208  } else if (dtype == ObsTypes::SHORT) {
209  newStore = new VarAttrStore<short>;
210  } else if (dtype == ObsTypes::INT) {
211  newStore = new VarAttrStore<int>;
212  } else if (dtype == ObsTypes::LONG) {
213  newStore = new VarAttrStore<long>;
214  } else if (dtype == ObsTypes::LLONG) {
215  newStore = new VarAttrStore<long long>;
216  } else if (dtype == ObsTypes::UCHAR) {
217  newStore = new VarAttrStore<unsigned char>;
218  } else if (dtype == ObsTypes::USHORT) {
219  newStore = new VarAttrStore<unsigned short>;
220  } else if (dtype == ObsTypes::UINT) {
221  newStore = new VarAttrStore<unsigned int>;
222  } else if (dtype == ObsTypes::ULONG) {
223  newStore = new VarAttrStore<unsigned long>;
224  } else if (dtype == ObsTypes::ULLONG) {
225  newStore = new VarAttrStore<unsigned long long>;
226  } else if (dtype == ObsTypes::CHAR) {
227  newStore = new VarAttrStore<char>;
228  } else if (dtype == ObsTypes::WCHAR) {
229  newStore = new VarAttrStore<wchar_t>;
230  } else if (dtype == ObsTypes::CHAR16) {
231  newStore = new VarAttrStore<char16_t>;
232  } else if (dtype == ObsTypes::CHAR32) {
233  newStore = new VarAttrStore<char32_t>;
234  } else if (dtype == ObsTypes::STRING) {
235  newStore = new VarAttrStore<std::string>;
236  } else
237  throw Exception("Unrecognized data type encountered during "
238  "Attribute object construnction", ioda_Here());
239 
240  return newStore;
241 }
242 
243 } // namespace ObsStore
244 } // namespace ioda
245 
246 /// @}
IODA's error system.
Functions for ObsStore Selection.
Functions for ObsStore type markers.
The ioda exception class.
Definition: Exception.h:54
bool end_lin_indx() const
returns true when at the end of the linear memory indices
void init_lin_indx()
initializes iterator for walking through linear memory indices
std::size_t next_lin_indx()
returns next linear memory index
void read(gsl::span< char > data, Selection &m_select, Selection &f_select) const override
transfer data from data storage vector
void resize(std::size_t newSize, gsl::span< char > &fillValue) override
resizes memory allocated for data storage (vector)
void resize(std::size_t newSize) override
resizes memory allocated for data storage (vector)
std::vector< std::string > var_attr_data_
data storage mechanism (vector)
void write(gsl::span< char > data, Selection &m_select, Selection &f_select) override
transfer data to data storage vector
virtual void write(gsl::span< char > data, Selection &m_select, Selection &f_select)=0
transfer data to data storage vector
virtual void resize(std::size_t newSize, gsl::span< char > &fillValue)=0
resizes memory allocated for data storage (vector)
virtual void resize(std::size_t newSize)=0
resizes memory allocated for data storage (vector)
virtual void read(gsl::span< char > data, Selection &m_select, Selection &f_select) const =0
transfer data from data storage vector
std::vector< DataType > var_attr_data_
data storage mechanism (vector)
void resize(std::size_t newSize) override
resizes memory allocated for data storage (vector)
void resize(std::size_t newSize, gsl::span< char > &fillValue) override
resizes memory allocated for data storage (vector)
void read(gsl::span< char > data, Selection &m_select, Selection &f_select) const override
transfer data from data storage vector
void write(gsl::span< char > data, Selection &m_select, Selection &f_select) override
transfer data to data storage vector
@ ObsStore
ObsStore in-memory.
VarAttrStore_Base * createVarAttrStore(ObsTypes dtype)
factory style function to create a new templated object
ObsTypes
ObsStore data type markers.
Definition: Types.hpp:30
#define ioda_Here()