// 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;
}
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;
}
*
* \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
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
// 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 );
}
}
// 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 );
}
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;
}