4 #define COPYA(T,P,N) (T*) memcpy( malloc( N * sizeof(T) ), P, N * sizeof( T ) )
5 #define COPY(T,P) COPYA(T,P,1)
7 // Add an indexing hashvector to the relation using the nominated
8 // column indexes being the value part. the key must be a clone of the
9 // relation columns but with some columns reset.
10 int relation_addindex(relation *r,tupleschema *key) {
11 tupleschema *primary = r->columns;
12 if ( primary->arity != key->arity ) {
16 for ( ; i < primary->arity; i++ ) {
17 if ( key->columns[i] && primary->columns[i] != key->columns[i] ) {
21 i = (int) r->indexes.size;
22 vector_append( &r->indexes, hashvector_create( 1, (itemkeyfun*) key ) );
26 relation *relation_create(int arity,tupleschema *schema) {
27 relation *r = (relation *) malloc( sizeof( relation ) );
39 // Iteration context for adding or querying a relation
46 // Determine matches to ((knockoutdata*)data)->key in
47 // (hashvector*)item, optionally using ((knockoutdata*)data)->columns
48 // for ignoring full matches to the key tuple.
49 static int knockout_check(vector_index index,void *item,void *data) {
50 knockoutdata *kod = (knockoutdata*) data;
52 if ( hashvector_find( (hashvector*) item, kod->key, &old ) ) {
53 if ( kod->columns == 0 ||
54 kod->columns->haskey( kod->columns, old, kod->key ) == 0 ) {
55 if ( vector_find( &kod->knockouts, old ) >= kod->knockouts.size ) {
56 vector_append( &kod->knockouts, old );
63 // delete the (tuple*)item from the (hashvector*)data
64 static int knockout_delete_item(vector_index index,void *item,void *data) {
65 hashvector_delete( (hashvector*)data, item );
69 // delete the tuples of (vector*)data from the (hashvector*)item
70 static int knockout_delete(vector_index index,void *item,void *data) {
71 vector_iterate( (vector*)data, 0, knockout_delete_item, item );
75 // add the (tuple*)data to the (hashvector*)item
76 static int knockout_add(vector_index index,void *item,void *data) {
77 hashvector_add( (hashvector*)item, data );
81 // add a tuple to a relation and return a vector of knocked out
82 // tuples, if any, or 0 otherwise.
83 vector *relation_add(relation *r,tuple *x) {
85 .columns = &(r->columns->functions),
86 .knockouts = { .variant = 2, .size = 0, .entries = 0 },
90 vector_iterate( &r->indexes, 0, knockout_check, &data );
92 vector_iterate( &r->indexes, 0, knockout_delete, &data.knockouts );
94 vector_iterate( &r->indexes, 0, knockout_add, x );
95 if ( data.knockouts.size == 0 ) {
98 return vector_clone( 3, &data.knockouts );