#define QueryCallbacks_H
typedef struct HashVector HashVector;
+typedef struct Query Query;
+typedef struct BindingTable BindingTable;;
enum NextState {
/**
* A struct Query_callbacks record defines the callbacks for a
* specific Query type.
*/
-struct QueryCallbacks {
+typedef struct QueryCallbacks {
/**
* \brief Callback function to reclaim the Query memory for a
* given Query.
* hashvector.
*/
void (*variables)(Query *this,HashVector *hv);
-};
+} QueryCallbacks;
#endif
--- /dev/null
+#include <stdlib.h>
+#include <View.h>
+#include <HashVector.h>
+#include <QueryCallbacks.h>
+#include <Query.h>
+#include <stringitem.h>
+
+/**
+ * A View is a "virtual relation" that captures the differences at
+ * successive evaluations in the binding sequences offered by a query.
+ */
+typedef struct {
+ struct QueryCallbacks *def;
+ /**
+ * This is the source query to be a view of.
+ */
+ Query *source;
+ /**
+ * This is the size of the names tuple.
+ */
+ int arity;
+ /**
+ * This is the binding names to track.
+ */
+ Tuple *names;
+ /**
+ * This is the collection of bindings for the tracked names being
+ * gained at the latest evaluation.
+ */
+ HashVector gained;
+ /**
+ * This is the collection of bindings for the tracked names being
+ * last at the latest evaluation.
+ */
+ HashVector lost;
+} View;
+
+static Tuple *View_type_Tuple(HashVector *hv) {
+ Tuple *t = Tuple_calloc( hv->fill );
+ VectorIndex index = 0;
+ for ( ; index < hv->table.size; index++ ) {
+ t->elements[ index ] = &stringitem;
+ }
+ return t;
+}
+
+static QueryCallbacks View_def = {
+ .reclaim = 0,
+ .next = 0,
+ .variables = 0
+};
+
+Query *View_create(Query *q) {
+ View *vq = (View*) malloc( sizeof( View ) );
+ HashVector hv = (HashVector) {
+ .table = (Vector) {
+ .variant = Nibble_index_levels, .size = 16, .entries = 0
+ },
+ .fill = 0, .holes = 0, .type = &stringitem
+ };
+ q->def->variables( q, &hv ); // Obtain query variables
+
+ TupleSchema *ts = TupleSchema_create( hv.fill, View_type_Tuple( &hv ) );
+ (*vq) = (View) {
+ .def = &View_def,
+ .source = q,
+ .arity = 0,
+ .gained = (HashVector) {
+ .table = (Vector) {
+ .variant = Nibble_index_levels,
+ .size = 16,
+ .entries = 0
+ },
+ .fill = 0, .holes = 0, .type = (ItemKeyFun*) ts
+ },
+ .lost = (HashVector) {
+ .table = (Vector) {
+ .variant = Nibble_index_levels,
+ .size = 16,
+ .entries = 0
+ },
+ .fill = 0, .holes = 0, .type = (ItemKeyFun*) ts
+ }
+ };
+ return (Query*) vq;
+}