rework Relation_next and HashVector_next to void query handling in HashVector
authorRalph Ronnquist <ralph.ronnquist@gmail.com>
Wed, 13 Jul 2022 06:05:33 +0000 (16:05 +1000)
committerRalph Ronnquist <ralph.ronnquist@gmail.com>
Wed, 13 Jul 2022 06:05:33 +0000 (16:05 +1000)
vector/HashVector.c
vector/HashVector.h
vector/Relation.c

index dbf1ab2ee3c6cbeaa17cefff205483e4ebaf1059..ec0e0b41a38e18aed3b4e7f48de3180a66fc4810 100644 (file)
@@ -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;
 }
index 387f7ce53cbe3782fee880af84e5f6c0af71a238..b9316d688aedc1d42b9d3d099313c14f9a2ebd9e 100644 (file)
@@ -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
index 4a6417053c73bff4f223f00064f2c839b2d8504d..0f671abce2d09c475f8092e22ff760825211250c 100644 (file)
@@ -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;
 }