portability fixes
[rrq/rrqmisc.git] / vector / View.c
1 #include <stdlib.h>
2 #include <View.h>
3 #include <HashVector.h>
4 #include <QueryCallbacks.h>
5 #include <Query.h>
6 #include <stringitem.h>
7
8 /**
9  * A View is a "virtual relation" that captures the differences at
10  * successive evaluations in the binding sequences offered by a query.
11  */
12 typedef struct {
13     struct QueryCallbacks *def;
14     /**
15      * This is the source query to be a view of.
16      */
17     Query *source;
18     /**
19      * This is the size of the names tuple.
20      */
21     int arity;
22     /**
23      * This is the binding names to track.
24      */
25     Tuple *names;
26     /**
27      * This is the collection of bindings for the tracked names being
28      * gained at the latest evaluation.
29      */
30     Vector gained;
31     /**
32      * This is the collection of bindings for the tracked names being
33      * last at the latest evaluation.
34      */
35     HashVector lost;
36 } View;
37
38 static Tuple *View_type_Tuple(HashVector *hv) {
39     Tuple *t = Tuple_calloc( hv->fill );
40     VectorIndex index = 0;
41     for ( ; index < hv->table.size; index++ ) {
42         t->elements[ index ] = HashVector_next( hv, &index );
43     }
44     return t;
45 }
46
47 static void View_reclaim(Query *this) {
48     View *v = (View*) this;
49     TupleSchema *ts = (TupleSchema*) gained->type;
50     Vector_resize( &v->gained, 0, Vector_clear_any, 0 );
51     Vector_resize( &v->lost, 0, Vector_clear_any, 0 );
52     free( ts->columns );
53     free( ts );
54     free( this );
55 }
56
57 static QueryCallbacks View_def = {
58     .reclaim = View_reclaim,
59     .next = 0,
60     .variables = 0
61 };
62
63 Query *View_create(Query *q) {
64     View *vq = (View*) malloc( sizeof( View ) );
65     HashVector hv = (HashVector) {
66         .table = (Vector) {
67             .variant = Nibble_index_levels, .size = 16, .entries = 0
68         },
69         .fill = 0, .holes = 0, .type = &stringitem
70     };
71     q->def->variables( q, &hv ); // Obtain query variables
72     
73     TupleSchema *ts = TupleSchema_create( hv.fill, View_type_Tuple( &hv ) );
74     (*vq) = (View) {
75         .def = &View_def,
76         .source = q,
77         .arity = 0,
78         .gained = (HashVector) {
79             .table = (Vector) {
80                 .variant = Nibble_index_levels,
81                 .size = 16,
82                 .entries = 0
83             },
84             .fill = 0, .holes = 0, .type = (ItemKeyFun*) ts
85         },
86         .lost = (HashVector) {
87             .table = (Vector) {
88                 .variant = Nibble_index_levels,
89                 .size = 16,
90                 .entries = 0
91             },
92             .fill = 0, .holes = 0, .type = (ItemKeyFun*) ts
93         }
94     };
95     Vector_resize( &hv, 0, Vector_clear_any, 0 );
96     return (Query*) vq;
97 }