c2e5293b8141425aeea418f93cf3286b7cbf20c7
[rrq/rrqmisc.git] / vector / relation.h
1 #ifndef relation_H
2 #define relation_H
3
4 #include <hashvector.h>
5 #include <tupleitem.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,vector_index *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