X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=vector%2FRelation.c;h=868a47776f0f495e476618bdc7927a5148d98107;hb=48cdb87442b7b3f1cdde9c1710ed90ec773dce97;hp=0b7450f3b3b0aec251e6c99b707bfef8bcc1222b;hpb=e938f8c45fd191d96da48f65262e4efcfada7805;p=rrq%2Frrqmisc.git diff --git a/vector/Relation.c b/vector/Relation.c index 0b7450f..868a477 100644 --- a/vector/Relation.c +++ b/vector/Relation.c @@ -30,16 +30,16 @@ Relation *Relation_create(TupleSchema *schema) { int Relation_add_constraint(Relation *r,...) { va_list ap; TupleSchema *ts = (TupleSchema *) r->content.type; - tuple *columns = (tuple*) calloc( ts->arity, sizeof( void* ) ); + Tuple *columns = Tuple_clone( ts->columns ); int i = 0; va_start( ap, r ); - for ( ; i < ts->arity; i++ ) { - if ( va_arg( ap, int ) ) { - (*columns)[i] = ts->columns[i]; + for ( ; i < columns->size; i++ ) { + if ( va_arg( ap, int ) == 0 ) { + columns->elements[i] = 0; } } va_end( ap ); - ts = TupleSchema_create( ts->arity, columns ); + ts = TupleSchema_create( columns ); i = (int) r->constraints.size; Vector_append( &r->constraints, @@ -60,10 +60,16 @@ typedef struct { // for ignoring full matches to the key tuple. static int knockout_check(VectorIndex index,void *item,void *data) { Knockout *kod = (Knockout*) data; + void *key = kod->item; + HashVector *hv = (HashVector*) item; + TupleSchema *type = (TupleSchema *)hv->type; VectorIndex i = 0; - for ( ; i < ((HashVector*) item)->table.size; i++ ) { - void *old = HashVector_next( (HashVector*) item, &i, kod->item ); + for ( ; i < hv->table.size; i++ ) { + void *old = HashVector_next( hv, &i ); if ( old ) { + if ( key && type->base.haskey( type, old, key ) == 0 ) { + continue; + } HashVector_add( &kod->knockouts, old ); } } @@ -85,7 +91,7 @@ static int knockout_add(VectorIndex index,void *item,void *data) { // Find and remove all collisions for a Query, unless "add" is // non-zero in which case the function aborts if there is any match in // the main content. -static int knockout_clear(Knockout *this,Relation *r,tuple *item,int add) { +static int knockout_clear(Knockout *this,Relation *r,Tuple *item,int add) { (*this) = (Knockout) { .rel = r, .knockouts = { @@ -108,7 +114,7 @@ static int knockout_clear(Knockout *this,Relation *r,tuple *item,int add) { // Delete them from all tables VectorIndex i; for ( i = 0; i < this->knockouts.table.size; i++ ) { - void *t = HashVector_next( &this->knockouts, &i, 0 ); + void *t = HashVector_next( &this->knockouts, &i ); if ( t ) { HashVector_delete( &r->content, t ); Vector_iterate( &r->constraints, 0, knockout_delete, t ); @@ -120,7 +126,7 @@ static int knockout_clear(Knockout *this,Relation *r,tuple *item,int add) { // add a tuple to a Relation and return a Vector of knocked out // tuples, if any, or 0 otherwise. -Vector *Relation_add(Relation *r,tuple *item) { +Vector *Relation_add(Relation *r,Tuple *item) { Knockout data; if ( knockout_clear( &data, r, item, 1 ) ) { // Add the new tuple @@ -131,13 +137,26 @@ Vector *Relation_add(Relation *r,tuple *item) { return 0; } -Vector *Relation_delete(Relation *r,tuple *item) { +Vector *Relation_delete(Relation *r,Tuple *item) { Knockout data; (void) knockout_clear( &data, r, item, 0 ); return HashVector_contents( &data.knockouts, single_index_level, 0 ); } -void *Relation_next(Relation *r,VectorIndex *index,tuple *Query) { - return HashVector_next( &r->content, index, Query ); +void *Relation_next(Relation *r,VectorIndex *index,Tuple *query) { + HashVector *hv = &r->content; + void *key = query; + TupleSchema *type = (TupleSchema *) hv->type; + for ( ; (*index) < hv->table.size; (*index)++ ) { + void *old = HashVector_next( hv, index ); + if ( old ) { + if ( key && type->base.haskey( type, old, key ) == 0 ) { + continue; + } + return old; + } + } + (*index) = hv->table.size; + return 0; }