bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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
50namespace libdap {
51class XMLWriter;
52}
53
54namespace dmrpp {
55
56 class SuperChunk;
57
58enum string_pad_type { not_set, null_term, null_pad, space_pad };
59
60struct ons {
61 unsigned long long offset;
62 unsigned long long size;
63 ons(const std::string &ons_pair_str);
64};
65
77class DmrppArray : public libdap::Array, public dmrpp::DmrppCommon {
78
79private:
80 //void _duplicate(const DmrppArray &ts);
81
82 // In the dmr++ XML:
83 // <dmrpp:vStringArray>0:1084,1025:653,65523:8746,9750:100,84660:122, ... ,98466:12</dmrpp:vStringArray>
84
85 std::string d_vlen_ons_str;
86 bool is_variable_length_string_array = false;
87 bool is_fixed_length_string_array = false;
88
89
90 // In the dmr++ XML:
91 // <dmrpp:fStringArray string_length="##" pad="null_pad | null_term | space_pad" />
92 unsigned long long d_fixed_str_length = 0;
93 string_pad_type d_fixed_length_string_pad_type = not_set;
94 vector<u_int8_t> d_compact_str_buf;
95
96 bool is_readable_struct = false;
97 vector<char> d_structure_array_buf;
98 unsigned long long bytes_per_element;
99
100 vector<char> d_structure_array_str_buf;
101 bool is_special_structure = false;
102
103 DmrppArray::dimension get_dimension(unsigned int dim_num);
104
105 void insert_constrained_contiguous(Dim_iter dim_iter, unsigned long *target_index,
106 std::vector<unsigned long long> &subset_addr,
107 const std::vector<unsigned long long> &array_shape, char *data, char *dest_buf);
108
109 void read_contiguous();
110 void read_one_chunk_dio();
111 void read_contiguous_string();
112
113#ifdef USE_READ_SERIAL
114 virtual void insert_chunk_serial(unsigned int dim, std::vector<unsigned long long> *target_element_address,
115 std::vector<unsigned long long> *chunk_source_address, Chunk *chunk);
116 virtual void read_chunks_serial();
117#endif
118
119 friend class DmrppArrayTest;
120 // Called from read_chunks_unconstrained() and also using pthreads
121 friend void
122 process_one_chunk_unconstrained(std::shared_ptr<Chunk> chunk, const vector<unsigned long long> &chunk_shape,
123 DmrppArray *array, const vector<unsigned long long> &array_shape);
124
125 // Change this for direct chunk IO.
126 friend void
127 process_one_chunk_unconstrained_dio(std::shared_ptr<Chunk> chunk, const vector<unsigned long long> &chunk_shape,
128 DmrppArray *array, const vector<unsigned long long> &array_shape);
129
130
131 // Called from read_chunks()
132 friend void
133 process_one_chunk(std::shared_ptr<Chunk> chunk, DmrppArray *array, const vector<unsigned long long> &constrained_array_shape);
134
135
136
137 virtual void insert_chunk_unconstrained(std::shared_ptr<Chunk> chunk, unsigned int dim,
138 unsigned long long array_offset, const std::vector<unsigned long long> &array_shape,
139 unsigned long long chunk_offset, const std::vector<unsigned long long> &chunk_shape,
140 const std::vector<unsigned long long> &chunk_origin);
141
142 virtual void insert_chunk_unconstrained_dio(std::shared_ptr<Chunk> chunk);
143
144 void read_chunks();
145 void read_chunks_unconstrained();
146 void read_chunks_dio_unconstrained();
147 void read_linked_blocks();
148 void read_linked_blocks_constrained();
149 void read_chunks_with_linked_blocks();
150 void read_chunks_with_linked_blocks_constrained();
151
152 void read_buffer_chunks();
153 void read_buffer_chunks_unconstrained();
154
155 unsigned long long get_chunk_start(const dimension &thisDim, unsigned long long chunk_origin_for_dim);
156
157 std::shared_ptr<Chunk> find_needed_chunks(unsigned int dim, std::vector<unsigned long long> *target_element_address, std::shared_ptr<Chunk> chunk);
158
159 virtual void insert_chunk(
160 unsigned int dim,
161 std::vector<unsigned long long> *target_element_address,
162 std::vector<unsigned long long> *chunk_element_address,
163 std::shared_ptr<Chunk> chunk,
164 const vector<unsigned long long> &constrained_array_shape,char *target_buf);
165 void read_array_of_structure(vector<char> &values);
166 bool check_struct_handling();
167
168 bool use_direct_io_opt();
169
170 bool use_buffer_chunk();
171
172 unsigned long long inflate_simple(char **destp, unsigned long long dest_len, char *src, unsigned long long src_len);
173
174public:
175
176 DmrppArray(const std::string &n, libdap::BaseType *v) :
177 libdap::Array(n, v, true /*is dap4*/), DmrppCommon()
178 { }
179
180 DmrppArray(const std::string &n, const std::string &d, libdap::BaseType *v) :
181 libdap::Array(n, d, v, true), DmrppCommon()
182 { }
183
184 DmrppArray(const string &n, BaseType *v, shared_ptr<DMZ> dmz) :
185 libdap::Array(n, v, true), DmrppCommon(dmz)
186 { }
187
188 DmrppArray(const string &n, const string &d, BaseType *v, shared_ptr<DMZ> dmz) :
189 libdap::Array(n, d, v, true), DmrppCommon(dmz)
190 { }
191
192 DmrppArray(const DmrppArray &) = default;
193
194 ~DmrppArray() override = default;
195
196 DmrppArray &operator=(const DmrppArray &rhs);
197
198 libdap::BaseType *ptr_duplicate() override { return new DmrppArray(*this); }
199
200 bool read() override;
201 void set_send_p(bool state) override;
202
203 virtual unsigned long long get_size(bool constrained = false);
204
205 virtual std::vector<unsigned long long> get_shape(bool constrained);
206
207 void print_dap4(libdap::XMLWriter &writer, bool constrained = false) override;
208
209 void dump(ostream &strm) const override;
210
215 void set_is_flsa(bool state){
216 is_fixed_length_string_array = state;
217 };
218 bool is_flsa() const{ return is_fixed_length_string_array; }
219
220 void set_is_vlsa(bool state){
221 is_variable_length_string_array = state;
222 };
223 bool is_vlsa() const{ return is_variable_length_string_array; }
224
225 void set_fixed_string_length(const unsigned long long length){ d_fixed_str_length = length; }
226 unsigned long long set_fixed_string_length(const string &length_str);
227 unsigned long long get_fixed_string_length() const { return d_fixed_str_length; }
228
229 void set_fixed_length_string_pad(const string_pad_type pad){ d_fixed_length_string_pad_type = pad; }
230 string_pad_type set_fixed_length_string_pad_type(const std::string &pad_str);
231 string_pad_type get_fixed_length_string_pad() const { return d_fixed_length_string_pad_type; }
232 std::string get_fixed_length_string_pad_str() const { return pad_type_to_str(d_fixed_length_string_pad_type); }
233
234 void set_ons_string(const std::string &ons_str);
235 void set_ons_string(const vector<ons> &ons_pairs);
236 std::string get_ons_string(){ return d_vlen_ons_str; };
237 void get_ons_objs(vector<ons> &ons_list);
238
239 static std::string pad_type_to_str(string_pad_type pad_type);
240 static string ingest_fixed_length_string(const char *buf, unsigned long long fixed_str_len, string_pad_type pad_type);
241
242
243 unsigned int buf2val(void **val) override;
244 vector<u_int8_t> &compact_str_buffer(){ return d_compact_str_buf; }
245
246 vector<char> & get_structure_array_str_buffer() { return d_structure_array_str_buf;}
247 char * get_structure_array_buf_ptr() { return d_structure_array_buf.data(); }
248
249 unsigned long long get_bytes_per_element() const { return bytes_per_element;}
250 void set_bytes_per_element(unsigned long long bpe) { bytes_per_element = bpe;}
251 void set_special_structure_flag(bool is_special_struct) {is_special_structure = is_special_struct;}
252 bool get_special_structure_flag() { return is_special_structure;}
253 bool is_projected();
254
255};
256
260struct one_super_chunk_args {
261 std::thread::id parent_thread_id;
262 std::shared_ptr<SuperChunk> super_chunk;
263 DmrppArray *array;
264
265 one_super_chunk_args(std::shared_ptr<SuperChunk> sc, DmrppArray *a)
266 : parent_thread_id(std::this_thread::get_id()), super_chunk(std::move(sc)), array(a) {}
267};
268
269
274struct one_child_chunk_args {
275 int *fds; // pipe back to parent
276 unsigned char tid; // thread id as a byte
277 std::shared_ptr<Chunk> child_chunk; // this chunk reads data; temporary allocation
278 std::shared_ptr<Chunk> master_chunk; // this chunk gets the data; shared memory, managed by DmrppArray
279
280 one_child_chunk_args(int *pipe, unsigned char id, std::shared_ptr<Chunk> c_c, std::shared_ptr<Chunk> m_c)
281 : fds(pipe), tid(id), child_chunk(c_c), master_chunk(m_c) {}
282
283 ~one_child_chunk_args() { }
284};
285
286
291struct one_child_chunk_args_new {
292 std::shared_ptr<Chunk> child_chunk; // this chunk reads data; temporary allocation
293 std::shared_ptr<Chunk> the_one_chunk; // this chunk gets the data; shared memory, managed by DmrppArray
294
295 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) {}
296
297 ~one_child_chunk_args_new() { }
298};
299
300
301bool get_next_future(list< std::future<bool> > &futures, atomic_uint &thread_counter, unsigned long timeout, string debug_prefix);
302
303} // namespace dmrpp
304
305#endif // _dmrpp_array_h
306
Extend libdap::Array so that a handler can read data using a DMR++ file.
Definition DmrppArray.h:77
void set_is_flsa(bool state)
Marks the array as a Fixed length string array, or not, depending on state.
Definition DmrppArray.h:215
virtual std::vector< unsigned long long > get_shape(bool constrained)
Get the array shape.
void get_ons_objs(vector< ons > &ons_list)
void print_dap4(libdap::XMLWriter &writer, bool constrained=false) override
Shadow libdap::Array::print_dap4() - optionally prints DMR++ chunk information.
virtual unsigned long long get_size(bool constrained=false)
Return the total number of elements in this Array.
bool is_projected()
Is this Array subset?
bool read() override
Read data for the array.
Size and offset information of data included in DMR++ files.
Definition DmrppCommon.h:97
A SuperChunk is a collection of contiguous Chunk objects along with optimized methods for data retrie...
Definition SuperChunk.h:44
STL class.
STL class.
STL class.