added convenience callbacks
[rrq/rrqmisc.git] / vector / relation.c
index e7469de74b203b3b56ef8f6d45a2f9329bfa6f91..6777d9a5ae19dc9bdea0587ca9f844a93d80bf76 100644 (file)
@@ -1,3 +1,4 @@
+#include <stdarg.h>
 #include <stdlib.h>
 #include <relation.h>
 
@@ -24,24 +25,25 @@ relation *relation_create(tupleschema *schema) {
 #define COPYA(T,P,N) (T*) memcpy( malloc( N * sizeof(T) ), P, N * sizeof( T ) )
 #define COPY(T,P) COPYA(T,P,1)
 
-// Add an indexing hashvector to the relation using the nominated
-// column indexes being the value part. the key must be a clone of the
-// relation columns but with some columns reset.
-int relation_add_constraint(relation *r,tupleschema *key) {
-    tupleschema *primary = (tupleschema *) r->content.type;
-    if ( primary->arity != key->arity ) {
-       return -1; // no good
-    }
+// Add an indexing hashvector to the relation using the given column
+// flags with 1 indicating key column and 0 indicating value column.
+int relation_add_constraint(relation *r,...) {
+    va_list ap;
+    tupleschema *ts = (tupleschema *) r->content.type;
+    tuple *columns = (tuple*) calloc( ts->arity, sizeof( void* ) );
     int i = 0;
-    for ( ; i < primary->arity; i++ ) {
-       if ( key->columns[i] && primary->columns[i] != key->columns[i] ) {
-           return -1;
+    va_start( ap, r );
+    for ( ; i < ts->arity; i++ ) {
+       if ( va_arg( ap, int ) ) {
+           (*columns)[i] = ts->columns[i];
        }
     }
+    va_end( ap );
+    ts = tupleschema_create( ts->arity, columns );
     i = (int) r->constraints.size;
     vector_append(
        &r->constraints,
-       hashvector_create( nibble_index_levels, &key->base ) );
+       hashvector_create( nibble_index_levels, (itemkeyfun*) ts ) );
     return i;
 }
 
@@ -138,3 +140,4 @@ vector *relation_delete(relation *r,tuple *item) {
 void *relation_next(relation *r,vector_index *index,tuple *query) {
     return hashvector_next( &r->content, index, query );
 }
+