libdballe  8.3
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  int remaining() const override
201  {
202  if (at_start) return results.size();
203  return results.end() - cur;
204  }
205 
206  bool next() override
207  {
208  if (at_start)
209  {
210  cur = results.begin();
211  at_start = false;
212  }
213  else if (cur != results.end())
214  ++cur;
215  return cur != results.end();
216  }
217 
218  void discard() override
219  {
220  cur = results.end();
221  }
222 
223  static DBStation _get_dbstation(const DBStation& s) { return s; }
224  static DBStation _get_dbstation(const dballe::Station& station)
225  {
226  DBStation res;
227  res.report = station.report;
228  res.coords = station.coords;
229  res.ident = station.ident;
230  return res;
231  }
232  static int _get_station_id(const DBStation& s) { return s.id; }
233  static int _get_station_id(const dballe::Station& s) { return MISSING_INT; }
234 
235  DBStation get_station() const override
236  {
237  return _get_dbstation(cur->station_entry.station);
238  }
239 
240 #if 0
241  int get_station_id() const override
242  {
243  return _get_station_id(cur->station_entry.station);
244  }
245 
246  Coords get_coords() const override { return cur->station_entry.station.coords; }
247  Ident get_ident() const override { return cur->station_entry.station.ident; }
248  std::string get_report() const override { return cur->station_entry.station.report; }
249 
250  unsigned test_iterate(FILE* dump=0) override
251  {
252  unsigned count;
253  for (count = 0; next(); ++count)
254  ;
255 #if 0
256  if (dump)
257  cur->dump(dump);
258 #endif
259  return count;
260  }
261 #endif
262 
263  Level get_level() const override { return cur->var_entry.var.level; }
264  Trange get_trange() const override { return cur->var_entry.var.trange; }
265  wreport::Varcode get_varcode() const override { return cur->var_entry.var.varcode; }
266  DatetimeRange get_datetimerange() const override { return cur->var_entry.dtrange; }
267  size_t get_count() const override { return cur->var_entry.count; }
268 
269  void enq(impl::Enq& enq) const;
270 };
271 
272 
273 extern template class Cursor<dballe::Station>;
274 extern template class Cursor<dballe::DBStation>;
275 
276 }
277 
278 
282 template<typename Station>
284 {
285 protected:
286  // Summary of items for the currently active filter
288 
293  mutable dballe::DatetimeRange dtrange;
294  mutable size_t count = 0;
295 
296  mutable bool dirty = false;
297 
298  void recompute_summaries() const;
299 
300 public:
301  BaseSummary();
302  BaseSummary(const BaseSummary&) = delete;
303  BaseSummary(BaseSummary&&) = delete;
304  BaseSummary& operator=(const BaseSummary&) = delete;
305  BaseSummary& operator=(BaseSummary&&) = delete;
306 
307  bool operator==(const BaseSummary& o) const
308  {
309  return entries == o.entries;
310  }
311 
312  const summary::StationEntries<Station>& stations() const { if (dirty) recompute_summaries(); return entries.sorted(); }
313  const core::SortedSmallUniqueValueSet<std::string>& reports() const { if (dirty) recompute_summaries(); return m_reports; }
314  const core::SortedSmallUniqueValueSet<dballe::Level>& levels() const { if (dirty) recompute_summaries(); return m_levels; }
315  const core::SortedSmallUniqueValueSet<dballe::Trange>& tranges() const { if (dirty) recompute_summaries(); return m_tranges; }
316  const core::SortedSmallUniqueValueSet<wreport::Varcode>& varcodes() const { if (dirty) recompute_summaries(); return m_varcodes; }
317 
324  const Datetime& datetime_min() const { if (dirty) recompute_summaries(); return dtrange.min; }
325  const Datetime& datetime_max() const { if (dirty) recompute_summaries(); return dtrange.max; }
326  unsigned data_count() const { if (dirty) recompute_summaries(); return count; }
327 
338  std::unique_ptr<dballe::CursorSummary> query_summary(const Query& query) const;
339 
341  void add(const Station& station, const summary::VarDesc& vd, const dballe::DatetimeRange& dtrange, size_t count);
342 
344  void add_cursor(const dballe::CursorSummary& cur);
345 
347  void add_message(const dballe::Message& message);
348 
350  void add_messages(const std::vector<std::shared_ptr<dballe::Message>>& messages);
351 
353  template<typename OSummary>
354  void add_summary(const BaseSummary<OSummary>& summary);
355 
357  void add_filtered(const BaseSummary& summary, const dballe::Query& query);
358 
359 #if 0
360 
366  void merge_entries();
367 #endif
368 
370  void to_json(core::JSONWriter& writer) const;
371 
373  void load_json(core::json::Stream& in);
374 
375  DBALLE_TEST_ONLY void dump(FILE* out) const;
376 };
377 
382 
387 
388 extern template class BaseSummary<dballe::Station>;
391 extern template class BaseSummary<dballe::DBStation>;
394 
395 }
396 }
397 
398 #endif
const Datetime & datetime_min() const
Recompute reports, levels, tranges, and varcodes.
Definition: summary.h:324
Ident ident
Mobile station identifier.
Definition: types.h:799
Class passed to key-value accessors to set values in an invoker-defined way.
Definition: core/enq.h:17
Definition: json.h:165
Station information.
Definition: types.h:790
Level get_level() const override
Get the level.
Definition: summary.h:263
Description of a variable, independent of where and when it was measured.
Definition: summary.h:20
Information about a station, and statistics about its variables.
Definition: summary.h:84
Coords coords
Station coordinates.
Definition: types.h:796
Coordinates.
Definition: types.h:365
Information on how a value has been sampled or computed with regards to time.
Definition: types.h:683
Functions used to connect to DB-All.e and insert, query and delete data.
Trange get_trange() const override
Get the time range.
Definition: summary.h:264
A bulletin that has been decoded and physically interpreted.
Definition: message.h:28
Definition: cmdline.h:18
void add_summary(const BaseSummary< OSummary > &summary)
Merge the copy of another summary into this one.
Cursor iterating over summary entries.
Definition: cursor.h:84
Vertical level or layer.
Definition: types.h:621
A station identifier, that can be any string (including the empty string) or a missing value...
Definition: types.h:744
int remaining() const override
Get the number of rows still to be fetched.
Definition: summary.h:200
uint16_t Varcode
Range of datetimes.
Definition: types.h:291
Definition: summary.h:185
Set structure optimized for a small number of items.
Definition: smallset.h:16
Datetime max
Upper bound of the range.
Definition: types.h:296
std::string report
Report name for this station.
Definition: types.h:793
bool next() override
Get a new item from the results of a query.
Definition: summary.h:206
int id
Database ID of the station.
Definition: types.h:854
Definition: summary.h:187
wreport::Varcode get_varcode() const override
Get the variable code.
Definition: summary.h:265
Datetime min
Lower bound of the range.
Definition: types.h:294
High level objects for working with DB-All.e DB summaries.
Definition: summary.h:283
Statistics about a variable.
Definition: summary.h:44
Query used to filter DB-All.e data.
Definition: query.h:14
Date and time.
Definition: types.h:164
JSON serializer.
Definition: json.h:29
Cursor iterating over summary entries.
Definition: core/cursor.h:57
void discard() override
Discard the results that have not been read yet.
Definition: summary.h:218
Definition: types.h:847
void merge(const DatetimeRange &range)
Merge range into this one, resulting in the smallest range that contains both.
Index of all stations known to a summary.
Definition: summary.h:147
Common definitions.
DBStation get_station() const override
Get the whole station data in a single call.
Definition: summary.h:235
DatetimeRange get_datetimerange() const override
Get the datetime range.
Definition: summary.h:266
size_t get_count() const override
Get the count of elements.
Definition: summary.h:267