bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
HDFSPArray_RealField.cc
1
2// This file is part of the hdf4 data handler for the OPeNDAP data server.
3// It retrieves the real SDS field values for special HDF4 data products.
4// Authors: Kent Yang <myang6@hdfgroup.org> Eunsoo Seo
5// Copyright (c) The HDF Group
7#include "HDFSPArray_RealField.h"
8#include <iostream>
9#include <sstream>
10#include <cassert>
11#include <libdap/debug.h>
12#include "hdf.h"
13#include "mfhdf.h"
14#include <libdap/InternalErr.h>
15#include <BESDebug.h>
16#include "BESInternalError.h"
17#include "HDFCFUtil.h"
18#include "HDF4RequestHandler.h"
19
20//#include "BESH4MCache.h"
21#include "dodsutil.h"
22
23using namespace std;
24using namespace libdap;
25#define SIGNED_BYTE_TO_INT32 1
26
27
28bool
30{
31
32 BESDEBUG("h4","Coming to HDFSPArray_RealField read "<<endl);
33 if (length() == 0)
34 return true;
35
36 // Declare offset, count and step
37 vector<int>offset;
38 offset.resize(rank);
39 vector<int>count;
40 count.resize(rank);
41 vector<int>step;
42 step.resize(rank);
43
44 // Obtain offset,step and count from the client expression constraint
45 int nelms = format_constraint (offset.data(), step.data(), count.data());
46
47 // Cache
48 // Check if a BES key H4.EnableDataCacheFile is true, if yes, we will check
49 // if we can read the data from this file.
50
51 bool data_from_cache = false;
52 bool data_to_cache = false;
53
54 short dtype_size = HDFCFUtil::obtain_type_size(dtype);
55 if (-1 == dtype_size) {
56 string err_mesg = "Wrong data type size for the variable ";
57 err_mesg += name();
58 throw InternalErr(__FILE__,__LINE__,err_mesg);
59 }
60
61 string cache_fpath;
62 if (true == HDF4RequestHandler::get_enable_data_cachefile()) {
63
65
66 // Here we have a sanity check for the cached parameters:Cached directory,file prefix and cached directory size.
67 // Supposedly Hyrax BES cache feature should check this and the code exists. However, the
68 // current hyrax 1.9.7 doesn't provide this feature. KY 2014-10-24
69
70 // Make it simple, the data cache parameters also shares with the HDF-EOS2 grid lat/lon cache
71 string bescachedir = HDF4RequestHandler::get_cache_latlon_path();
72 string bescacheprefix = HDF4RequestHandler::get_cache_latlon_prefix();
73 long cachesize = HDF4RequestHandler::get_cache_latlon_size();
74
75 if (("" == bescachedir)||(""==bescacheprefix)||(cachesize <=0))
76 throw InternalErr (__FILE__, __LINE__, "Either the cached dir is empty or the prefix is NULL or the cache size is not set.");
77 else {
78 struct stat sb;
79 if (stat(bescachedir.c_str(),&sb) !=0) {
80 string err_mesg="The cached directory " + bescachedir;
81 err_mesg = err_mesg + " doesn't exist. ";
82 throw InternalErr(__FILE__,__LINE__,err_mesg);
83 }
84 else {
85 if (true == S_ISDIR(sb.st_mode)) {
86 if (access(bescachedir.c_str(),R_OK|W_OK|X_OK) == -1) {
87 string err_mesg="The cached directory " + bescachedir;
88 err_mesg = err_mesg + " can NOT be read,written or executable.";
89 throw InternalErr(__FILE__,__LINE__,err_mesg);
90 }
91 }
92 else {
93 string err_mesg="The cached directory " + bescachedir;
94 err_mesg = err_mesg + " is not a directory.";
95 throw InternalErr(__FILE__,__LINE__,err_mesg);
96 }
97 }
98 }
99
100 string cache_fname=HDFCFUtil::obtain_cache_fname(bescacheprefix,filename,name());
101 cache_fpath = bescachedir + "/"+ cache_fname;
102
103 int total_elems = 1;
104 for (unsigned int i = 0; i <dimsizes.size();i++)
105 total_elems = total_elems*dimsizes[i];
106 dtype_size = HDFCFUtil::obtain_type_size(dtype);
107 if (-1 == dtype_size) {
108 string err_mesg = "Wrong data type size for the variable ";
109 err_mesg += name();
110 throw InternalErr(__FILE__,__LINE__,err_mesg);
111 }
112 int expected_file_size = dtype_size *total_elems;
113 int fd = 0;
114 if ( true == llcache->get_data_from_cache(cache_fpath, expected_file_size,fd)) {
115
116 vector<int32>offset32;
117 offset32.resize(offset.size());
118 for (int i = 0; i< rank;i++)
119 offset32[i] = offset[i];
120 int offset_1st = INDEX_nD_TO_1D(dimsizes,offset32);
121 vector<int32>end;
122 end.resize(rank);
123 for (int i = 0; i < rank; i++)
124 end[i] = offset[i] +(count[i]-1)*step[i];
125 int offset_last = INDEX_nD_TO_1D(dimsizes,end);
126 size_t total_read = dtype_size*(offset_last-offset_1st+1);
127
128 off_t fpos = lseek(fd,dtype_size*offset_1st,SEEK_SET);
129 if (-1 == fpos) {
130 llcache->unlock_and_close(cache_fpath);
131 llcache->purge_file(cache_fpath);
132 }
133
135 else
136 data_from_cache = obtain_cached_data(llcache,cache_fpath,fd, step,count,total_read,dtype_size);
137
138 }
139
140 if (true == data_from_cache)
141 return true;
142 else
143 data_to_cache = true;
144
145 }
146
147 bool check_pass_fileid_key = HDF4RequestHandler::get_pass_fileid();
148
149 // Just declare offset,count and step in the int32 type.
150 vector<int32>offset32;
151 offset32.resize(rank);
152 vector<int32>count32;
153 count32.resize(rank);
154 vector<int32>step32;
155 step32.resize(rank);
156
157 // Just obtain the offset,count and step in the datatype of int32.
158 for (int i = 0; i < rank; i++) {
159 offset32[i] = (int32) offset[i];
160 count32[i] = (int32) count[i];
161 step32[i] = (int32) step[i];
162 }
163
164 int32 sdid = -1;
165
166 // Obtain SD ID.
167 if (false == check_pass_fileid_key) {
168 sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
169 if (sdid < 0) {
170 ostringstream eherr;
171 eherr << "File " << filename.c_str () << " cannot be open.";
172 throw InternalErr (__FILE__, __LINE__, eherr.str ());
173 }
174 }
175 else {
176 // This code will make sure that the file ID is not passed when H4.EnableMetaDataCacheFile key is set.
177 // We will wait to see if Hyrax core supports the cache and then make improvement. KY 2015-04-30
178
179 if (true == HDF4RequestHandler::get_enable_metadata_cachefile()) {
180
181 sdid = SDstart (const_cast < char *>(filename.c_str ()), DFACC_READ);
182 if (sdid < 0) {
183 ostringstream eherr;
184 eherr << "File " << filename.c_str () << " cannot be open.";
185 throw InternalErr (__FILE__, __LINE__, eherr.str ());
186 }
187 // Reset the pass file ID key to be false for resource clean-up.
188 check_pass_fileid_key = false;
189
190 }
191 else
192 sdid = sdfd;
193 }
194
195 // Initialize SDS ID.
196 int32 sdsid = 0;
197
198 // Obtain the SDS index based on the input sds reference number.
199 int32 sdsindex = SDreftoindex (sdid, (int32) fieldref);
200 if (sdsindex == -1) {
201 HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
202 ostringstream eherr;
203 eherr << "SDS index " << sdsindex << " is not right.";
204 throw InternalErr (__FILE__, __LINE__, eherr.str ());
205 }
206
207 // Obtain this SDS ID.
208 sdsid = SDselect (sdid, sdsindex);
209 if (sdsid < 0) {
210 HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
211 ostringstream eherr;
212 eherr << "SDselect failed.";
213 throw InternalErr (__FILE__, __LINE__, eherr.str ());
214 }
215
216 // Initialize the temp. returned value.
217 int32 r = 0;
218
219 // Loop through all the possible SDS datatype and then read the data.
220 switch (dtype) {
221
222 case DFNT_INT8:
223 {
224 vector<char>buf;
225 buf.resize(nelms);
226 r = SDreaddata (sdsid, offset32.data(), step32.data(), count32.data(), buf.data());
227 if (r != 0) {
228 SDendaccess (sdsid);
229 HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
230 ostringstream eherr;
231 eherr << "SDreaddata failed.";
232 throw InternalErr (__FILE__, __LINE__, eherr.str ());
233 }
234
235#ifndef SIGNED_BYTE_TO_INT32
236 val2buf(buf.data());
237 set_read_p(true);
238#else
239 vector<int32>newval;
240 newval.resize(nelms);
241 for (int counter = 0; counter < nelms; counter++)
242 newval[counter] = (int32) (buf[counter]);
243
244 set_value ((dods_int32 *) newval.data(), nelms);
245#endif
246 if (true == data_to_cache) {
247 try {
248 write_data_to_cache(sdsid,cache_fpath,dtype_size,buf,nelms);
249 }
250 catch(...) {
251 SDendaccess (sdsid);
252 HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
253 ostringstream eherr;
254 eherr << "write data to cache failed.";
255 throw InternalErr (__FILE__, __LINE__, eherr.str ());
256
257 }
258 }
259 }
260 break;
261
262 // Will keep the following comments until we formally decide not to support these old products.
263 // Leave the following #if 0 #endif as stated above. KY 2022-11-28
264#if 0
265 // --------------------------------------------------------
266 // HANDLE this later if necessary. KY 2010-8-17
267 //if (sptype == TRMML2_V6)
268 // Find scale_factor, add_offset attributes
269 // create a new val to float32, remember to change int16 at HDFSP.cc to float32
270 // if (sptype == OBPGL3) 16-bit unsigned integer
271 // Find slope and intercept,
272 // CZCS: also find base. data = base**((slope*l3m_data)+intercept)
273 // Others : slope*data+intercept
274 // OBPGL2: 16-bit signed integer, (8-bit signed integer or 32-bit signed integer)
275 // If slope = 1 and intercept = 0 no need to do conversion
276 // ---------------------------------------------------------
277#endif
278
279 case DFNT_UINT8:
280 case DFNT_UCHAR8:
281 case DFNT_INT16:
282 case DFNT_UINT16:
283 case DFNT_INT32:
284 case DFNT_UINT32:
285 case DFNT_FLOAT32:
286 case DFNT_FLOAT64:
287 {
288 vector<char>buf;
289 buf.resize(nelms*dtype_size);
290
291 r = SDreaddata (sdsid, offset32.data(), step32.data(), count32.data(), buf.data());
292 if (r != 0) {
293 SDendaccess (sdsid);
294 HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
295 ostringstream eherr;
296 eherr << "SDreaddata failed";
297 throw InternalErr (__FILE__, __LINE__, eherr.str ());
298 }
299
300 if((basename(filename).size() >=7) && ((basename(filename)).compare(0,7,"MCD43GF")==0)) {
301 if (fieldname=="Latitude" && dtype == DFNT_FLOAT32) {
302
303 char *temp_buf = buf.data()+nelms*dtype_size-dtype_size;
304 float last_val = *((float*)(temp_buf));
305 if (last_val <-90.0) {
306 last_val = -90.0;
307 vector<char>last_val_buf(dtype_size);
308 memcpy(last_val_buf.data(),(void*)&last_val,dtype_size);
309 for (unsigned int i = 0; i<dtype_size;i++)
310 buf[i+nelms*dtype_size-dtype_size] = last_val_buf[i];
311 }
312 }
313 else if (fieldname=="Longitude" && dtype == DFNT_FLOAT32) {
314 char *temp_buf = buf.data()+nelms*dtype_size-dtype_size;
315 float last_val = *((float*)(temp_buf));
316 if (last_val > 180.0) {
317 last_val = 180.0;
318 vector<char>last_val_buf(dtype_size);
319 memcpy(last_val_buf.data(),(void*)&last_val,dtype_size);
320 for (unsigned int i = 0; i<dtype_size;i++)
321 buf[i+nelms*dtype_size-dtype_size] = last_val_buf[i];
322 }
323 }
324 val2buf(buf.data());
325 }
326 else
327 val2buf(buf.data());
328
329 set_read_p(true);
330
331 // write data to cache if cache is set.
332 if (true == data_to_cache) {
333 try {
334 write_data_to_cache(sdsid,cache_fpath,dtype_size,buf,nelms);
335 }
336 catch(...) {
337 SDendaccess (sdsid);
338 HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
339 ostringstream eherr;
340 eherr << "write data to cache failed.";
341 throw InternalErr (__FILE__, __LINE__, eherr.str ());
342
343 }
344 }
345 }
346 break;
347 default:
348 SDendaccess (sdsid);
349 HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
350 throw InternalErr (__FILE__, __LINE__, "unsupported data type.");
351 }
352
353 // Close the SDS interface
354 r = SDendaccess (sdsid);
355 if (r != 0) {
356 ostringstream eherr;
357 eherr << "SDendaccess failed.";
358 throw InternalErr (__FILE__, __LINE__, eherr.str ());
359 }
360 HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
361
362 return true;
363}
364
365bool HDFSPArray_RealField::obtain_cached_data(BESH4Cache *llcache,const string & cache_fpath, int fd,vector<int> &cd_step, vector<int>&cd_count,size_t total_read,short dtype_size) {
366
367 ssize_t ret_read_val = -1;
368 vector<char>buf;
369 buf.resize(total_read);
370 ret_read_val = HDFCFUtil::read_buffer_from_file(fd,(void*)buf.data(),total_read);
371 llcache->unlock_and_close(cache_fpath);
372 if ((-1 == ret_read_val) || (ret_read_val != (ssize_t)total_read)) {
373 llcache->purge_file(cache_fpath);
374 return false;
375 }
376 else {
377 unsigned int nele_to_read = 1;
378 for(int i = 0; i<rank;i++)
379 nele_to_read *=cd_count[i];
380
381 if (nele_to_read == (total_read/dtype_size)) {
382 val2buf(buf.data());
383 set_read_p(true);
384 }
385 else { // Need to re-assemble the buffer according to different datatype
386
387 vector<int>cd_start(rank,0);
388 vector<int32>cd_pos(rank,0);
389 int nelms_to_send = 1;
390 for(int i = 0; i <rank; i++)
391 nelms_to_send = nelms_to_send*cd_count[i];
392 switch (dtype) {
393
394 case DFNT_INT8:
395 {
396
397#ifndef SIGNED_BYTE_TO_INT32
398 vector<int8>total_val;
399 total_val.resize(total_read/dtype_size);
400 memcpy(total_val.data(),(void*)buf.data(),total_read);
401
402 vector<int8>final_val;
403 subset<int8>(
404 total_val.data(),
405 rank,
406 dimsizes,
407 cd_start,
408 cd_step,
409 cd_count,
410 &final_val,
411 cd_pos,
412 0
413 );
414
415 set_value((dods_byte*)final_val.data(),nelms_to_send);
416
417#else
418 vector<int32>total_val2;
419 total_val2.resize(total_read/dtype_size);
420 memcpy(total_val2.data(),(void*)buf.data(),total_read);
421
422 vector<int32>final_val2;
423 subset<int32>(
424 total_val2.data(),
425 rank,
426 dimsizes,
427 cd_start,
428 cd_step,
429 cd_count,
430 &final_val2,
431 cd_pos,
432 0
433 );
434
435 set_value((dods_int32*)final_val2.data(),nelms_to_send);
436
437#endif
438 }
439
440 break;
441 case DFNT_UINT8:
442 case DFNT_UCHAR8:
443 {
444 vector<uint8>total_val;
445 total_val.resize(total_read/dtype_size);
446 memcpy(total_val.data(),(void*)buf.data(),total_read);
447
448 vector<uint8>final_val;
449 subset<uint8>(
450 total_val.data(),
451 rank,
452 dimsizes,
453 cd_start,
454 cd_step,
455 cd_count,
456 &final_val,
457 cd_pos,
458 0
459 );
460
461
462 set_value ((dods_byte *) final_val.data(), nelms_to_send);
463 }
464 break;
465
466 case DFNT_INT16:
467 {
468 vector<int16>total_val;
469 total_val.resize(total_read/dtype_size);
470 memcpy(total_val.data(),(void*)buf.data(),total_read);
471
472 vector<int16>final_val;
473 subset<int16>(
474 total_val.data(),
475 rank,
476 dimsizes,
477 cd_start,
478 cd_step,
479 cd_count,
480 &final_val,
481 cd_pos,
482 0
483 );
484
485
486 set_value ((dods_int16 *) final_val.data(), nelms_to_send);
487 }
488 break;
489
490 case DFNT_UINT16:
491 {
492 vector<uint16>total_val;
493 total_val.resize(total_read/dtype_size);
494 memcpy(total_val.data(),(void*)buf.data(),total_read);
495
496 vector<uint16>final_val;
497 subset<uint16>(
498 total_val.data(),
499 rank,
500 dimsizes,
501 cd_start,
502 cd_step,
503 cd_count,
504 &final_val,
505 cd_pos,
506 0
507 );
508
509
510 set_value ((dods_uint16 *) final_val.data(), nelms_to_send);
511 }
512 break;
513
514 case DFNT_INT32:
515 {
516 vector<int32>total_val;
517 total_val.resize(total_read/dtype_size);
518 memcpy(total_val.data(),(void*)buf.data(),total_read);
519
520 vector<int32>final_val;
521 subset<int32>(
522 total_val.data(),
523 rank,
524 dimsizes,
525 cd_start,
526 cd_step,
527 cd_count,
528 &final_val,
529 cd_pos,
530 0
531 );
532
533
534 set_value ((dods_int32 *) final_val.data(), nelms_to_send);
535 }
536 break;
537
538 case DFNT_UINT32:
539 {
540 vector<uint32>total_val;
541 total_val.resize(total_read/dtype_size);
542 memcpy(total_val.data(),(void*)buf.data(),total_read);
543
544 vector<uint32>final_val;
545 subset<uint32>(
546 total_val.data(),
547 rank,
548 dimsizes,
549 cd_start,
550 cd_step,
551 cd_count,
552 &final_val,
553 cd_pos,
554 0
555 );
556
557
558 set_value ((dods_uint32 *) final_val.data(), nelms_to_send);
559 }
560 break;
561
562 case DFNT_FLOAT32:
563 {
564 vector<float32>total_val;
565 total_val.resize(total_read/dtype_size);
566 memcpy(total_val.data(),(void*)buf.data(),total_read);
567
568 vector<float32>final_val;
569 subset<float32>(
570 total_val.data(),
571 rank,
572 dimsizes,
573 cd_start,
574 cd_step,
575 cd_count,
576 &final_val,
577 cd_pos,
578 0
579 );
580
581
582 set_value ((dods_float32 *) final_val.data(), nelms_to_send);
583 }
584 break;
585 case DFNT_FLOAT64:
586 {
587 vector<float64>total_val;
588 total_val.resize(total_read/dtype_size);
589 memcpy(total_val.data(),(void*)buf.data(),total_read);
590
591 vector<float64>final_val;
592 subset<float64>(
593 total_val.data(),
594 rank,
595 dimsizes,
596 cd_start,
597 cd_step,
598 cd_count,
599 &final_val,
600 cd_pos,
601 0
602 );
603
604 set_value ((dods_float64 *) final_val.data(), nelms_to_send);
605 }
606 break;
607 default:
608 throw InternalErr (__FILE__, __LINE__, "unsupported data type.");
609
610 }// end switch(dtype)
611 }// end else (stride is not 1)
612 return true;
613 }// end else(full_read = true)
614}
615
616void
617HDFSPArray_RealField::write_data_to_cache(int32 sdsid, const string& cache_fpath,short dtype_size,const vector<char> &buf, int nelms) {
618
619 BESH4Cache *llcache = BESH4Cache::get_instance();
620 vector<int32>woffset32(rank,0);
621 vector<int32>wstep32(rank,1);
622 vector<int32>wcount32;
623 wcount32.resize(rank);
624 int total_nelem = 1;
625 for(int i = 0; i <rank; i++){
626 wcount32[i] = (int32)dimsizes[i];
627 total_nelem = total_nelem*dimsizes[i];
628 }
629 vector<char>val;
630 if (DFNT_INT8 == dtype) {
631
632#ifndef SIGNED_BYTE_TO_INT32
633 if (total_nelem == nelms)
634 llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)buf.data());
635 else {
636 val.resize(dtype_size*total_nelem);
637 if (SDreaddata (sdsid, woffset32.data(), wstep32.data(), wcount32.data(), val.data())<0)
638 throw InternalErr (__FILE__, __LINE__, "Cannot read the whole SDS for cache.");
639 llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)val.data());
640 }
641
642#else
643 vector<int>newval;
644 newval.resize(total_nelem);
645 if (total_nelem == nelms) {
646 for (int i = 0; i < total_nelem;i++)
647 newval[i] = (int)buf[i];
648 llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)newval.data());
649 }
650 else {
651 vector<char>val2;
652 val2.resize(total_nelem);
653 if (SDreaddata (sdsid, woffset32.data(), wstep32.data(), wcount32.data(), val2.data())<0)
654 throw InternalErr (__FILE__, __LINE__, "Cannot read the whole SDS for cache.");
655 for (int i = 0; i < total_nelem;i++)
656 newval[i] = (int)val2[i];
657 llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)newval.data());
658 }
659#endif
660 }
661 else {
662 if (total_nelem == nelms) {
663 llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)buf.data());
664 }
665 else {
666 val.resize(dtype_size*total_nelem);
667 if (SDreaddata (sdsid, woffset32.data(), wstep32.data(), wcount32.data(), val.data())<0)
668 throw InternalErr (__FILE__, __LINE__, "Cannot read the whole SDS for cache.");
669
670 llcache->write_cached_data2(cache_fpath,dtype_size*total_nelem,(const void*)val.data());
671 }
672 }
673}
674// Standard way to pass the coordinates of the subsetted region from the client to the handlers
675// Returns the number of elements
676int
677HDFSPArray_RealField::format_constraint (int *offset, int *step, int *count)
678{
679 int nels = 1;
680 int id = 0;
681
682 Dim_iter p = dim_begin ();
683 while (p != dim_end ()) {
684
685 int start = dimension_start (p, true);
686 int stride = dimension_stride (p, true);
687 int stop = dimension_stop (p, true);
688
689 // Check for illegal constraint
690 if (start > stop) {
691 ostringstream oss;
692 oss << "Array/Grid hyperslab start point "<< start <<
693 " is greater than stop point " << stop <<".";
694 throw Error(malformed_expr, oss.str());
695 }
696
697 offset[id] = start;
698 step[id] = stride;
699 count[id] = ((stop - start) / stride) + 1; // count of elements
700 nels *= count[id]; // total number of values for variable
701
702 BESDEBUG ("h4",
703 "=format_constraint():"
704 << "id=" << id << " offset=" << offset[id]
705 << " step=" << step[id]
706 << " count=" << count[id]
707 << endl);
708
709 id++;
710 p++;
711 }
712
713 return nels;
714}
715
716
718//
719// \param input Input variable
720// \param dim dimension info of the input
721// \param start start indexes of each dim
722// \param stride stride of each dim
723// \param edge count of each dim
724// \param poutput output variable
725// \parrm index dimension index
726// \return 0 if successful. -1 otherwise.
727//
728template<typename T> int
729HDFSPArray_RealField::subset(
730 const T input[],
731 int sf_rank,
732 vector<int32> & dim,
733 vector<int> & start,
734 vector<int> & stride,
735 vector<int> & edge,
736 std::vector<T> *poutput,
737 vector<int32>& pos,
738 int index)
739{
740 for(int k=0; k<edge[index]; k++)
741 {
742 pos[index] = start[index] + k*stride[index];
743 if (index+1<sf_rank)
744 subset(input, sf_rank, dim, start, stride, edge, poutput,pos,index+1);
745 if (index==sf_rank-1)
746 {
747 poutput->push_back(input[INDEX_nD_TO_1D( dim, pos)]);
748 }
749 } // end of for
750 return 0;
751} // end of template<typename T> static int subset
virtual void unlock_and_close(const std::string &target)
virtual void purge_file(const std::string &file)
Purge a single file from the cache.
static BESH4Cache * get_instance()
static short obtain_type_size(int32)
Obtain datatype size.
Definition HDFCFUtil.cc:384
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)