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#ifndef _GDK_CAND_H_
10#define _GDK_CAND_H_
11
12struct canditer {
13 const oid *oids; /* candidate or exceptions for non-dense */
14 BAT *s; /* candidate BAT the iterator is based on */
15 oid seq; /* first candidate */
16 oid add; /* value to add because of exceptions seen */
17 BUN noids; /* number of values in .oids */
18 BUN ncand; /* number of candidates */
19 BUN next; /* next BUN to return value for */
20 BUN offset; /* how much of candidate list BAT we skipped */
21 enum {
22 cand_dense, /* simple dense BAT, i.e. no look ups */
23 cand_materialized, /* simple materialized OID list */
24 cand_except, /* list of exceptions in vheap */
25 } tpe;
26};
27
28static inline oid
29canditer_next(struct canditer *ci)
30{
31 if (ci->next == ci->ncand)
32 return oid_nil;
33 switch (ci->tpe) {
34 case cand_dense:
35 return ci->seq + ci->next++;
36 case cand_materialized:
37 assert(ci->next < ci->noids);
38 return ci->oids[ci->next++];
39 case cand_except:
40 /* work around compiler error: control reaches end of
41 * non-void function */
42 break;
43 }
44 oid o = ci->seq + ci->add + ci->next++;
45 while (ci->add < ci->noids && o == ci->oids[ci->add]) {
46 ci->add++;
47 o++;
48 }
49 return o;
50}
51#define canditer_next_dense(ci) ((ci)->next == (ci)->ncand ? oid_nil : (ci)->seq + (ci)->next++)
52#define canditer_next_mater(ci) ((ci)->next == (ci)->ncand ? oid_nil : (ci)->oids[(ci)->next++])
53static inline oid
54canditer_next_except(struct canditer *ci)
55{
56 if (ci->next == ci->ncand)
57 return oid_nil;
58 oid o = ci->seq + ci->add + ci->next++;
59 while (ci->add < ci->noids && o == ci->oids[ci->add]) {
60 ci->add++;
61 o++;
62 }
63 return o;
64}
65#define canditer_search_dense(ci, o, next) ((o) < (ci)->seq ? next ? 0 : BUN_NONE : (o) >= (ci)->seq + (ci)->ncand ? next ? (ci)->ncand : BUN_NONE : (o) - (ci)->seq)
66
67
68gdk_export BUN canditer_init(struct canditer *ci, BAT *b, BAT *s);
69gdk_export oid canditer_peek(struct canditer *ci);
70gdk_export oid canditer_last(struct canditer *ci);
71gdk_export oid canditer_prev(struct canditer *ci);
72gdk_export oid canditer_peekprev(struct canditer *ci);
73gdk_export oid canditer_idx(struct canditer *ci, BUN p);
74gdk_export void canditer_setidx(struct canditer *ci, BUN p);
75gdk_export void canditer_reset(struct canditer *ci);
76gdk_export BUN canditer_search(struct canditer *ci, oid o, bool next);
77gdk_export BAT *canditer_slice(struct canditer *ci, BUN lo, BUN hi);
78gdk_export BAT *canditer_slice2(struct canditer *ci, BUN lo1, BUN hi1, BUN lo2, BUN hi2);
79gdk_export gdk_return BATnegcands( BAT *cands, BAT *odels);
80
81#endif /* _GDK_CAND_H_ */
82