OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
ArrayAggregateOnOuterDimension.cc
Go to the documentation of this file.
1 // This file is part of the "NcML Module" project, a BES module designed
3 // to allow NcML files to be used to be used as a wrapper to add
4 // AIS to existing datasets of any format.
5 //
6 // Copyright (c) 2010 OPeNDAP, Inc.
7 // Author: Michael Johnson <m.johnson@opendap.org>
8 //
9 // For more information, please also see the main website: http://opendap.org/
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // Please see the files COPYING and COPYRIGHT for more information on the GLPL.
26 //
27 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
29 
31 
32 #include "AggregationException.h"
33 #include <DataDDS.h> // libdap::DataDDS
34 
35 // only NCML backlinks we want in this agg_util class.
36 #include "NCMLDebug.h" // BESDEBUG and throw macros
37 #include "NCMLUtil.h" // SAFE_DELETE, NCMLUtil::getVariableNoRecurse
38 
39 // BES debug channel we output to
40 static const string DEBUG_CHANNEL("agg_util");
41 
42 // Local flag for whether to print constraints, to help debugging
43 // unused jhrg 4/16/14 static const bool PRINT_CONSTRAINTS = true;
44 
45 namespace agg_util
46 {
47 
49  const libdap::Array& proto,
50  const AMDList& memberDatasets,
51  std::auto_ptr<ArrayGetterInterface>& arrayGetter,
52  const Dimension& newDim
53  )
54  : ArrayAggregationBase(proto, memberDatasets, arrayGetter) // no new dim yet in super chain
55  , _newDim(newDim)
56  {
57  BESDEBUG(DEBUG_CHANNEL, "ArrayAggregateOnOuterDimension: ctor called!" << endl);
58 
59  // Up the rank of the array using the new dimension as outer (prepend)
60  BESDEBUG(DEBUG_CHANNEL,
61  "ArrayAggregateOnOuterDimension: adding new outer dimension: "
62  << _newDim.name
63  << endl);
64  prepend_dim(_newDim.size, _newDim.name);
65  }
66 
69  )
70  : ArrayAggregationBase(proto)
71  , _newDim()
72  {
73  BESDEBUG(DEBUG_CHANNEL,
74  "ArrayAggregateOnOuterDimension() copy ctor called!" <<
75  endl);
76  duplicate(proto);
77  }
78 
80  {
81  BESDEBUG(DEBUG_CHANNEL, "~ArrayAggregateOnOuterDimension() dtor called!" << endl);
82  cleanup();
83  }
84 
87  {
88  return new ArrayAggregateOnOuterDimension(*this);
89  }
90 
93  {
94  if (this != &rhs)
95  {
96  cleanup();
98  duplicate(rhs);
99  }
100  return *this;
101  }
102 
104  // helpers
105 
106  void
107  ArrayAggregateOnOuterDimension::duplicate(const ArrayAggregateOnOuterDimension& rhs)
108  {
109  _newDim = rhs._newDim;
110  }
111 
112  void
113  ArrayAggregateOnOuterDimension::cleanup() throw()
114  {
115  }
116 
117  /* virtual */
118  void
120  {
121  // transfer the constraints from this object into the subArray template
122  // skipping our first dim which is the new one and not in the subArray.
124  &(getGranuleTemplateArray()), // into this template
125  *this, // from this
126  true, // skip first dim in the copy since we handle it special
127  false, // also skip it in the toArray for the same reason.
128  true, // print debug
129  DEBUG_CHANNEL); // on this channel
130  }
131 
132  /* virtual */
133  void
135  {
136  // outer one is the first in iteration
137  const Array::dimension& outerDim = *(dim_begin());
138  BESDEBUG(DEBUG_CHANNEL,
139  "Aggregating datasets array with outer dimension constraints: "
140  << " start=" << outerDim.start
141  << " stride=" << outerDim.stride
142  << " stop=" << outerDim.stop
143  << endl);
144 
145  // Be extra sure we have enough datasets for the given request
146  if (static_cast<unsigned int>(outerDim.size) != getDatasetList().size())
147  {
148  // Not sure whose fault it was, but tell the author
150  "The new outer dimension of the joinNew aggregation doesn't "
151  " have the same size as the number of datasets in the aggregation!");
152  }
153 
154  // Prepare our output buffer for our constrained length
155  reserve_value_capacity();
156 
157  // this index pointing into the value buffer for where to write.
158  // The buffer has a stride equal to the _pSubArrayProto->length().
159  int nextElementIndex = 0;
160 
161  // Traverse the dataset array respecting hyperslab
162  for (int i = outerDim.start;
163  i <= outerDim.stop && i < outerDim.size;
164  i += outerDim.stride)
165  {
166  AggMemberDataset& dataset = *((getDatasetList())[i]);
167 
168  try
169  {
171  *this, // into the output buffer of this object
172  nextElementIndex, // into the next open slice
173  getGranuleTemplateArray(), // constraints template
174  name(), // aggvar name
175  dataset, // Dataset who's DDS should be searched
177  DEBUG_CHANNEL
178  );
179  }
181  {
182  std::ostringstream oss;
183  oss << "Got AggregationException while streaming dataset index="
184  << i
185  << " data for location=\""
186  << dataset.getLocation()
187  << "\" The error msg was: "
188  << std::string(ex.what());
189  THROW_NCML_PARSE_ERROR(-1, oss.str());
190  }
191 
192  // Jump forward by the amount we added.
193  nextElementIndex += getGranuleTemplateArray().length();
194  }
195 
196  // If we succeeded, we are at the end of the array!
197  NCML_ASSERT_MSG(nextElementIndex == length(),
198  "Logic error:\n"
199  "ArrayAggregateOnOuterDimension::read(): "
200  "At end of aggregating, expected the nextElementIndex to be the length of the "
201  "aggregated array, but it wasn't!");
202  }
203 
204 }
ArrayAggregationBase & operator=(const ArrayAggregationBase &rhs)
Abstract helper superclass for allowing lazy access to the DataDDS for an aggregation.
virtual ~ArrayAggregateOnOuterDimension()
Destroy any local memory.
unsigned int size
Definition: Dimension.h:64
std::string name
Definition: Dimension.h:61
libdap::Array & getGranuleTemplateArray()
Accessor for subclasses Note this is protected, so not const! Subclasses may mutate the return hence ...
virtual ArrayAggregateOnOuterDimension * ptr_duplicate()
Virtual Constructor: Make a deep copy (clone) of the object and return it.
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...
#define NCML_ASSERT_MSG(cond, msg)
Definition: NCMLDebug.h:83
const std::string & getLocation() const
The location to which the AggMemberDataset refers Note: this could be "" for some subclasses if they ...
Base class for subclasses of libdap::Array which perform aggregation on a list of AggMemberDatasets w...
#define THROW_NCML_PARSE_ERROR(parseLine, msg)
Definition: NCMLDebug.h:69
Struct for holding information about a dimension of data, minimally a name and a cardinality (size)...
Definition: Dimension.h:50
const ArrayGetterInterface & getArrayGetterInterface() const
Accessor for subclasses Note this is protected, so not const! Subclasses may mutate the return hence ...
static void addDatasetArrayDataToAggregationOutputArray(libdap::Array &oOutputArray, unsigned int atIndex, const libdap::Array &constrainedTemplateArray, const string &varName, AggMemberDataset &dataset, const ArrayGetterInterface &arrayGetter, const string &debugChannel)
Load the given dataset's DataDDS.
virtual void transferOutputConstraintsIntoGranuleTemplateHook()
Subclass hook for read() to copy granule constraints properly (inner dim ones).
std::vector< RCPtr< AggMemberDataset > > AMDList
ArrayAggregateOnOuterDimension & operator=(const ArrayAggregateOnOuterDimension &rhs)
Assign this from rhs object.
const AMDList & getDatasetList() const
Get the list of AggMemberDataset's that comprise this aggregation.
ArrayAggregateOnOuterDimension(const libdap::Array &proto, const AMDList &memberDatasets, std::auto_ptr< ArrayGetterInterface > &arrayGetter, const Dimension &newDim)
Construct a joinNew Array aggregation given the parameters.
static void transferArrayConstraints(libdap::Array *pToArray, const libdap::Array &fromArray, bool skipFirstFromDim, bool skipFirstToDim, bool printDebug=false, const std::string &debugChannel="agg_util")
Copy the constraints from the from Array into the pToArray in Dim_iter order.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
Exception class used by AggregationUtil and other agg_util classes to pass generic exceptions upward ...
virtual void readConstrainedGranuleArraysAndAggregateDataHook()
Actually go through the constraints and stream the correctly constrained data into the superclass's o...