bes  Updated for version 3.20.10
DmrppArray.h
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of the BES
4 
5 // Copyright (c) 2016 OPeNDAP, Inc.
6 // Author: James Gallagher <jgallagher@opendap.org>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 //
22 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
23 
24 #ifndef _dmrpp_array_h
25 #define _dmrpp_array_h 1
26 
27 #include <string>
28 #include <utility>
29 #include <vector>
30 #include <thread>
31 #include <memory>
32 #include <queue>
33 #include <future>
34 #include <list>
35 
36 #include <libdap/Array.h>
37 
38 #include "DmrppCommon.h"
39 #include "SuperChunk.h"
40 
41 // The 'read_serial()' method is more closely related to the original code
42 // used to read data when the DMR++ handler was initially developed for NASA.
43 // I modified that code for a while when we built the prototype version of
44 // the handler, but then morphed that into a version that would support parallel
45 // access. Defining this symbol will include the old code in the handler,
46 // although the DmrppArray::read() method will still have to be hacked to
47 // use it. jhrg 5/10/18
48 #undef USE_READ_SERIAL
49 
50 namespace libdap {
51 class XMLWriter;
52 }
53 
54 namespace dmrpp {
55 
56  class SuperChunk;
68 class DmrppArray : public libdap::Array, public dmrpp::DmrppCommon {
69 
70 private:
71  //void _duplicate(const DmrppArray &ts);
72 
73  bool is_projected();
74 
75  DmrppArray::dimension get_dimension(unsigned int dim_num);
76 
77  void insert_constrained_contiguous(Dim_iter dim_iter, unsigned long *target_index,
78  std::vector<unsigned long long> &subset_addr,
79  const std::vector<unsigned long long> &array_shape, char *data);
80 
81  void read_contiguous();
82 
83 #ifdef USE_READ_SERIAL
84  virtual void insert_chunk_serial(unsigned int dim, std::vector<unsigned int> *target_element_address,
85  std::vector<unsigned int> *chunk_source_address, Chunk *chunk);
86  virtual void read_chunks_serial();
87 #endif
88 
89  friend class DmrppArrayTest;
90  // Called from read_chunks_unconstrained() and also using pthreads
91  friend void
92  process_one_chunk_unconstrained(std::shared_ptr<Chunk> chunk, const vector<unsigned long long> &chunk_shape,
93  DmrppArray *array, const vector<unsigned long long> &array_shape);
94 
95  // Called from read_chunks()
96  friend void
97  process_one_chunk(std::shared_ptr<Chunk> chunk, DmrppArray *array, const vector<unsigned long long> &constrained_array_shape);
98 
99 
100 
101  virtual void insert_chunk_unconstrained(std::shared_ptr<Chunk> chunk, unsigned int dim,
102  unsigned long long array_offset, const std::vector<unsigned long long> &array_shape,
103  unsigned long long chunk_offset, const std::vector<unsigned long long> &chunk_shape,
104  const std::vector<unsigned long long> &chunk_origin);
105 
106  void read_chunks();
107  void read_chunks_unconstrained();
108 
109  unsigned long long get_chunk_start(const dimension &thisDim, unsigned int chunk_origin_for_dim);
110 
111  std::shared_ptr<Chunk> find_needed_chunks(unsigned int dim, std::vector<unsigned long long> *target_element_address, std::shared_ptr<Chunk> chunk);
112 
113  virtual void insert_chunk(
114  unsigned int dim,
115  std::vector<unsigned long long> *target_element_address,
116  std::vector<unsigned long long> *chunk_element_address,
117  std::shared_ptr<Chunk> chunk,
118  const vector<unsigned long long> &constrained_array_shape);
119 
120 public:
121  DmrppArray(const std::string &n, libdap::BaseType *v) : libdap::Array(n, v, true /*is dap4*/), DmrppCommon() { }
122 
123  DmrppArray(const std::string &n, const std::string &d, libdap::BaseType *v) :
124  libdap::Array(n, d, v, true), DmrppCommon() { }
125 
126  DmrppArray(const string &n, BaseType *v, shared_ptr<DMZ> dmz) :
127  libdap::Array(n, v, true), DmrppCommon(dmz) { }
128 
129  DmrppArray(const string &n, const string &d, BaseType *v, shared_ptr<DMZ> dmz) :
130  libdap::Array(n, d, v, true), DmrppCommon(dmz) { }
131 
132  DmrppArray(const DmrppArray &) = default;
133 
134  virtual ~DmrppArray() = default;
135 
136  DmrppArray &operator=(const DmrppArray &rhs);
137 
138  virtual libdap::BaseType *ptr_duplicate() { return new DmrppArray(*this); }
139 
140  bool read() override;
141  void set_send_p(bool state) override;
142 
143  virtual unsigned long long get_size(bool constrained = false);
144 
145  virtual std::vector<unsigned long long> get_shape(bool constrained);
146 
147  virtual void print_dap4(libdap::XMLWriter &writer, bool constrained = false);
148 
149  virtual void dump(ostream &strm) const;
150 };
151 
156  std::thread::id parent_thread_id;
157  std::shared_ptr<SuperChunk> super_chunk;
158  DmrppArray *array;
159 
160  one_super_chunk_args(std::shared_ptr<SuperChunk> sc, DmrppArray *a)
161  : parent_thread_id(std::this_thread::get_id()), super_chunk(std::move(sc)), array(a) {}
162 };
163 
164 
170  int *fds; // pipe back to parent
171  unsigned char tid; // thread id as a byte
172  std::shared_ptr<Chunk> child_chunk; // this chunk reads data; temporary allocation
173  std::shared_ptr<Chunk> master_chunk; // this chunk gets the data; shared memory, managed by DmrppArray
174 
175  one_child_chunk_args(int *pipe, unsigned char id, std::shared_ptr<Chunk> c_c, std::shared_ptr<Chunk> m_c)
176  : fds(pipe), tid(id), child_chunk(c_c), master_chunk(m_c) {}
177 
178  ~one_child_chunk_args() { }
179 };
180 
181 
187  std::shared_ptr<Chunk> child_chunk; // this chunk reads data; temporary allocation
188  std::shared_ptr<Chunk> the_one_chunk; // this chunk gets the data; shared memory, managed by DmrppArray
189 
190  one_child_chunk_args_new(std::shared_ptr<Chunk> c_c, std::shared_ptr<Chunk> m_c) : child_chunk(c_c), the_one_chunk(m_c) {}
191 
193 };
194 
195 
196 bool get_next_future(list<std::future<bool>> &futures, atomic_uint &thread_counter, unsigned long timeout, string debug_prefix);
197 
198 } // namespace dmrpp
199 
200 #endif // _dmrpp_array_h
201 
Extend libdap::Array so that a handler can read data using a DMR++ file.
Definition: DmrppArray.h:68
virtual std::vector< unsigned long long > get_shape(bool constrained)
Get the array shape.
Definition: DmrppArray.cc:596
virtual unsigned long long get_size(bool constrained=false)
Return the total number of elements in this Array.
Definition: DmrppArray.cc:580
bool read() override
Read data for the array.
Definition: DmrppArray.cc:1460
virtual void print_dap4(libdap::XMLWriter &writer, bool constrained=false)
Shadow libdap::Array::print_dap4() - optionally prints DMR++ chunk information.
Definition: DmrppArray.cc:1633
Size and offset information of data included in DMR++ files.
Definition: DmrppCommon.h:76