/src/netcdf-c/libnczarr/zodom.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************* |
2 | | * Copyright 2018, UCAR/Unidata |
3 | | * See netcdf/COPYRIGHT file for copying and redistribution conditions. |
4 | | *********************************************************************/ |
5 | | #include "zincludes.h" |
6 | | |
7 | | /*Forward*/ |
8 | | static int buildodom(int rank, NCZOdometer** odomp); |
9 | | |
10 | | void |
11 | | nczodom_reset(NCZOdometer* odom) |
12 | 0 | { |
13 | 0 | int r; |
14 | 0 | for(r=0;r<odom->rank;r++) |
15 | 0 | odom->index[r] = odom->start[r]; |
16 | 0 | } |
17 | | |
18 | | NCZOdometer* |
19 | | nczodom_new(int rank, const size64_t* start, const size64_t* stop, const size64_t* stride, const size64_t* len) |
20 | 0 | { |
21 | 0 | int i; |
22 | 0 | NCZOdometer* odom = NULL; |
23 | 0 | if(buildodom(rank,&odom)) return NULL; |
24 | 0 | odom->properties.stride1 = 1; /* assume */ |
25 | 0 | odom->properties.start0 = 1; /* assume */ |
26 | 0 | for(i=0;i<rank;i++) { |
27 | 0 | odom->start[i] = (size64_t)start[i]; |
28 | 0 | odom->stop[i] = (size64_t)stop[i]; |
29 | 0 | odom->stride[i] = (size64_t)stride[i]; |
30 | 0 | odom->len[i] = (size64_t)len[i]; |
31 | 0 | if(odom->start[i] != 0) odom->properties.start0 = 0; |
32 | 0 | if(odom->stride[i] != 1) odom->properties.stride1 = 0; |
33 | 0 | } |
34 | 0 | nczodom_reset(odom); |
35 | 0 | for(i=0;i<rank;i++) |
36 | 0 | assert(stop[i] >= start[i] && stride[i] > 0 && (len[i]+1) >= stop[i]); |
37 | 0 | return odom; |
38 | 0 | } |
39 | | |
40 | | NCZOdometer* |
41 | | nczodom_fromslices(int rank, const NCZSlice* slices) |
42 | 0 | { |
43 | 0 | size_t i; |
44 | 0 | NCZOdometer* odom = NULL; |
45 | |
|
46 | 0 | if(buildodom(rank,&odom)) return NULL; |
47 | 0 | odom->properties.stride1 = 1; /* assume */ |
48 | 0 | odom->properties.start0 = 1; /* assume */ |
49 | 0 | for(i=0;i<rank;i++) { |
50 | 0 | odom->start[i] = slices[i].start; |
51 | 0 | odom->stop[i] = slices[i].stop; |
52 | 0 | odom->stride[i] = slices[i].stride; |
53 | 0 | odom->len[i] = slices[i].len; |
54 | 0 | if(odom->start[i] != 0) odom->properties.start0 = 0; |
55 | 0 | if(odom->stride[i] != 1) odom->properties.stride1 = 0; |
56 | 0 | } |
57 | 0 | nczodom_reset(odom); |
58 | 0 | for(i=0;i<rank;i++) { |
59 | 0 | assert(slices[i].stop >= slices[i].start && slices[i].stride > 0); |
60 | 0 | assert((slices[i].stop - slices[i].start) <= slices[i].len); |
61 | 0 | } |
62 | 0 | return odom; |
63 | 0 | } |
64 | | |
65 | | void |
66 | | nczodom_free(NCZOdometer* odom) |
67 | 0 | { |
68 | 0 | if(odom == NULL) return; |
69 | 0 | nullfree(odom->start); |
70 | 0 | nullfree(odom->stop); |
71 | 0 | nullfree(odom->stride); |
72 | 0 | nullfree(odom->len); |
73 | 0 | nullfree(odom->index); |
74 | 0 | nullfree(odom); |
75 | 0 | } |
76 | | |
77 | | int |
78 | | nczodom_more(const NCZOdometer* odom) |
79 | 0 | { |
80 | 0 | return (odom->index[0] < odom->stop[0]); |
81 | 0 | } |
82 | | |
83 | | void |
84 | | nczodom_next(NCZOdometer* odom) |
85 | 0 | { |
86 | 0 | int i; |
87 | 0 | int rank; |
88 | 0 | rank = odom->rank; |
89 | 0 | for(i=rank-1;i>=0;i--) { |
90 | 0 | odom->index[i] += odom->stride[i]; |
91 | 0 | if(odom->index[i] < odom->stop[i]) break; |
92 | 0 | if(i == 0) goto done; /* leave the 0th entry if it overflows */ |
93 | 0 | odom->index[i] = odom->start[i]; /* reset this position */ |
94 | 0 | } |
95 | 0 | done: |
96 | 0 | return; |
97 | 0 | } |
98 | | |
99 | | /* Get the value of the odometer */ |
100 | | size64_t* |
101 | | nczodom_indices(const NCZOdometer* odom) |
102 | 0 | { |
103 | 0 | return odom->index; |
104 | 0 | } |
105 | | |
106 | | size64_t |
107 | | nczodom_offset(const NCZOdometer* odom) |
108 | 0 | { |
109 | 0 | int i; |
110 | 0 | size64_t offset; |
111 | 0 | int rank = odom->rank; |
112 | |
|
113 | 0 | offset = 0; |
114 | 0 | for(i=0;i<rank;i++) { |
115 | 0 | #if 1 |
116 | 0 | offset *= odom->len[i]; |
117 | | #else |
118 | | offset *= odom->stop[i]; |
119 | | #endif |
120 | 0 | offset += odom->index[i]; |
121 | 0 | } |
122 | 0 | return offset; |
123 | 0 | } |
124 | | |
125 | | static int |
126 | | buildodom(int rank, NCZOdometer** odomp) |
127 | 0 | { |
128 | 0 | int stat = NC_NOERR; |
129 | 0 | NCZOdometer* odom = NULL; |
130 | 0 | if(odomp) { |
131 | 0 | if((odom = calloc(1,sizeof(NCZOdometer))) == NULL) |
132 | 0 | goto done; |
133 | 0 | odom->rank = rank; |
134 | 0 | if((odom->start=malloc(sizeof(size64_t)*rank))==NULL) goto nomem; |
135 | 0 | if((odom->stop=malloc(sizeof(size64_t)*rank))==NULL) goto nomem; |
136 | 0 | if((odom->stride=malloc(sizeof(size64_t)*rank))==NULL) goto nomem; |
137 | 0 | if((odom->len=malloc(sizeof(size64_t)*rank))==NULL) goto nomem; |
138 | 0 | if((odom->index=malloc(sizeof(size64_t)*rank))==NULL) goto nomem; |
139 | 0 | *odomp = odom; odom = NULL; |
140 | 0 | } |
141 | 0 | done: |
142 | 0 | nczodom_free(odom); |
143 | 0 | return stat; |
144 | 0 | nomem: |
145 | 0 | stat = NC_ENOMEM; |
146 | 0 | goto done; |
147 | 0 | } |
148 | | |
149 | | /* Compute the total avail in last position */ |
150 | | size64_t |
151 | | nczodom_avail(const NCZOdometer* odom) |
152 | 0 | { |
153 | 0 | size64_t avail; |
154 | | /* The best we can do is compute the count for the rightmost index */ |
155 | 0 | avail = (odom->stop[odom->rank-1] - odom->start[odom->rank-1]); |
156 | 0 | return avail; |
157 | 0 | } |
158 | | |
159 | | /* |
160 | | Incr the odometer by nczodom_avail() values. |
161 | | Calling nczodom_next at that point should properly increment |
162 | | rest of the odometer. |
163 | | */ |
164 | | void |
165 | | nczodom_skipavail(NCZOdometer* odom) |
166 | 0 | { |
167 | 0 | if(odom->rank > 0) |
168 | 0 | odom->index[odom->rank-1] = odom->stop[odom->rank-1]; |
169 | 0 | } |
170 | | |
171 | | #if 0 |
172 | | size64_t |
173 | | nczodom_laststride(const NCZOdometer* odom) |
174 | | { |
175 | | assert(odom != NULL && odom->rank > 0); |
176 | | return odom->stride[odom->rank-1]; |
177 | | } |
178 | | |
179 | | size64_t |
180 | | nczodom_lastlen(const NCZOdometer* odom) |
181 | | { |
182 | | assert(odom != NULL && odom->rank > 0); |
183 | | return odom->len[odom->rank-1]; |
184 | | } |
185 | | #endif |