bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
Odometer.h
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
30namespace functions {
31
57{
58public:
59 typedef std::vector<unsigned int> shape;
60
61private:
62 // The state set by the ctor
63 shape d_shape;
64 size_t d_highest_offset;
65 size_t d_rank;
66
67 // The varying state of the Odometer
68 shape d_indices;
69 size_t d_offset{0};
70
71public:
80 explicit Odometer(shape shape) : d_shape(std::move(shape))
81 {
82 d_rank = d_shape.size();
83
84 // compute the highest offset value based on the array shape
85 d_highest_offset = 1;
86 for (unsigned int i = 0; i < d_rank; ++i) {
87 d_highest_offset *= d_shape.at(i);
88 }
89
90 d_indices.resize(d_rank, 0);
91 }
92
97 void reset()
98 {
99 for (unsigned int i = 0; i < d_rank; ++i)
100 d_indices.at(i) = 0;
101 d_offset = 0;
102 }
103
115 inline unsigned int next()
116 {
117 // About 2.4 seconds for 10^9 elements
118 auto si = d_shape.rbegin();
119 for (auto i = d_indices.rbegin(), e = d_indices.rend(); i != e; ++i, ++si) {
120 if (++(*i) == *si) {
121 *i = 0;
122 }
123 else {
124 break;
125 }
126 }
127
128 return ++d_offset;
129 }
130
131 // This version throws Error if offset() == end()
132 unsigned int next_safe();
133
141 inline unsigned int set_indices(const shape &indices)
142 {
143 d_indices = indices;
144
145 // I copied this algorithm from Nathan's code in NDimenensionalArray in the
146 // ugrid function module. jhrg 5/22/15
147
148 auto shape_index = d_shape.rbegin();
149 auto index = d_indices.rbegin(), index_end = d_indices.rend();
150 d_offset = *index++;
151 unsigned int chunk_size = *shape_index++;
152 while (index != index_end) {
153 d_offset += chunk_size * *index++;
154 chunk_size *= *shape_index++;
155 }
156
157 return d_offset;
158 }
159
160 unsigned int set_indices(const std::vector<int> &indices)
161 {
162 shape temp;
163 std::copy(indices.begin(), indices.end(), std::back_inserter(temp));
164
165 return set_indices(temp);
166 }
167
174 inline void indices(shape &indices)
175 {
176 indices = d_indices;
177 }
178
182 inline unsigned int offset()
183 {
184 return d_offset;
185 }
186
194 inline unsigned int end()
195 {
196 return d_highest_offset;
197 }
198
199};
200
201} // namespace libdap
202
203#endif /* ODOMETER_H_ */
unsigned int offset()
Definition Odometer.h:182
unsigned int set_indices(const shape &indices)
Definition Odometer.h:141
Odometer(shape shape)
Definition Odometer.h:80
void indices(shape &indices)
Definition Odometer.h:174
unsigned int end()
Definition Odometer.h:194
unsigned int next()
Definition Odometer.h:115