34#include <libdap/Marshaller.h>
37#include "BESStopWatch.h"
39#include "ArrayJoinExistingAggregation.h"
41#include "AggregationException.h"
42#include "AggregationUtil.h"
45#define DEBUG_CHANNEL "ncml:2"
46#define prolog string("ArrayJoinExistingAggregation::").append(__func__).append("() - ")
51 AMDList memberDatasets, std::unique_ptr<ArrayGetterInterface> arrayGetter,
const Dimension& joinDim) :
55 BESDEBUG_FUNC(DEBUG_CHANNEL,
"Making the aggregated outer dimension be: " + joinDim.
toString() +
"\n");
60 libdap::Array::dimension& rOuterDim = *(dim_begin());
61 NCML_ASSERT_MSG(rOuterDim.name == joinDim.name,
"The outer dimension name of this is not the expected "
62 "outer dimension name! Broken precondition: This ctor cannot be called "
63 "without this being true!");
64 rOuterDim.size = joinDim.size;
71 BESDEBUG_FUNC(DEBUG_CHANNEL,
"Constrained Dims after set are: " + oss.str());
81ArrayJoinExistingAggregation::~ArrayJoinExistingAggregation()
91 ArrayAggregationBase::operator=(rhs);
114bool ArrayJoinExistingAggregation::serialize(libdap::ConstraintEvaluator &eval, libdap::DDS &dds, libdap::Marshaller &m,
117 BES_STOPWATCH_START(DEBUG_CHANNEL, prolog +
"Timing");
124 if (!(send_p() || is_in_selection())) {
125 BESDEBUG_FUNC(DEBUG_CHANNEL,
"Object not in output, skipping... name=" << name() << endl);
143 const Array::dimension& outerDim = *(dim_begin());
145 "Aggregating datasets array with outer dimension constraints: " <<
" start=" << outerDim.start <<
" stride=" << outerDim.stride <<
" stop=" << outerDim.stop << endl);
150 m.put_vector_start(length());
152 reserve_value_capacity();
157 NCML_ASSERT(!datasets.empty());
158 int currDatasetIndex = 0;
161 int outerDimIndexOfCurrDatasetHead = 0;
163 bool currDatasetWasRead =
false;
166 unsigned int nextOutputBufferElementIndex = 0;
171 for (
int outerDimIndex = outerDim.start; outerDimIndex <= outerDim.stop && outerDimIndex < outerDim.size;
172 outerDimIndex += outerDim.stride) {
174 int localGranuleIndex = outerDimIndex - outerDimIndexOfCurrDatasetHead;
178 while (localGranuleIndex >= currDatasetSize) {
179 localGranuleIndex -= currDatasetSize;
180 outerDimIndexOfCurrDatasetHead += currDatasetSize;
182 NCML_ASSERT(currDatasetIndex <
int(datasets.size()));
183 pCurrDataset = datasets[currDatasetIndex].get();
185 currDatasetWasRead =
false;
187 BESDEBUG_FUNC(DEBUG_CHANNEL,
188 "The constraint traversal passed a granule boundary " <<
"on the outer dimension and is stepping forward into " <<
"granule index=" << currDatasetIndex << endl);
193 if (!currDatasetWasRead) {
194 BESDEBUG_FUNC(DEBUG_CHANNEL,
195 " Current granule dataset was traversed but not yet " "read and copied into output. Mapping constraints " "and calling read()..." << endl);
204 Array::Dim_iter outerDimIt = granuleConstraintTemplate.dim_begin();
209 outerDimIt->size = currDatasetSize;
210 outerDimIt->c_size = currDatasetSize;
220 int granuleStopIndex = std::min(outerDim.stop - outerDimIndexOfCurrDatasetHead,
221 (
unsigned long long)currDatasetSize - 1);
223 int granuleStopIndex = outerDim.stop - outerDimIndexOfCurrDatasetHead;
224 if (granuleStopIndex > (currDatasetSize - 1))
225 granuleStopIndex = currDatasetSize - 1;
234 int clampedStride = std::min(outerDim.stride, (
unsigned long long)currDatasetSize);
236 int clampedStride = outerDim.stride;
237 if (clampedStride > currDatasetSize)
238 clampedStride = currDatasetSize;
241 granuleConstraintTemplate.add_constraint(outerDimIt, localGranuleIndex, clampedStride,
250 this->set_value_slice_from_row_major_vector(*pDatasetArray, nextOutputBufferElementIndex);
253 pDatasetArray->clear_local_data();
257 currDatasetWasRead =
true;
259 BESDEBUG_FUNC(DEBUG_CHANNEL,
260 " The granule index " << currDatasetIndex <<
" was read with constraints and copied into the aggregation output." << endl);
264 catch (AggregationException& ex) {
265 THROW_NCML_PARSE_ERROR(-1, ex.what());
275 status = libdap::Array::serialize(eval, dds, m, ce_eval);
279 status = libdap::Array::serialize(eval, dds, m, ce_eval);
290 _joinDim = rhs._joinDim;
293void ArrayJoinExistingAggregation::cleanup() noexcept
313 BES_STOPWATCH_START(DEBUG_CHANNEL, prolog +
"Timing");
316 const Array::dimension& outerDim = *(dim_begin());
318 "Aggregating datasets array with outer dimension constraints: " <<
" start=" << outerDim.start <<
" stride=" << outerDim.stride <<
" stop=" << outerDim.stop << endl);
322 reserve_value_capacity();
326 NCML_ASSERT(!datasets.empty());
327 int currDatasetIndex = 0;
330 int outerDimIndexOfCurrDatasetHead = 0;
332 bool currDatasetWasRead =
false;
335 unsigned int nextOutputBufferElementIndex = 0;
340 for (
int outerDimIndex = outerDim.start; outerDimIndex <= outerDim.stop && outerDimIndex < outerDim.size;
341 outerDimIndex += outerDim.stride) {
343 int localGranuleIndex = outerDimIndex - outerDimIndexOfCurrDatasetHead;
347 while (localGranuleIndex >= currDatasetSize) {
348 localGranuleIndex -= currDatasetSize;
349 outerDimIndexOfCurrDatasetHead += currDatasetSize;
351 NCML_ASSERT(currDatasetIndex <
int(datasets.size()));
352 pCurrDataset = datasets[currDatasetIndex].get();
354 currDatasetWasRead =
false;
356 BESDEBUG_FUNC(DEBUG_CHANNEL,
357 "The constraint traversal passed a granule boundary " <<
"on the outer dimension and is stepping forward into " <<
"granule index=" << currDatasetIndex << endl);
362 if (!currDatasetWasRead) {
363 BESDEBUG_FUNC(DEBUG_CHANNEL,
364 " Current granule dataset was traversed but not yet " "read and copied into output. Mapping constraints " "and calling read()..." << endl);
373 Array::Dim_iter outerDimIt = granuleConstraintTemplate.dim_begin();
378 outerDimIt->size = currDatasetSize;
379 outerDimIt->c_size = currDatasetSize;
389 int granuleStopIndex = std::min(outerDim.stop - outerDimIndexOfCurrDatasetHead, (
unsigned long long)currDatasetSize - 1);
391 int granuleStopIndex = outerDim.stop - outerDimIndexOfCurrDatasetHead;
392 if (granuleStopIndex > (currDatasetSize - 1))
393 granuleStopIndex = currDatasetSize - 1;
403 int clampedStride = std::min(outerDim.stride, (
unsigned long long) currDatasetSize);
405 int clampedStride = outerDim.stride;
406 if (clampedStride > currDatasetSize)
407 clampedStride = currDatasetSize;
410 granuleConstraintTemplate.add_constraint(outerDimIt, localGranuleIndex, clampedStride, granuleStopIndex);
414 nextOutputBufferElementIndex,
422 currDatasetWasRead =
true;
424 BESDEBUG_FUNC(DEBUG_CHANNEL,
425 " The granule index " << currDatasetIndex <<
" was read with constraints and copied into the aggregation output." << endl);
431 THROW_NCML_PARSE_ERROR(-1, ex.what());
virtual unsigned int getCachedDimensionSize(const std::string &dimName) const =0
virtual unsigned int getCachedDimensionSize(const std::string &dimName) const =0
static void addDatasetArrayDataToAggregationOutputArray(libdap::Array &oOutputArray, unsigned int atIndex, const libdap::Array &constrainedTemplateArray, const string &varName, AggMemberDataset &dataset, const ArrayGetterInterface &arrayGetter, const string &debugChannel)
static void transferArrayConstraints(libdap::Array *pToArray, const libdap::Array &fromArray, bool skipFirstFromDim, bool skipFirstToDim, bool printDebug=false, const std::string &debugChannel="agg_util")
static void printDimensions(std::ostream &os, const libdap::Array &fromArray)
static libdap::Array * readDatasetArrayDataForAggregation(const libdap::Array &constrainedTemplateArray, const std::string &varName, AggMemberDataset &dataset, const ArrayGetterInterface &arrayGetter, const std::string &debugChannel)
const AMDList & getDatasetList() const
libdap::Array & getGranuleTemplateArray()
const ArrayGetterInterface & getArrayGetterInterface() const
ArrayAggregationBase(const libdap::Array &granuleProto, AMDList memberDatasets, std::unique_ptr< ArrayGetterInterface > arrayGetter)
virtual void readConstrainedGranuleArraysAndAggregateDataHook()
virtual ArrayJoinExistingAggregation * ptr_duplicate()
virtual void transferOutputConstraintsIntoGranuleTemplateHook()
ArrayJoinExistingAggregation(const libdap::Array &granuleTemplate, AMDList memberDatasets, std::unique_ptr< ArrayGetterInterface > arrayGetter, const Dimension &joinDim)
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...
std::string toString() const