1 | /* |
2 | * This Source Code Form is subject to the terms of the Mozilla Public |
3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
5 | * |
6 | * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V. |
7 | */ |
8 | |
9 | #include "monetdb_config.h" |
10 | #include "gdk.h" |
11 | #include "gdk_analytic.h" |
12 | #include "gdk_calc_private.h" |
13 | |
14 | #define ANALYTICAL_WINDOW_BOUNDS_ROWS_PRECEDING(LIMIT) \ |
15 | do { \ |
16 | lng calc1, calc2; \ |
17 | j = k; \ |
18 | for (; k < i; k++, rb++) { \ |
19 | lng rlimit = LIMIT; \ |
20 | SUB_WITH_CHECK(k, rlimit, lng, calc1, GDK_lng_max, goto calc_overflow); \ |
21 | ADD_WITH_CHECK(calc1, !first_half, lng, calc2, GDK_lng_max, goto calc_overflow); \ |
22 | *rb = MAX(calc2, j); \ |
23 | } \ |
24 | } while (0) |
25 | |
26 | #define ANALYTICAL_WINDOW_BOUNDS_ROWS_FOLLOWING(LIMIT) \ |
27 | do { \ |
28 | lng calc1, calc2; \ |
29 | for (; k < i; k++, rb++) { \ |
30 | lng rlimit = LIMIT; \ |
31 | ADD_WITH_CHECK(rlimit, k, lng, calc1, GDK_lng_max, goto calc_overflow); \ |
32 | ADD_WITH_CHECK(calc1, !first_half, lng, calc2, GDK_lng_max, goto calc_overflow); \ |
33 | *rb = MIN(calc2, i); \ |
34 | } \ |
35 | } while (0) |
36 | |
37 | #define ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE_PRECEDING(TPE1, LIMIT, TPE2) \ |
38 | do { \ |
39 | lng m = k - 1; \ |
40 | TPE1 v, calc; \ |
41 | TPE2 rlimit; \ |
42 | if (b->tnonil) { \ |
43 | for (; k < i; k++, rb++) { \ |
44 | rlimit = (TPE2) LIMIT; \ |
45 | v = bp[k]; \ |
46 | for (j = k; ; j--) { \ |
47 | if (j == m) \ |
48 | break; \ |
49 | SUB_WITH_CHECK(v, bp[j], TPE1, calc, GDK_##TPE1##_max, goto calc_overflow); \ |
50 | if ((TPE2)(ABSOLUTE(calc)) > rlimit) \ |
51 | break; \ |
52 | } \ |
53 | j++; \ |
54 | *rb = j; \ |
55 | } \ |
56 | } else { \ |
57 | for (; k < i; k++, rb++) { \ |
58 | rlimit = (TPE2) LIMIT; \ |
59 | v = bp[k]; \ |
60 | if (is_##TPE1##_nil(v)) { \ |
61 | for (j = k; ; j--) { \ |
62 | if (j == m) \ |
63 | break; \ |
64 | if (!is_##TPE1##_nil(bp[j])) \ |
65 | break; \ |
66 | } \ |
67 | } else { \ |
68 | for (j = k; ; j--) { \ |
69 | if (j == m) \ |
70 | break; \ |
71 | if (is_##TPE1##_nil(bp[j])) \ |
72 | break; \ |
73 | SUB_WITH_CHECK(v, bp[j], TPE1, calc, GDK_##TPE1##_max, goto calc_overflow); \ |
74 | if ((TPE2)(ABSOLUTE(calc)) > rlimit) \ |
75 | break; \ |
76 | } \ |
77 | } \ |
78 | j++; \ |
79 | *rb = j; \ |
80 | } \ |
81 | } \ |
82 | } while (0) |
83 | |
84 | #define ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE_FOLLOWING(TPE1, LIMIT, TPE2) \ |
85 | do { \ |
86 | TPE1 v, calc; \ |
87 | TPE2 rlimit; \ |
88 | if (b->tnonil) { \ |
89 | for (; k < i; k++, rb++) { \ |
90 | rlimit = (TPE2) LIMIT; \ |
91 | v = bp[k]; \ |
92 | for (j = k + 1; j < i; j++) { \ |
93 | SUB_WITH_CHECK(v, bp[j], TPE1, calc, GDK_##TPE1##_max, goto calc_overflow); \ |
94 | if ((TPE2)(ABSOLUTE(calc)) > rlimit) \ |
95 | break; \ |
96 | } \ |
97 | *rb = j; \ |
98 | } \ |
99 | } else { \ |
100 | for (; k < i; k++, rb++) { \ |
101 | rlimit = (TPE2) LIMIT; \ |
102 | v = bp[k]; \ |
103 | if (is_##TPE1##_nil(v)) { \ |
104 | for (j =k + 1; j < i; j++) { \ |
105 | if (!is_##TPE1##_nil(bp[j])) \ |
106 | break; \ |
107 | } \ |
108 | } else { \ |
109 | for (j = k + 1; j < i; j++) { \ |
110 | if (is_##TPE1##_nil(bp[j])) \ |
111 | break; \ |
112 | SUB_WITH_CHECK(v, bp[j], TPE1, calc, GDK_##TPE1##_max, goto calc_overflow); \ |
113 | if ((TPE2)(ABSOLUTE(calc)) > rlimit) \ |
114 | break; \ |
115 | } \ |
116 | } \ |
117 | *rb = j; \ |
118 | } \ |
119 | } \ |
120 | } while (0) |
121 | |
122 | #define ANALYTICAL_WINDOW_BOUNDS_FIXED_GROUPS_PRECEDING(TPE1, LIMIT, TPE2) \ |
123 | do { \ |
124 | lng m = k - 1; \ |
125 | if (b->tnonil) { \ |
126 | for (; k < i; k++, rb++) { \ |
127 | TPE2 rlimit = LIMIT; \ |
128 | TPE1 v = bp[k]; \ |
129 | for (j = k; ; j--) { \ |
130 | if (j == m) \ |
131 | break; \ |
132 | if (v != bp[j]) { \ |
133 | if (rlimit == 0) \ |
134 | break; \ |
135 | rlimit--; \ |
136 | v = bp[j]; \ |
137 | } \ |
138 | } \ |
139 | j++; \ |
140 | *rb = j; \ |
141 | } \ |
142 | } else { \ |
143 | for (; k < i; k++, rb++) { \ |
144 | TPE2 rlimit = LIMIT; \ |
145 | TPE1 v = bp[k]; \ |
146 | if (is_##TPE1##_nil(v)) { \ |
147 | for (j = k; ; j--) { \ |
148 | if (j == m) \ |
149 | break; \ |
150 | if (!is_##TPE1##_nil(bp[j])) \ |
151 | break; \ |
152 | } \ |
153 | } else { \ |
154 | for (j = k; ; j--) { \ |
155 | if (j == m) \ |
156 | break; \ |
157 | if (is_##TPE1##_nil(bp[j])) \ |
158 | break; \ |
159 | if (v != bp[j]) { \ |
160 | if (rlimit == 0) \ |
161 | break; \ |
162 | rlimit--; \ |
163 | v = bp[j]; \ |
164 | } \ |
165 | } \ |
166 | } \ |
167 | j++; \ |
168 | *rb = j; \ |
169 | } \ |
170 | } \ |
171 | } while (0) |
172 | |
173 | #define ANALYTICAL_WINDOW_BOUNDS_FIXED_GROUPS_FOLLOWING(TPE1, LIMIT, TPE2) \ |
174 | do { \ |
175 | if (b->tnonil) { \ |
176 | for (; k < i; k++, rb++) { \ |
177 | TPE2 rlimit = LIMIT; \ |
178 | TPE1 v = bp[k]; \ |
179 | for (j = k + 1; j < i; j++) { \ |
180 | if (v != bp[j]) { \ |
181 | if (rlimit == 0) \ |
182 | break; \ |
183 | rlimit--; \ |
184 | v = bp[j]; \ |
185 | } \ |
186 | } \ |
187 | *rb = j; \ |
188 | } \ |
189 | } else { \ |
190 | for (; k < i; k++, rb++) { \ |
191 | TPE2 rlimit = LIMIT; \ |
192 | TPE1 v = bp[k]; \ |
193 | if (is_##TPE1##_nil(v)) { \ |
194 | for (j = k + 1; j < i; j++) { \ |
195 | if (!is_##TPE1##_nil(bp[j])) \ |
196 | break; \ |
197 | } \ |
198 | } else { \ |
199 | for (j = k + 1; j < i; j++) { \ |
200 | if (is_##TPE1##_nil(bp[j])) \ |
201 | break; \ |
202 | if (v != bp[j]) { \ |
203 | if (rlimit == 0) \ |
204 | break; \ |
205 | rlimit--; \ |
206 | v = bp[j]; \ |
207 | } \ |
208 | } \ |
209 | } \ |
210 | *rb = j; \ |
211 | } \ |
212 | } \ |
213 | } while (0) |
214 | |
215 | #define ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(TPE1, IMP, LIMIT, TPE2) \ |
216 | do { \ |
217 | TPE1 *restrict bp = (TPE1*)Tloc(b, 0); \ |
218 | if (np) { \ |
219 | nend += cnt; \ |
220 | for (; np < nend; np++) { \ |
221 | if (*np) { \ |
222 | i += (np - pnp); \ |
223 | IMP(TPE1, LIMIT, TPE2); \ |
224 | pnp = np; \ |
225 | } \ |
226 | } \ |
227 | i += (np - pnp); \ |
228 | IMP(TPE1, LIMIT, TPE2); \ |
229 | } else { \ |
230 | i += (lng) cnt; \ |
231 | IMP(TPE1, LIMIT, TPE2); \ |
232 | } \ |
233 | } while (0) |
234 | |
235 | #define ANALYTICAL_WINDOW_BOUNDS_VARSIZED_RANGE_PRECEDING(LIMIT, TPE) \ |
236 | do { \ |
237 | lng m = k - 1; \ |
238 | if (b->tnonil) { \ |
239 | for (; k < i; k++, rb++) { \ |
240 | void *v = BUNtail(bpi, (BUN) k); \ |
241 | for (j = k; ; j--) { \ |
242 | void *next; \ |
243 | if (j == m) \ |
244 | break; \ |
245 | next = BUNtail(bpi, (BUN) j); \ |
246 | if (ABSOLUTE((TPE) atomcmp(v, next)) > (TPE) LIMIT) \ |
247 | break; \ |
248 | } \ |
249 | j++; \ |
250 | *rb = j; \ |
251 | } \ |
252 | } else { \ |
253 | for (; k < i; k++, rb++) { \ |
254 | void *v = BUNtail(bpi, (BUN) k); \ |
255 | if (atomcmp(v, nil) == 0) { \ |
256 | for (j = k; ; j--) { \ |
257 | if (j == m) \ |
258 | break; \ |
259 | if (atomcmp(BUNtail(bpi, (BUN) j), nil) != 0) \ |
260 | break; \ |
261 | } \ |
262 | } else { \ |
263 | for (j = k; ; j--) { \ |
264 | void *next; \ |
265 | if (j == m) \ |
266 | break; \ |
267 | next = BUNtail(bpi, (BUN) j); \ |
268 | if (atomcmp(next, nil) == 0) \ |
269 | break; \ |
270 | if (ABSOLUTE((TPE) atomcmp(v, next)) > (TPE) LIMIT) \ |
271 | break; \ |
272 | } \ |
273 | } \ |
274 | j++; \ |
275 | *rb = j; \ |
276 | } \ |
277 | } \ |
278 | } while (0) |
279 | |
280 | #define ANALYTICAL_WINDOW_BOUNDS_VARSIZED_RANGE_FOLLOWING(LIMIT, TPE) \ |
281 | do { \ |
282 | if (b->tnonil) { \ |
283 | for (; k < i; k++, rb++) { \ |
284 | void *v = BUNtail(bpi, (BUN) k); \ |
285 | for (j = k + 1; j < i; j++) { \ |
286 | void *next = BUNtail(bpi, (BUN) j); \ |
287 | if (ABSOLUTE((TPE) atomcmp(v, next)) > (TPE) LIMIT) \ |
288 | break; \ |
289 | } \ |
290 | *rb = j; \ |
291 | } \ |
292 | } else { \ |
293 | for (; k < i; k++, rb++) { \ |
294 | void *v = BUNtail(bpi, (BUN) k); \ |
295 | if (atomcmp(v, nil) == 0) { \ |
296 | for (j = k + 1; j < i; j++) { \ |
297 | if (atomcmp(BUNtail(bpi, (BUN) j), nil) != 0) \ |
298 | break; \ |
299 | } \ |
300 | } else { \ |
301 | for (j = k + 1; j < i; j++) { \ |
302 | void *next = BUNtail(bpi, (BUN) j); \ |
303 | if (atomcmp(next, nil) == 0) \ |
304 | break; \ |
305 | if (ABSOLUTE((TPE) atomcmp(v, next)) > (TPE) LIMIT) \ |
306 | break; \ |
307 | } \ |
308 | } \ |
309 | *rb = j; \ |
310 | } \ |
311 | } \ |
312 | } while (0) |
313 | |
314 | #define ANALYTICAL_WINDOW_BOUNDS_VARSIZED_GROUPS_PRECEDING(LIMIT, TPE) \ |
315 | do { \ |
316 | lng m = k - 1; \ |
317 | if (b->tnonil) { \ |
318 | for (; k < i; k++, rb++) { \ |
319 | TPE rlimit = LIMIT; \ |
320 | void *v = BUNtail(bpi, (BUN) k); \ |
321 | for (j = k; ; j--) { \ |
322 | void *next; \ |
323 | if (j == m) \ |
324 | break; \ |
325 | next = BUNtail(bpi, (BUN) j); \ |
326 | if (atomcmp(v, next)) { \ |
327 | if (rlimit == 0) \ |
328 | break; \ |
329 | rlimit--; \ |
330 | v = next; \ |
331 | } \ |
332 | } \ |
333 | j++; \ |
334 | *rb = j; \ |
335 | } \ |
336 | } else { \ |
337 | for (; k < i; k++, rb++) { \ |
338 | TPE rlimit = LIMIT; \ |
339 | void *v = BUNtail(bpi, (BUN) k); \ |
340 | if (atomcmp(v, nil) == 0) { \ |
341 | for (j = k; ; j--) { \ |
342 | if (j == m) \ |
343 | break; \ |
344 | if (atomcmp(BUNtail(bpi, (BUN) j), nil) != 0) \ |
345 | break; \ |
346 | } \ |
347 | } else { \ |
348 | for (j = k; ; j--) { \ |
349 | void *next; \ |
350 | if (j == m) \ |
351 | break; \ |
352 | next = BUNtail(bpi, (BUN) j); \ |
353 | if (atomcmp(next, nil) == 0) \ |
354 | break; \ |
355 | if (atomcmp(v, next)) { \ |
356 | if (rlimit == 0) \ |
357 | break; \ |
358 | rlimit--; \ |
359 | v = next; \ |
360 | } \ |
361 | } \ |
362 | } \ |
363 | j++; \ |
364 | *rb = j; \ |
365 | } \ |
366 | } \ |
367 | } while (0) |
368 | |
369 | #define ANALYTICAL_WINDOW_BOUNDS_VARSIZED_GROUPS_FOLLOWING(LIMIT, TPE) \ |
370 | do { \ |
371 | if (b->tnonil) { \ |
372 | for (; k < i; k++, rb++) { \ |
373 | TPE rlimit = LIMIT; \ |
374 | void *v = BUNtail(bpi, (BUN) k); \ |
375 | for (j = k + 1; j < i; j++) { \ |
376 | void *next = BUNtail(bpi, (BUN) j); \ |
377 | if (atomcmp(v, next)) { \ |
378 | if (rlimit == 0) \ |
379 | break; \ |
380 | rlimit--; \ |
381 | v = next; \ |
382 | } \ |
383 | } \ |
384 | *rb = j; \ |
385 | } \ |
386 | } else { \ |
387 | for (; k < i; k++, rb++) { \ |
388 | TPE rlimit = LIMIT; \ |
389 | void *v = BUNtail(bpi, (BUN) k); \ |
390 | if (atomcmp(v, nil) == 0) { \ |
391 | for (j = k + 1; j < i; j++) { \ |
392 | if (atomcmp(BUNtail(bpi, (BUN) j), nil) != 0) \ |
393 | break; \ |
394 | } \ |
395 | } else { \ |
396 | for (j = k + 1; j < i; j++) { \ |
397 | void *next = BUNtail(bpi, (BUN) j); \ |
398 | if (atomcmp(next, nil) == 0) \ |
399 | break; \ |
400 | if (atomcmp(v, next)) { \ |
401 | if (rlimit == 0) \ |
402 | break; \ |
403 | rlimit--; \ |
404 | v = next; \ |
405 | } \ |
406 | } \ |
407 | } \ |
408 | *rb = j; \ |
409 | } \ |
410 | } \ |
411 | } while (0) |
412 | |
413 | #define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(IMP, LIMIT) \ |
414 | do { \ |
415 | if (p) { \ |
416 | pnp = np = (bit*)Tloc(p, 0); \ |
417 | nend = np + cnt; \ |
418 | for (; np < nend; np++) { \ |
419 | if (*np) { \ |
420 | i += (np - pnp); \ |
421 | ANALYTICAL_WINDOW_BOUNDS_ROWS##IMP(LIMIT); \ |
422 | pnp = np; \ |
423 | } \ |
424 | } \ |
425 | i += (np - pnp); \ |
426 | ANALYTICAL_WINDOW_BOUNDS_ROWS##IMP(LIMIT); \ |
427 | } else { \ |
428 | i += (lng) cnt; \ |
429 | ANALYTICAL_WINDOW_BOUNDS_ROWS##IMP(LIMIT); \ |
430 | } \ |
431 | } while (0) |
432 | |
433 | #define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(IMP, LIMIT, CAST) \ |
434 | do { \ |
435 | switch (tp1) { \ |
436 | case TYPE_bit: \ |
437 | case TYPE_flt: \ |
438 | case TYPE_dbl: \ |
439 | goto type_not_supported; \ |
440 | case TYPE_bte: \ |
441 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(bte, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, lng); \ |
442 | break; \ |
443 | case TYPE_sht: \ |
444 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(sht, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, lng); \ |
445 | break; \ |
446 | case TYPE_int: \ |
447 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(int, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, lng); \ |
448 | break; \ |
449 | case TYPE_lng: \ |
450 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(lng, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, lng); \ |
451 | break; \ |
452 | default: { \ |
453 | if (p) { \ |
454 | pnp = np = (bit*)Tloc(p, 0); \ |
455 | nend = np + cnt; \ |
456 | for (; np < nend; np++) { \ |
457 | if (*np) { \ |
458 | i += (np - pnp); \ |
459 | ANALYTICAL_WINDOW_BOUNDS_VARSIZED_RANGE##IMP(LIMIT, CAST); \ |
460 | pnp = np; \ |
461 | } \ |
462 | } \ |
463 | i += (np - pnp); \ |
464 | ANALYTICAL_WINDOW_BOUNDS_VARSIZED_RANGE##IMP(LIMIT, CAST); \ |
465 | } else { \ |
466 | i += (lng) cnt; \ |
467 | ANALYTICAL_WINDOW_BOUNDS_VARSIZED_RANGE##IMP(LIMIT, CAST); \ |
468 | } \ |
469 | } \ |
470 | } \ |
471 | } while (0) |
472 | |
473 | #define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_FLT(IMP, LIMIT) \ |
474 | do { \ |
475 | switch (tp1) { \ |
476 | case TYPE_flt: \ |
477 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(flt, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, flt); \ |
478 | break; \ |
479 | default: \ |
480 | goto type_not_supported; \ |
481 | } \ |
482 | } while (0) |
483 | |
484 | #define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_DBL(IMP, LIMIT) \ |
485 | do { \ |
486 | switch (tp1) { \ |
487 | case TYPE_dbl: \ |
488 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(dbl, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, dbl); \ |
489 | break; \ |
490 | default: \ |
491 | goto type_not_supported; \ |
492 | } \ |
493 | } while (0) |
494 | |
495 | #ifdef HAVE_HGE |
496 | #define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_HGE(IMP, LIMIT) \ |
497 | do { \ |
498 | switch (tp1) { \ |
499 | case TYPE_bit: \ |
500 | case TYPE_flt: \ |
501 | case TYPE_dbl: \ |
502 | goto type_not_supported; \ |
503 | case TYPE_bte: \ |
504 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(bte, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, hge); \ |
505 | break; \ |
506 | case TYPE_sht: \ |
507 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(sht, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, hge); \ |
508 | break; \ |
509 | case TYPE_int: \ |
510 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(int, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, hge); \ |
511 | break; \ |
512 | case TYPE_lng: \ |
513 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(lng, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, hge); \ |
514 | break; \ |
515 | case TYPE_hge: \ |
516 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(hge, ANALYTICAL_WINDOW_BOUNDS_FIXED_RANGE##IMP, LIMIT, hge); \ |
517 | break; \ |
518 | default: { \ |
519 | if (p) { \ |
520 | pnp = np = (bit*)Tloc(p, 0); \ |
521 | nend = np + cnt; \ |
522 | for (; np < nend; np++) { \ |
523 | if (*np) { \ |
524 | i += (np - pnp); \ |
525 | ANALYTICAL_WINDOW_BOUNDS_VARSIZED_RANGE##IMP(LIMIT, hge); \ |
526 | pnp = np; \ |
527 | } \ |
528 | } \ |
529 | i += (np - pnp); \ |
530 | ANALYTICAL_WINDOW_BOUNDS_VARSIZED_RANGE##IMP(LIMIT, hge); \ |
531 | } else { \ |
532 | i += (lng) cnt; \ |
533 | ANALYTICAL_WINDOW_BOUNDS_VARSIZED_RANGE##IMP(LIMIT, hge); \ |
534 | } \ |
535 | } \ |
536 | } \ |
537 | } while (0) |
538 | #endif |
539 | |
540 | #ifdef HAVE_HGE |
541 | #define ANALYTICAL_WINDOW_BOUNDS_GROUPS_HGE(IMP, LIMIT, TPE) \ |
542 | case TYPE_hge: \ |
543 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(hge, ANALYTICAL_WINDOW_BOUNDS_FIXED_GROUPS##IMP, LIMIT, TPE); \ |
544 | break; |
545 | #else |
546 | #define ANALYTICAL_WINDOW_BOUNDS_GROUPS_HGE(IMP, LIMIT, TPE) |
547 | #endif |
548 | |
549 | #define ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(IMP, LIMIT, TPE) \ |
550 | do { \ |
551 | switch (tp1) { \ |
552 | case TYPE_bit: \ |
553 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(bit, ANALYTICAL_WINDOW_BOUNDS_FIXED_GROUPS##IMP, LIMIT, TPE); \ |
554 | break; \ |
555 | case TYPE_bte: \ |
556 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(bte, ANALYTICAL_WINDOW_BOUNDS_FIXED_GROUPS##IMP, LIMIT, TPE); \ |
557 | break; \ |
558 | case TYPE_sht: \ |
559 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(sht, ANALYTICAL_WINDOW_BOUNDS_FIXED_GROUPS##IMP, LIMIT, TPE); \ |
560 | break; \ |
561 | case TYPE_int: \ |
562 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(int, ANALYTICAL_WINDOW_BOUNDS_FIXED_GROUPS##IMP, LIMIT, TPE); \ |
563 | break; \ |
564 | case TYPE_lng: \ |
565 | ANALYTICAL_WINDOW_BOUNDS_CALC_FIXED(lng, ANALYTICAL_WINDOW_BOUNDS_FIXED_GROUPS##IMP, LIMIT, TPE); \ |
566 | break; \ |
567 | ANALYTICAL_WINDOW_BOUNDS_GROUPS_HGE(IMP, LIMIT, TPE); \ |
568 | default: { \ |
569 | if (p) { \ |
570 | pnp = np = (bit*)Tloc(p, 0); \ |
571 | nend = np + cnt; \ |
572 | for (; np < nend; np++) { \ |
573 | if (*np) { \ |
574 | i += (np - pnp); \ |
575 | ANALYTICAL_WINDOW_BOUNDS_VARSIZED_GROUPS##IMP(LIMIT, TPE); \ |
576 | pnp = np; \ |
577 | } \ |
578 | } \ |
579 | i += (np - pnp); \ |
580 | ANALYTICAL_WINDOW_BOUNDS_VARSIZED_GROUPS##IMP(LIMIT, TPE); \ |
581 | } else { \ |
582 | i += (lng) cnt; \ |
583 | ANALYTICAL_WINDOW_BOUNDS_VARSIZED_GROUPS##IMP(LIMIT, TPE); \ |
584 | } \ |
585 | } \ |
586 | } \ |
587 | } while (0) |
588 | |
589 | static gdk_return |
590 | GDKanalyticalallbounds(BAT *r, BAT *b, BAT *p, bool preceding) |
591 | { |
592 | BUN cnt = BATcount(b); |
593 | lng *restrict rb = (lng *) Tloc(r, 0), i = 0, k = 0, j = 0; |
594 | bit *np = p ? (bit *) Tloc(p, 0) : NULL, *pnp = np, *nend = np; |
595 | |
596 | if (preceding) { |
597 | if (np) { |
598 | nend += cnt; |
599 | for (; np < nend; np++) { |
600 | if (*np) { |
601 | i += (np - pnp); |
602 | j = k; |
603 | for (; k < i; k++) |
604 | rb[k] = j; |
605 | pnp = np; |
606 | } |
607 | } |
608 | i += (np - pnp); |
609 | j = k; |
610 | for (; k < i; k++) |
611 | rb[k] = j; |
612 | } else { |
613 | i += (lng) cnt; |
614 | j = k; |
615 | for (; k < i; k++) |
616 | rb[k] = j; |
617 | } |
618 | } else if (np) { /* following */ |
619 | nend += cnt; |
620 | for (; np < nend; np++) { |
621 | if (*np) { |
622 | i += (np - pnp); |
623 | for (; k < i; k++) |
624 | rb[k] = i; |
625 | pnp = np; |
626 | } |
627 | } |
628 | i += (np - pnp); |
629 | for (; k < i; k++) |
630 | rb[k] = i; |
631 | } else { |
632 | i += (lng) cnt; |
633 | for (; k < i; k++) |
634 | rb[k] = i; |
635 | } |
636 | |
637 | BATsetcount(r, cnt); |
638 | r->tnonil = false; |
639 | r->tnil = false; |
640 | return GDK_SUCCEED; |
641 | } |
642 | |
643 | static gdk_return |
644 | GDKanalyticalrowbounds(BAT *r, BAT *b, BAT *p, BAT *l, const void *restrict bound, int tp2, bool preceding, lng first_half) |
645 | { |
646 | BUN cnt = BATcount(b), nils = 0; |
647 | lng *restrict rb = (lng *) Tloc(r, 0), i = 0, k = 0, j = 0; |
648 | bit *np, *pnp, *nend; |
649 | int abort_on_error = 1; |
650 | |
651 | if (l) { /* dynamic bounds */ |
652 | switch (tp2) { |
653 | case TYPE_bte:{ |
654 | bte *restrict limit = (bte *) Tloc(l, 0); |
655 | if (preceding) { |
656 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (lng) limit[k]); |
657 | } else { |
658 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (lng) limit[k]); |
659 | } |
660 | break; |
661 | } |
662 | case TYPE_sht:{ |
663 | sht *restrict limit = (sht *) Tloc(l, 0); |
664 | if (preceding) { |
665 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (lng) limit[k]); |
666 | } else { |
667 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (lng) limit[k]); |
668 | } |
669 | break; |
670 | } |
671 | case TYPE_int:{ |
672 | int *restrict limit = (int *) Tloc(l, 0); |
673 | if (preceding) { |
674 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (lng) limit[k]); |
675 | } else { |
676 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (lng) limit[k]); |
677 | } |
678 | break; |
679 | } |
680 | case TYPE_lng:{ |
681 | lng *restrict limit = (lng *) Tloc(l, 0); |
682 | if (preceding) { |
683 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (lng) limit[k]); |
684 | } else { |
685 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (lng) limit[k]); |
686 | } |
687 | break; |
688 | } |
689 | #ifdef HAVE_HGE |
690 | case TYPE_hge:{ |
691 | hge *restrict limit = (hge *) Tloc(l, 0); |
692 | if (preceding) { |
693 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, (limit[k] > (hge) GDK_lng_max) ? GDK_lng_max : (lng) limit[k]); |
694 | } else { |
695 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, (limit[k] > (hge) GDK_lng_max) ? GDK_lng_max : (lng) limit[k]); |
696 | } |
697 | break; |
698 | } |
699 | #endif |
700 | default: |
701 | goto bound_not_supported; |
702 | } |
703 | } else { /* static bounds, all the limits are cast to lng */ |
704 | lng limit; |
705 | switch (tp2) { |
706 | case TYPE_bte: |
707 | limit = is_bte_nil(*(bte *) bound) ? lng_nil : (lng) *(bte *) bound; |
708 | break; |
709 | case TYPE_sht: |
710 | limit = is_sht_nil(*(sht *) bound) ? lng_nil : (lng) *(sht *) bound; |
711 | break; |
712 | case TYPE_int: |
713 | limit = is_int_nil(*(int *) bound) ? lng_nil : (lng) *(int *) bound; |
714 | break; |
715 | case TYPE_lng: |
716 | limit = (lng) (*(lng *) bound); |
717 | break; |
718 | #ifdef HAVE_HGE |
719 | case TYPE_hge: { |
720 | hge nval = *(hge *) bound; |
721 | limit = is_hge_nil(nval) ? lng_nil : (nval > (hge) GDK_lng_max) ? GDK_lng_max : (lng) nval; |
722 | break; |
723 | } |
724 | #endif |
725 | default: |
726 | goto bound_not_supported; |
727 | } |
728 | if (is_lng_nil(limit)) { |
729 | return GDKanalyticalallbounds(r, b, p, preceding); |
730 | } else if (preceding) { |
731 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_PRECEDING, limit); |
732 | } else { |
733 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_ROWS(_FOLLOWING, limit); |
734 | } |
735 | } |
736 | |
737 | BATsetcount(r, cnt); |
738 | r->tnonil = (nils == 0); |
739 | r->tnil = (nils > 0); |
740 | return GDK_SUCCEED; |
741 | bound_not_supported: |
742 | GDKerror("GDKanalyticalrowbounds: rows frame bound type %s not supported.\n" , ATOMname(tp2)); |
743 | return GDK_FAIL; |
744 | calc_overflow: |
745 | GDKerror("22003!overflow in calculation.\n" ); |
746 | return GDK_FAIL; |
747 | } |
748 | |
749 | static gdk_return |
750 | GDKanalyticalrangebounds(BAT *r, BAT *b, BAT *p, BAT *l, const void *restrict bound, int tp1, int tp2, bool preceding) |
751 | { |
752 | BUN cnt = BATcount(b), nils = 0; |
753 | lng *restrict rb = (lng *) Tloc(r, 0), i = 0, k = 0, j = 0; |
754 | bit *np = p ? (bit *) Tloc(p, 0) : NULL, *pnp = np, *nend = np; |
755 | BATiter bpi = bat_iterator(b); |
756 | int (*atomcmp) (const void *, const void *) = ATOMcompare(tp1); |
757 | const void *restrict nil = ATOMnilptr(tp1); |
758 | int abort_on_error = 1; |
759 | |
760 | if (l) { /* dynamic bounds */ |
761 | switch (tp2) { |
762 | case TYPE_bte:{ |
763 | bte *restrict limit = (bte *) Tloc(l, 0); |
764 | if (preceding) { |
765 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_PRECEDING, limit[k], int); |
766 | } else { |
767 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_FOLLOWING, limit[k], int); |
768 | } |
769 | break; |
770 | } |
771 | case TYPE_sht:{ |
772 | sht *restrict limit = (sht *) Tloc(l, 0); |
773 | if (preceding) { |
774 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_PRECEDING, limit[k], int); |
775 | } else { |
776 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_FOLLOWING, limit[k], int); |
777 | } |
778 | break; |
779 | } |
780 | case TYPE_int:{ |
781 | int *restrict limit = (int *) Tloc(l, 0); |
782 | if (preceding) { |
783 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_PRECEDING, limit[k], int); |
784 | } else { |
785 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_FOLLOWING, limit[k], int); |
786 | } |
787 | break; |
788 | } |
789 | case TYPE_lng:{ |
790 | lng *restrict limit = (lng *) Tloc(l, 0); |
791 | if (preceding) { |
792 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_PRECEDING, limit[k], lng); |
793 | } else { |
794 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_FOLLOWING, limit[k], lng); |
795 | } |
796 | break; |
797 | } |
798 | case TYPE_flt:{ |
799 | flt *restrict limit = (flt *) Tloc(l, 0); |
800 | if (preceding) { |
801 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_FLT(_PRECEDING, limit[k]); |
802 | } else { |
803 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_FLT(_FOLLOWING, limit[k]); |
804 | } |
805 | break; |
806 | } |
807 | case TYPE_dbl:{ |
808 | dbl *restrict limit = (dbl *) Tloc(l, 0); |
809 | if (preceding) { |
810 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_DBL(_PRECEDING, limit[k]); |
811 | } else { |
812 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_DBL(_FOLLOWING, limit[k]); |
813 | } |
814 | break; |
815 | } |
816 | #ifdef HAVE_HGE |
817 | case TYPE_hge:{ |
818 | hge *restrict limit = (hge *) Tloc(l, 0); |
819 | if (preceding) { |
820 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_HGE(_PRECEDING, limit[k]); |
821 | } else { |
822 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_HGE(_FOLLOWING, limit[k]); |
823 | } |
824 | break; |
825 | } |
826 | #endif |
827 | default: |
828 | goto bound_not_supported; |
829 | } |
830 | } else { /* static bounds */ |
831 | switch (tp2) { |
832 | case TYPE_bte: |
833 | case TYPE_sht: |
834 | case TYPE_int: |
835 | case TYPE_lng:{ |
836 | lng limit = 0; |
837 | switch (tp2) { |
838 | case TYPE_bte:{ |
839 | bte ll = (*(bte *) bound); |
840 | if (is_bte_nil(ll)) /* UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING cases, avoid overflow */ |
841 | return GDKanalyticalallbounds(r, b, p, preceding); |
842 | else |
843 | limit = (lng) ll; |
844 | break; |
845 | } |
846 | case TYPE_sht:{ |
847 | sht ll = (*(sht *) bound); |
848 | if (is_sht_nil(ll)) |
849 | return GDKanalyticalallbounds(r, b, p, preceding); |
850 | else |
851 | limit = (lng) ll; |
852 | break; |
853 | } |
854 | case TYPE_int:{ |
855 | int ll = (*(int *) bound); |
856 | if (is_int_nil(ll)) |
857 | return GDKanalyticalallbounds(r, b, p, preceding); |
858 | else |
859 | limit = (lng) ll; |
860 | break; |
861 | } |
862 | case TYPE_lng:{ |
863 | lng ll = (*(lng *) bound); |
864 | if (is_lng_nil(ll)) |
865 | return GDKanalyticalallbounds(r, b, p, preceding); |
866 | else |
867 | limit = (lng) ll; |
868 | break; |
869 | } |
870 | default: |
871 | assert(0); |
872 | } |
873 | if (preceding) { |
874 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_PRECEDING, limit, lng); |
875 | } else { |
876 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_NUM(_FOLLOWING, limit, lng); |
877 | } |
878 | break; |
879 | } |
880 | case TYPE_flt:{ |
881 | flt limit = (*(flt *) bound); |
882 | if (is_flt_nil(limit)) { |
883 | return GDKanalyticalallbounds(r, b, p, preceding); |
884 | } else if (preceding) { |
885 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_FLT(_PRECEDING, limit); |
886 | } else { |
887 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_FLT(_FOLLOWING, limit); |
888 | } |
889 | break; |
890 | } |
891 | case TYPE_dbl:{ |
892 | dbl limit = (*(dbl *) bound); |
893 | if (is_dbl_nil(limit)) { |
894 | return GDKanalyticalallbounds(r, b, p, preceding); |
895 | } else if (preceding) { |
896 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_DBL(_PRECEDING, limit); |
897 | } else { |
898 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_DBL(_FOLLOWING, limit); |
899 | } |
900 | break; |
901 | } |
902 | #ifdef HAVE_HGE |
903 | case TYPE_hge:{ |
904 | hge limit = (*(hge *) bound); |
905 | if (is_hge_nil(limit)) { |
906 | return GDKanalyticalallbounds(r, b, p, preceding); |
907 | } else if (preceding) { |
908 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_HGE(_PRECEDING, limit); |
909 | } else { |
910 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_RANGE_HGE(_FOLLOWING, limit); |
911 | } |
912 | break; |
913 | } |
914 | #endif |
915 | default: |
916 | goto bound_not_supported; |
917 | } |
918 | } |
919 | BATsetcount(r, cnt); |
920 | r->tnonil = (nils == 0); |
921 | r->tnil = (nils > 0); |
922 | return GDK_SUCCEED; |
923 | bound_not_supported: |
924 | GDKerror("GDKanalyticalrangebounds: range frame bound type %s not supported.\n" , ATOMname(tp2)); |
925 | return GDK_FAIL; |
926 | type_not_supported: |
927 | GDKerror("GDKanalyticalrangebounds: type %s not supported for %s frame bound type.\n" , ATOMname(tp1), ATOMname(tp2)); |
928 | return GDK_FAIL; |
929 | calc_overflow: |
930 | GDKerror("22003!overflow in calculation.\n" ); |
931 | return GDK_FAIL; |
932 | } |
933 | |
934 | static gdk_return |
935 | GDKanalyticalgroupsbounds(BAT *r, BAT *b, BAT *p, BAT *l, const void *restrict bound, int tp1, int tp2, bool preceding) |
936 | { |
937 | BUN cnt = BATcount(b), nils = 0; |
938 | lng *restrict rb = (lng *) Tloc(r, 0), i = 0, k = 0, j = 0; |
939 | bit *np = p ? (bit *) Tloc(p, 0) : NULL, *pnp = np, *nend = np; |
940 | BATiter bpi = bat_iterator(b); |
941 | int (*atomcmp) (const void *, const void *) = ATOMcompare(tp1); |
942 | const void *restrict nil = ATOMnilptr(tp1); |
943 | |
944 | if (l) { /* dynamic bounds */ |
945 | switch (tp2) { |
946 | case TYPE_bte:{ |
947 | bte *restrict limit = (bte *) Tloc(l, 0); |
948 | if (preceding) { |
949 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_PRECEDING, limit[k], bte); |
950 | } else { |
951 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_FOLLOWING, limit[k], bte); |
952 | } |
953 | break; |
954 | } |
955 | case TYPE_sht:{ |
956 | sht *restrict limit = (sht *) Tloc(l, 0); |
957 | if (preceding) { |
958 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_PRECEDING, limit[k], sht); |
959 | } else { |
960 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_FOLLOWING, limit[k], sht); |
961 | } |
962 | break; |
963 | } |
964 | case TYPE_int:{ |
965 | int *restrict limit = (int *) Tloc(l, 0); |
966 | if (preceding) { |
967 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_PRECEDING, limit[k], int); |
968 | } else { |
969 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_FOLLOWING, limit[k], int); |
970 | } |
971 | break; |
972 | } |
973 | case TYPE_lng:{ |
974 | lng *restrict limit = (lng *) Tloc(l, 0); |
975 | if (preceding) { |
976 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_PRECEDING, limit[k], lng); |
977 | } else { |
978 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_FOLLOWING, limit[k], lng); |
979 | } |
980 | break; |
981 | } |
982 | #ifdef HAVE_HGE |
983 | case TYPE_hge:{ |
984 | hge *restrict limit = (hge *) Tloc(l, 0); |
985 | if (preceding) { |
986 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_PRECEDING, limit[k], hge); |
987 | } else { |
988 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_FOLLOWING, limit[k], hge); |
989 | } |
990 | break; |
991 | } |
992 | #endif |
993 | default: |
994 | goto bound_not_supported; |
995 | } |
996 | } else { /* static bounds, all the limits are cast to lng */ |
997 | lng limit; |
998 | switch (tp2) { |
999 | case TYPE_bte: |
1000 | limit = is_bte_nil(*(bte *) bound) ? lng_nil : (lng) *(bte *) bound; |
1001 | break; |
1002 | case TYPE_sht: |
1003 | limit = is_sht_nil(*(sht *) bound) ? lng_nil : (lng) *(sht *) bound; |
1004 | break; |
1005 | case TYPE_int: |
1006 | limit = is_int_nil(*(int *) bound) ? lng_nil : (lng) *(int *) bound; |
1007 | break; |
1008 | case TYPE_lng: |
1009 | limit = (lng) (*(lng *) bound); |
1010 | break; |
1011 | #ifdef HAVE_HGE |
1012 | case TYPE_hge: { |
1013 | hge nval = *(hge *) bound; |
1014 | limit = is_hge_nil(nval) ? lng_nil : (nval > (hge) GDK_lng_max) ? GDK_lng_max : (lng) nval; |
1015 | break; |
1016 | } |
1017 | #endif |
1018 | default: |
1019 | goto bound_not_supported; |
1020 | } |
1021 | if (is_lng_nil(limit)) { |
1022 | return GDKanalyticalallbounds(r, b, p, preceding); |
1023 | } else if (preceding) { |
1024 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_PRECEDING, limit, lng); |
1025 | } else { |
1026 | ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_FOLLOWING, limit, lng); |
1027 | } |
1028 | } |
1029 | BATsetcount(r, cnt); |
1030 | r->tnonil = (nils == 0); |
1031 | r->tnil = (nils > 0); |
1032 | return GDK_SUCCEED; |
1033 | bound_not_supported: |
1034 | GDKerror("GDKanalyticalgroupsbounds: groups frame bound type %s not supported.\n" , ATOMname(tp2)); |
1035 | return GDK_FAIL; |
1036 | } |
1037 | |
1038 | gdk_return |
1039 | GDKanalyticalwindowbounds(BAT *r, BAT *b, BAT *p, BAT *l, const void *restrict bound, int tp1, int tp2, int unit, bool preceding, lng first_half) |
1040 | { |
1041 | assert((l && !bound) || (!l && bound)); |
1042 | |
1043 | switch (unit) { |
1044 | case 0: |
1045 | return GDKanalyticalrowbounds(r, b, p, l, bound, tp2, preceding, first_half); |
1046 | case 1: |
1047 | return GDKanalyticalrangebounds(r, b, p, l, bound, tp1, tp2, preceding); |
1048 | case 2: |
1049 | return GDKanalyticalgroupsbounds(r, b, p, l, bound, tp1, tp2, preceding); |
1050 | case 3: |
1051 | return GDKanalyticalallbounds(r, b, p, preceding); |
1052 | default: |
1053 | assert(0); |
1054 | } |
1055 | GDKerror("GDKanalyticalwindowbounds: unit type %d not supported (this is a bug).\n" , unit); |
1056 | return GDK_FAIL; |
1057 | } |
1058 | |