852101a0dbd250a2f36c4aa17e76b4ceda10fc0c
[rrq/rrqmisc.git] / vector / Relation.h
1 #ifndef Relation_H
2 #define Relation_H
3
4 #include <HashVector.h>
5 #include <TupleSchema.h>
6
7 /**
8  * A Relation is an implementation of a tuple set with (optional) key
9  * constraints. The store is a \ref HashVector whose \b type is a \ref
10  * TupleSchema that defines the columns. The key constraints are
11  * represented as additional \ref HashVector "HashVectors" whose \ref
12  * TupleSchema "TupleSchemas" are clones of the column schema with
13  * some columns excluded.
14  *
15  * \extends HashVector
16  */
17 typedef struct {
18     /**
19      * This is the primary content store for the Relation. Its type
20      * should be a TupleSchema declaring the "item types" for the
21      * Relation columns.
22      */
23     HashVector content;
24
25     /**
26      * This is a collection of relational constraints, if any, which
27      * are represented as HashVectors whose TupleSchemas are clones of
28      * the content TupleSchema with some columns excluded.
29      */
30     Vector constraints;
31 } Relation;
32
33 /**
34  * \brief Create a Relation for the given TupleSchema.
35  *
36  * \param schema is the column schema
37  *
38  * \returns the allocated Relation record.
39  *
40  * The given TupleSchema is set up as the type of the content
41  * HashVector, which also is initialised as a Nibble_index_levels
42  * variant Vector.
43  *
44  * \related Relation
45  */
46 extern Relation *Relation_create(TupleSchema *schema);
47
48 /**
49  * \brief Add a key constraint to a \ref Relation.
50  *
51  * \param r is the Relation concerned.
52  *
53  * \param ... are the column flags indicating key (1) or value (0)
54  * column for all columns.
55  *
56  * \returns the index into the constraints \ref Vector for the added
57  * constraint.
58  *
59  * This function adds a \ref HashVector with a \ref TupleSchema as its
60  * item type cloned from the content type and then modified to
61  * represent the constraint. Namely that the key columns have their
62  * "column type" set while value columsn are reset.
63  *
64  * The \b constraint \ref HashVectors are used when \ref tuple
65  * "tuples" are added to the \ref Relation so as to identify the
66  * already contained \ref tuple "tuples" that contradict the addition
67  * by means of having the same constraint key. The already contained
68  * \ref tuple "tuples" are then "knocked out" from the Relation by the
69  * new addition.
70  *
71  * \see Relation_add
72  * \related Relation
73  */
74 extern int Relation_add_constraint(Relation *r,...);
75
76 /**
77  * \brief Add the tuple to the Relation.
78  *
79  * \param r is the \ref Relation concerned.
80  *
81  * \param t is the \ref tuple to add.
82  *
83  * \returns a Vector of all knocked out tuples.
84  *
85  * This function adds the \ref tuple \b t to the \ref Relation \b r,
86  * and it returns a \ref Vector (single_index_level variant) of all
87  * same-key constraint tuples. The returned Vector is malloc-ed and it
88  * must be free-ed by the caller. If the tuple is already contained or
89  * there are no other same-key tuples knocked out, then \b 0 is
90  * returned.
91  *
92  * \related Relation
93  */
94 extern Vector *Relation_add(Relation *r,Tuple *t);
95
96 /**
97  * \brief Delete all tuples matching to the Query \ref tuple fromt the
98  * \ref Relation.
99  *
100  * \param r is the \ref Relation concerned.
101  *
102  * \param t is the \ref tuple to delete.
103  *
104  * \returns a \Vector Vector of all knocked out tuples, i.e. the
105  * same-key tuples, if any, contained in the Relation
106  *
107  * Note that deletion uses a "Query" tuple, which means that some
108  * columns may be null to mark that them match to any value.
109  *
110  * \related Relation
111  */
112 extern Vector *Relation_delete(Relation *r,Tuple *query);
113
114 /**
115  * \brief Return the next \ref tuple in the \ref Relation that matches
116  * to the Query \ref tuple, at or after the index.
117  *
118  * \param r is the \ref Relation concerned.
119  *
120  * \param index is a pointer to the \ref Vector index to update.
121  *
122  * \param Query is a Query \tuple tuple for selection of certain
123  * column values.
124  *
125  * \returns any such matching \tuple tuple and an updateed *index.
126  *
127  * \related Relation
128  */
129 extern void *Relation_next(Relation *r,VectorIndex *index,Tuple *query);
130
131 /**
132  * \brief Lay out a dynamic \ref Relation initializer for a Relation
133  * wth the given column "types".
134  *
135  * This defines a \ref Relation intializer that creates the \ref
136  * TupleSchema for the given columns.
137  *
138  * \note The initializer cannot be used statically.
139  *
140  * The \b content \ref HashVector is a \ref Nibble_index_level variant
141  * with an initial size of 16 slots.
142  *
143  * The constraints \ref Vector is a \ref BitPair_index_level variant
144  * with initial size 0.
145  *
146  * The \b content \ref HashVector \b type is set up with an allocated
147  * \ref TupleSchema that has an allocated \ref tuple that declares the
148  * column "types" view the given \ref ItemKeyFun pointers. Any add
149  * constraints will need to clone that \ref TupleSchema and then clear
150  * the column slots for the constraint value columns, typically by
151  * using \ref TupleSchema_mask for this.
152  *
153  * \related Relation
154  */
155 #define RELATION(...) (Relation) { \
156     .content = { \
157         .table = { .variant = Nibble_index_levels, .size=16, .entries=0 }, \
158         .fill = 0, .holes = 0, \
159         .type = (ItemKeyFun*) TUPLESCHEMA( __VA_ARGS__ )        \
160     }, \
161     .constraints = { .variant = BitPair_index_levels, .size=0, .entries=0 } \
162 }
163
164 #endif