From: Ralph Ronnquist Date: Wed, 13 Jul 2022 06:05:33 +0000 (+1000) Subject: rework Relation_next and HashVector_next to void query handling in HashVector X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=3d4400773c3361961bcb9f8b6898321f2005a093;p=rrq%2Frrqmisc.git rework Relation_next and HashVector_next to void query handling in HashVector --- diff --git a/vector/HashVector.c b/vector/HashVector.c index dbf1ab2..ec0e0b4 100644 --- a/vector/HashVector.c +++ b/vector/HashVector.c @@ -65,26 +65,17 @@ void *HashVector_find(HashVector *hv,void *key) { // Find any element at or after the index that admits to the key. // Update index and return item. -void *HashVector_next(HashVector *hv,VectorIndex *index,void *key) { - unsigned long i = index? *index : 0; - for ( ; i < hv->table.size; i++ ) { - void **p = Vector_next_used( &hv->table, &i ); +void *HashVector_next(HashVector *hv,VectorIndex *index) { + for ( ; (*index) < hv->table.size; (*index)++ ) { + void **p = Vector_next_used( &hv->table, index ); if ( p == 0 ) { break; } if ( *p && *p != HV_HOLE ) { - if ( key && hv->type->haskey( hv->type, *p, key ) == 0 ) { - continue; - } - if ( index ) { - (*index) = i; - } return *p; } } - if ( index ) { - (*index) = hv->table.size; - } + (*index) = hv->table.size; return 0; } @@ -184,7 +175,7 @@ Vector *HashVector_contents( VectorIndex i; VectorIndex j = 0; for ( i = 0; i < v->size; i++, j++ ) { - Vector_set( v, i, HashVector_next( hv, &j, 0 ) ); + Vector_set( v, i, HashVector_next( hv, &j ) ); } return v; } diff --git a/vector/HashVector.h b/vector/HashVector.h index 387f7ce..b9316d6 100644 --- a/vector/HashVector.h +++ b/vector/HashVector.h @@ -35,7 +35,7 @@ * * \extends Vector */ -typedef struct { +typedef struct HashVector { /** * This is the backing \ref Vector for the HashVector. Items are * placed in the Vector by means of their key hashcodes, at the @@ -86,24 +86,18 @@ typedef struct { void *HashVector_find(HashVector *hv,void *key); /** - * \brief Scan the table for any subsequent item that admits to the - * given partial key. + * \brief Scan the table by index * * \param hv is the \ref HashVector concerned. * * \param index is a pointer to the index to advance. - * \ - * \param key is the query key * * \returns the next matching item, or \b 0 if none, with the index * updated. * - * This function is used where the query key doesn't fully identify an - * item, and is thus a partial key that - * * \related HashVector */ -extern void *HashVector_next(HashVector *hv,VectorIndex *i,void *key); +extern void *HashVector_next(HashVector *hv,VectorIndex *i); /** * \brief Add the given item into the \ref HashVector, growing it as diff --git a/vector/Relation.c b/vector/Relation.c index 4a64170..0f671ab 100644 --- a/vector/Relation.c +++ b/vector/Relation.c @@ -61,10 +61,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 ); } } @@ -109,7 +115,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 ); @@ -139,6 +145,19 @@ Vector *Relation_delete(Relation *r,Tuple *item) { } void *Relation_next(Relation *r,VectorIndex *index,Tuple *query) { - return HashVector_next( &r->content, index, 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; }