OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
Odometer.h
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2015 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 #ifndef ODOMETER_H_
26 #define ODOMETER_H_
27 
28 #include <vector>
29 
30 namespace libdap {
31 
38 class Odometer
39 {
40 public:
41  typedef std::vector<unsigned int> shape;
42 
43 private:
44  // The state set by the ctor
45  shape d_shape;
46  unsigned int d_highest_offset;
47  unsigned int d_rank;
48 
49  // The varying state of the Odometer
50  shape d_indices;
51  unsigned int d_offset;
52 
53 public:
62  Odometer(shape shape) :
63  d_shape(shape), d_offset(0)
64  {
65  d_rank = d_shape.size();
66 
67  d_highest_offset = 1;
68  for (unsigned int i = 0; i < d_rank; ++i) {
69  d_highest_offset *= d_shape.at(i);
70  }
71 
72  d_indices.resize(d_rank, 0);
73  }
74 
75  /*
76  * reset(): zero internal state
77  * next(): move to the next element, incrementing the shape information and returning an offset into a linear vector for that element.
78  * Calling next() when the object is at the last element should return one past the last element. calling next() after that should throw an exception.
79  * vector<int> indices(): for the given state of the odometer, return the indices that match the offset.
80  * offset(): return the offset
81  * end(): should return one past the last valid offset - the value returned by next() when it indicates all elements/indices have been visited.
82  *
83  */
84 
89  void reset()
90  {
91  for (unsigned int i = 0; i < d_rank; ++i)
92  d_indices.at(i) = 0;
93  d_offset = 0;
94  }
95 
107  inline unsigned int next()
108  {
109  // if (d_offset == d_highest_offset) throw Error("Attempt to move beyond the end of an array in the indexing software.");
110 
111  // About 2.4 seconds for 10^9 elements
112  shape::reverse_iterator si = d_shape.rbegin();
113  for (shape::reverse_iterator i = d_indices.rbegin(), e = d_indices.rend(); i != e; ++i, ++si) {
114  if (++(*i) == *si) {
115  *i = 0;
116  }
117  else {
118  break;
119  }
120  }
121 
122  return ++d_offset;
123  }
124 
125  // This version throws Error if offset() == end()
126  unsigned int next_safe();
127 
134  inline void indices(shape &indices)
135  {
136  indices = d_indices;
137  }
138 
142  inline unsigned int offset()
143  {
144  return d_offset;
145  }
146 
154  inline unsigned int end()
155  {
156  return d_highest_offset;
157  }
158 
159 };
160 
161 } // namespace libdap
162 
163 #endif /* ODOMETER_H_ */
void indices(shape &indices)
Return the current set of indices.
Definition: Odometer.h:134
std::vector< unsigned int > shape
Definition: Odometer.h:41
Odometer(shape shape)
Build an instance of Odometer using the given 'shape'.
Definition: Odometer.h:62
void reset()
Reset the internal state.
Definition: Odometer.h:89
unsigned int end()
Return the sentinel value that indicates that the offset (returned by offset()) is at the end of the ...
Definition: Odometer.h:154
static class NCMLUtil overview
unsigned int next_safe()
Definition: Odometer.cc:38
unsigned int offset()
The offset into memory for the current element.
Definition: Odometer.h:142
Map the indices of a N-dimensional array to the offset into memory that matches those indices...
Definition: Odometer.h:38
unsigned int next()
Increment the Odometer to the next element and return the offset value.
Definition: Odometer.h:107