IODA Bundle
TablesReader.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2018 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 /// @author Simon Smart
12 /// @date Dec 2018
13 
14 #ifndef odc_core_ReadTablesIterator_H
15 #define odc_core_ReadTablesIterator_H
16 
17 #include <cstdint>
18 #include <memory>
19 
20 #include "odc/core/Table.h"
22 
23 
24 namespace eckit { class DataHandle; }
25 
26 namespace odc {
27 namespace core {
28 
29 //----------------------------------------------------------------------------------------------------------------------
30 
31 class TablesReader;
32 
34 
35 public: // methods
36 
37  ReadTablesIterator(TablesReader& owner, long pos=0);
38 
39  // Functionality to work as an iterator
40 
41  bool operator!=(const ReadTablesIterator& other);
42  bool operator==(const ReadTablesIterator& other);
43 
46 
47  Table* operator->();
48  const Table* operator->() const;
49 
50  Table& operator*();
51  const Table& operator*() const;
52 
53 private: // methods
54 
55  friend std::ostream& operator<<(std::ostream& os, const ReadTablesIterator& rti) {
56  os << "ReadTablesIterator(" << &rti.owner_ << ", " << rti.pos_ << ")";
57  return os;
58  }
59 
60 private: // members
61 
63  long pos_;
64 };
65 
66 //----------------------------------------------------------------------------------------------------------------------
67 
68 // TablesReader builds (in a thread safe way) a list of tables that can be queried by
69 // the iterator. This is done lazily. As a result:
70 //
71 // i) Iterators can be instantiated multiple times, but the table structure will only be
72 // read once
73 //
74 // ii) If data is encoded on the fly, it is all read in one pass. This means that for
75 // straightforward workflows, this will work on streaming data that is larger than memory.
76 
77 class TablesReader {
78 
79 public: // types
80 
82 
83 public: // methods
84 
85  TablesReader(eckit::DataHandle& dh);
86  TablesReader(eckit::DataHandle* dh); // n.b. takes ownership
87  TablesReader(const eckit::PathName& path);
88 
89  iterator begin();
90  iterator end();
91 
92 private: // members
93 
94  friend class ReadTablesIterator;
95 
96  bool ensureTable(long idx);
97  Table& getTable(long idx);
98 
99 private: // members
100 
101  std::mutex m_;
102 
103  // Vector of pointers --> objects don't move if vector changes after returning reference to object
104  std::vector<std::unique_ptr<Table>> tables_;
105 
107 };
108 
109 //----------------------------------------------------------------------------------------------------------------------
110 
111 } // namespace core
112 } // namespace odc
113 
114 #endif
friend std::ostream & operator<<(std::ostream &os, const ReadTablesIterator &rti)
Definition: TablesReader.h:55
ReadTablesIterator(TablesReader &owner, long pos=0)
Definition: TablesReader.cc:22
bool operator!=(const ReadTablesIterator &other)
Definition: TablesReader.cc:33
bool operator==(const ReadTablesIterator &other)
Definition: TablesReader.cc:37
ReadTablesIterator & operator++()
Definition: TablesReader.cc:41
Table & getTable(long idx)
TablesReader(const eckit::PathName &path)
std::vector< std::unique_ptr< Table > > tables_
Definition: TablesReader.h:104
ThreadSharedDataHandle dh_
Definition: TablesReader.h:106
bool ensureTable(long idx)
TablesReader(eckit::DataHandle &dh)
Definition: TablesReader.cc:82
friend class ReadTablesIterator
Definition: TablesReader.h:94
Definition: ColumnInfo.h:23