libdballe  8.6
summary.h
1 #ifndef DBALLE_DB_SUMMARY_H
2 #define DBALLE_DB_SUMMARY_H
3 
4 #include <dballe/core/fwd.h>
5 #include <dballe/core/defs.h>
6 #include <dballe/core/query.h>
7 #include <dballe/core/smallset.h>
8 #include <dballe/db/db.h>
9 #include <vector>
10 #include <set>
11 #include <functional>
12 
13 namespace dballe {
14 namespace db {
15 namespace summary {
16 
20 struct VarDesc
21 {
22  dballe::Level level;
23  dballe::Trange trange;
24  wreport::Varcode varcode;
25 
26  VarDesc() = default;
27 
28  VarDesc(const dballe::Level& level, const dballe::Trange& trange, wreport::Varcode varcode)
29  : level(level), trange(trange), varcode(varcode) {}
30 
31  VarDesc(const VarDesc&) = default;
32 
33  bool operator==(const VarDesc& o) const { return std::tie(level, trange, varcode) == std::tie(o.level, o.trange, o.varcode); }
34  bool operator!=(const VarDesc& o) const { return std::tie(level, trange, varcode) != std::tie(o.level, o.trange, o.varcode); }
35  bool operator< (const VarDesc& o) const { return std::tie(level, trange, varcode) < std::tie(o.level, o.trange, o.varcode); }
36  bool operator<=(const VarDesc& o) const { return std::tie(level, trange, varcode) <= std::tie(o.level, o.trange, o.varcode); }
37  bool operator> (const VarDesc& o) const { return std::tie(level, trange, varcode) > std::tie(o.level, o.trange, o.varcode); }
38  bool operator>=(const VarDesc& o) const { return std::tie(level, trange, varcode) >= std::tie(o.level, o.trange, o.varcode); }
39 };
40 
44 struct VarEntry
45 {
46  VarDesc var;
47 
48  dballe::DatetimeRange dtrange;
49  size_t count = 0;
50 
51  VarEntry() = default;
52 
53  VarEntry(const VarDesc& var, const dballe::DatetimeRange& dtrange, size_t count)
54  : var(var), dtrange(dtrange), count(count)
55  {
56  }
57 
58  VarEntry(const VarEntry&) = default;
59 
60  bool operator==(const VarEntry& o) const { return std::tie(var, dtrange, count) == std::tie(o.var, o.dtrange, o.count); }
61  bool operator!=(const VarEntry& o) const { return std::tie(var, dtrange, count) != std::tie(o.var, o.dtrange, o.count); }
62 
63  void merge(const dballe::DatetimeRange& dtrange, size_t count)
64  {
65  this->dtrange.merge(dtrange);
66  this->count += count;
67  }
68 
69  void to_json(core::JSONWriter& writer) const;
70  static VarEntry from_json(core::json::Stream& in);
71 
72  DBALLE_TEST_ONLY void dump(FILE* out) const;
73 };
74 
75 
76 inline const VarDesc& station_entry_get_value(const VarEntry& item) { return item.var; }
77 
83 template<typename Station>
84 struct StationEntry : protected core::SmallSet<VarEntry, VarDesc, station_entry_get_value>
85 {
86  using SmallSet::iterator;
87  using SmallSet::const_iterator;
88  using SmallSet::reverse_iterator;
89  using SmallSet::const_reverse_iterator;
90  using SmallSet::begin;
91  using SmallSet::end;
92  using SmallSet::rbegin;
93  using SmallSet::rend;
94  using SmallSet::size;
95  using SmallSet::empty;
96  using SmallSet::add;
97  bool operator==(const StationEntry& o) const { return SmallSet::operator==(o); }
98  bool operator!=(const StationEntry& o) const { return SmallSet::operator!=(o); }
99 
100  Station station;
101 
102  StationEntry() = default;
103 
104  template<typename OStation>
105  StationEntry(const Station& station, const StationEntry<OStation>& entry)
106  : station(station)
107  {
108  for (const auto& item: entry)
109  this->add(item);
110  }
111 
112  StationEntry(const Station& station, const VarDesc& vd, const dballe::DatetimeRange& dtrange, size_t count)
113  : station(station)
114  {
115  add(vd, dtrange, count);
116  }
117 
118  StationEntry(const StationEntry& entries, const dballe::Query& query)
119  : station(entries.station)
120  {
121  add_filtered(entries, query);
122  }
123 
124  StationEntry(const StationEntry&) = default;
125 
126  void add(const VarDesc& vd, const dballe::DatetimeRange& dtrange, size_t count);
127  template<typename OStation>
128  void add(const StationEntry<OStation>& entries);
129  void add_filtered(const StationEntry& entries, const dballe::Query& query);
130 
131  void to_json(core::JSONWriter& writer) const;
132  static StationEntry from_json(core::json::Stream& in);
133 
134  DBALLE_TEST_ONLY void dump(FILE* out) const;
135 };
136 
137 
138 template<typename Station>
139 inline const Station& station_entries_get_value(const StationEntry<Station>& item) { return item.station; }
140 
146 template<typename Station>
147 struct StationEntries : protected core::SmallSet<StationEntry<Station>, Station, station_entries_get_value<Station>>
148 {
149  typedef core::SmallSet<StationEntry<Station>, Station, station_entries_get_value<Station>> Parent;
150  typedef typename Parent::iterator iterator;
151  typedef typename Parent::const_iterator const_iterator;
152  typedef typename Parent::reverse_iterator reverse_iterator;
153  typedef typename Parent::const_reverse_iterator const_reverse_iterator;
154  using Parent::begin;
155  using Parent::end;
156  using Parent::rbegin;
157  using Parent::rend;
158  using Parent::size;
159  using Parent::empty;
160  bool operator==(const StationEntries<Station>& o) const { return Parent::operator==(o); }
161  bool operator!=(const StationEntries<Station>& o) const { return Parent::operator!=(o); }
162 
164  void add(const Station& station, const VarDesc& vd, const dballe::DatetimeRange& dtrange, size_t count);
165 
167  template<typename OStation>
168  void add(const StationEntries<OStation>& entry);
169 
171  void add(const StationEntries<Station>& entry);
172 
174  void add(const StationEntry<Station>& entry);
175 
176  void add_filtered(const StationEntries& entry, const dballe::Query& query);
177 
178  bool has(const Station& station) const { return this->find(station) != this->end(); }
179 
180  const StationEntries& sorted() const { if (this->dirty) this->rearrange_dirty(); return *this; }
181 };
182 
183 
184 template<typename Station>
186 {
187  struct Entry
188  {
189  const summary::StationEntry<Station>& station_entry;
190  const summary::VarEntry& var_entry;
191  Entry(const summary::StationEntry<Station>& station_entry, const summary::VarEntry& var_entry)
192  : station_entry(station_entry), var_entry(var_entry) {}
193  };
194  std::vector<Entry> results;
195  typename std::vector<Entry>::const_iterator cur;
196  bool at_start = true;
197 
198  Cursor(const summary::StationEntries<Station>& entries, const Query& query);
199 
200  bool has_value() const { return !at_start && cur != results.end(); }
201 
202  int remaining() const override
203  {
204  if (at_start) return results.size();
205  return results.end() - cur;
206  }
207 
208  bool next() override
209  {
210  if (at_start)
211  {
212  cur = results.begin();
213  at_start = false;
214  }
215  else if (cur != results.end())
216  ++cur;
217  return cur != results.end();
218  }
219 
220  void discard() override
221  {
222  cur = results.end();
223  }
224 
225  static DBStation _get_dbstation(const DBStation& s) { return s; }
226  static DBStation _get_dbstation(const dballe::Station& station)
227  {
228  DBStation res;
229  res.report = station.report;
230  res.coords = station.coords;
231  res.ident = station.ident;
232  return res;
233  }
234  static int _get_station_id(const DBStation& s) { return s.id; }
235  static int _get_station_id(const dballe::Station& s) { return MISSING_INT; }
236 
237  DBStation get_station() const override
238  {
239  return _get_dbstation(cur->station_entry.station);
240  }
241 
242 #if 0
243  int get_station_id() const override
244  {
245  return _get_station_id(cur->station_entry.station);
246  }
247 
248  Coords get_coords() const override { return cur->station_entry.station.coords; }
249  Ident get_ident() const override { return cur->station_entry.station.ident; }
250  std::string get_report() const override { return cur->station_entry.station.report; }
251 
252  unsigned test_iterate(FILE* dump=0) override
253  {
254  unsigned count;
255  for (count = 0; next(); ++count)
256  ;
257 #if 0
258  if (dump)
259  cur->dump(dump);
260 #endif
261  return count;
262  }
263 #endif
264 
265  Level get_level() const override { return cur->var_entry.var.level; }
266  Trange get_trange() const override { return cur->var_entry.var.trange; }
267  wreport::Varcode get_varcode() const override { return cur->var_entry.var.varcode; }
268  DatetimeRange get_datetimerange() const override { return cur->var_entry.dtrange; }
269  size_t get_count() const override { return cur->var_entry.count; }
270 
271  void enq(impl::Enq& enq) const;
272 };
273 
274 
275 extern template class Cursor<dballe::Station>;
276 extern template class Cursor<dballe::DBStation>;
277 
278 }
279 
280 
284 template<typename Station>
286 {
287 protected:
288  // Summary of items for the currently active filter
290 
295  mutable dballe::DatetimeRange dtrange;
296  mutable size_t count = 0;
297 
298  mutable bool dirty = false;
299 
300  void recompute_summaries() const;
301 
302 public:
303  BaseSummary();
304  BaseSummary(const BaseSummary&) = delete;
305  BaseSummary(BaseSummary&&) = delete;
306  BaseSummary& operator=(const BaseSummary&) = delete;
307  BaseSummary& operator=(BaseSummary&&) = delete;
308 
309  bool operator==(const BaseSummary& o) const
310  {
311  return entries == o.entries;
312  }
313 
314  const summary::StationEntries<Station>& stations() const { if (dirty) recompute_summaries(); return entries.sorted(); }
315  const core::SortedSmallUniqueValueSet<std::string>& reports() const { if (dirty) recompute_summaries(); return m_reports; }
316  const core::SortedSmallUniqueValueSet<dballe::Level>& levels() const { if (dirty) recompute_summaries(); return m_levels; }
317  const core::SortedSmallUniqueValueSet<dballe::Trange>& tranges() const { if (dirty) recompute_summaries(); return m_tranges; }
318  const core::SortedSmallUniqueValueSet<wreport::Varcode>& varcodes() const { if (dirty) recompute_summaries(); return m_varcodes; }
319 
326  const Datetime& datetime_min() const { if (dirty) recompute_summaries(); return dtrange.min; }
327  const Datetime& datetime_max() const { if (dirty) recompute_summaries(); return dtrange.max; }
328  unsigned data_count() const { if (dirty) recompute_summaries(); return count; }
329 
340  std::unique_ptr<dballe::CursorSummary> query_summary(const Query& query) const;
341 
343  void add(const Station& station, const summary::VarDesc& vd, const dballe::DatetimeRange& dtrange, size_t count);
344 
346  void add_cursor(const dballe::CursorSummary& cur);
347 
349  void add_message(const dballe::Message& message);
350 
352  void add_messages(const std::vector<std::shared_ptr<dballe::Message>>& messages);
353 
355  template<typename OSummary>
356  void add_summary(const BaseSummary<OSummary>& summary);
357 
359  void add_filtered(const BaseSummary& summary, const dballe::Query& query);
360 
361 #if 0
362 
368  void merge_entries();
369 #endif
370 
372  void to_json(core::JSONWriter& writer) const;
373 
375  void load_json(core::json::Stream& in);
376 
377  DBALLE_TEST_ONLY void dump(FILE* out) const;
378 };
379 
383 typedef BaseSummary<dballe::Station> Summary;
384 
388 typedef BaseSummary<dballe::DBStation> DBSummary;
389 
390 extern template class BaseSummary<dballe::Station>;
391 extern template void BaseSummary<dballe::Station>::add_summary(const BaseSummary<dballe::Station>&);
392 extern template void BaseSummary<dballe::Station>::add_summary(const BaseSummary<dballe::DBStation>&);
393 extern template class BaseSummary<dballe::DBStation>;
394 extern template void BaseSummary<dballe::DBStation>::add_summary(const BaseSummary<dballe::Station>&);
395 extern template void BaseSummary<dballe::DBStation>::add_summary(const BaseSummary<dballe::DBStation>&);
396 
397 }
398 }
399 
400 #endif
dballe::DatetimeRange::merge
void merge(const DatetimeRange &range)
Merge range into this one, resulting in the smallest range that contains both.
dballe::Station::report
std::string report
Report name for this station.
Definition: types.h:796
dballe::db::summary::Cursor::get_count
size_t get_count() const override
Get the count of elements.
Definition: summary.h:269
dballe::impl::Enq
Class passed to key-value accessors to set values in an invoker-defined way.
Definition: core/enq.h:17
dballe::CursorSummary
Cursor iterating over summary entries.
Definition: cursor.h:97
dballe::Message
A bulletin that has been decoded and physically interpreted.
Definition: message.h:28
dballe::db::summary::StationEntries::add
void add(const Station &station, const VarDesc &vd, const dballe::DatetimeRange &dtrange, size_t count)
Merge the given entry.
dballe::Cursor
Base class for cursors that iterate over DB query results.
Definition: cursor.h:15
dballe::db::summary::Cursor::get_trange
Trange get_trange() const override
Get the time range.
Definition: summary.h:266
dballe::impl::CursorSummary
Cursor iterating over summary entries.
Definition: core/cursor.h:57
dballe::Station
Station information.
Definition: types.h:793
dballe::db::summary::VarEntry
Statistics about a variable.
Definition: summary.h:44
dballe::db::summary::StationEntries
Index of all stations known to a summary.
Definition: summary.h:147
dballe::core::SortedSmallUniqueValueSet< std::string >
dballe::core::SmallSet
Set structure optimized for a small number of items.
Definition: smallset.h:16
dballe::core::json::Stream
Definition: json.h:165
defs.h
dballe::DatetimeRange::max
Datetime max
Upper bound of the range.
Definition: types.h:299
dballe::DBStation
Definition: types.h:850
wreport::Varcode
uint16_t Varcode
dballe::Ident
A station identifier, that can be any string (including the empty string) or a missing value.
Definition: types.h:747
dballe::Station::ident
Ident ident
Mobile station identifier.
Definition: types.h:802
dballe::DatetimeRange
Range of datetimes.
Definition: types.h:294
db.h
dballe::DBStation::id
int id
Database ID of the station.
Definition: types.h:857
dballe::Trange
Information on how a value has been sampled or computed with regards to time.
Definition: types.h:686
dballe::db::summary::Cursor
Definition: summary.h:185
dballe::db::summary::Cursor::has_value
bool has_value() const
Check if the cursor points to a valid value.
Definition: summary.h:200
dballe::Level
Vertical level or layer.
Definition: types.h:624
dballe::db::summary::Cursor::next
bool next() override
Get a new item from the results of a query.
Definition: summary.h:208
dballe::db::summary::StationEntry
Information about a station, and statistics about its variables.
Definition: summary.h:84
dballe::db::BaseSummary
High level objects for working with DB-All.e DB summaries.
Definition: summary.h:285
dballe::db::summary::Cursor::discard
void discard() override
Discard the results that have not been read yet.
Definition: summary.h:220
dballe::db::summary::Cursor::get_station
DBStation get_station() const override
Get the whole station data in a single call.
Definition: summary.h:237
dballe::db::summary::Cursor::remaining
int remaining() const override
Get the number of rows still to be fetched.
Definition: summary.h:202
dballe::DatetimeRange::min
Datetime min
Lower bound of the range.
Definition: types.h:297
dballe::Station::coords
Coords coords
Station coordinates.
Definition: types.h:799
dballe::Datetime
Date and time.
Definition: types.h:164
dballe::db::summary::Cursor::get_varcode
wreport::Varcode get_varcode() const override
Get the variable code.
Definition: summary.h:267
dballe::db::summary::Cursor::Entry
Definition: summary.h:187
dballe::core::JSONWriter
JSON serializer.
Definition: json.h:29
dballe::db::BaseSummary::add_summary
void add_summary(const BaseSummary< OSummary > &summary)
Merge the copy of another summary into this one.
dballe::db::summary::VarDesc
Description of a variable, independent of where and when it was measured.
Definition: summary.h:20
dballe::db::summary::Cursor::get_datetimerange
DatetimeRange get_datetimerange() const override
Get the datetime range.
Definition: summary.h:268
dballe::db::BaseSummary::datetime_min
const Datetime & datetime_min() const
Recompute reports, levels, tranges, and varcodes.
Definition: summary.h:326
dballe::Coords
Coordinates.
Definition: types.h:368
dballe::Query
Query used to filter DB-All.e data.
Definition: query.h:14
dballe::db::summary::Cursor::get_level
Level get_level() const override
Get the level.
Definition: summary.h:265