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 | |
12 | struct 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 | |
28 | static inline oid |
29 | canditer_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++]) |
53 | static inline oid |
54 | canditer_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 | |
68 | gdk_export BUN canditer_init(struct canditer *ci, BAT *b, BAT *s); |
69 | gdk_export oid canditer_peek(struct canditer *ci); |
70 | gdk_export oid canditer_last(struct canditer *ci); |
71 | gdk_export oid canditer_prev(struct canditer *ci); |
72 | gdk_export oid canditer_peekprev(struct canditer *ci); |
73 | gdk_export oid canditer_idx(struct canditer *ci, BUN p); |
74 | gdk_export void canditer_setidx(struct canditer *ci, BUN p); |
75 | gdk_export void canditer_reset(struct canditer *ci); |
76 | gdk_export BUN canditer_search(struct canditer *ci, oid o, bool next); |
77 | gdk_export BAT *canditer_slice(struct canditer *ci, BUN lo, BUN hi); |
78 | gdk_export BAT *canditer_slice2(struct canditer *ci, BUN lo1, BUN hi1, BUN lo2, BUN hi2); |
79 | gdk_export gdk_return BATnegcands( BAT *cands, BAT *odels); |
80 | |
81 | #endif /* _GDK_CAND_H_ */ |
82 | |