Example #1
0
bool VersionVector::operator<=( const VersionVector& other ) const
{
    // build a set of all keys in both vectors
    set_t   keys;
    keyUnion(keys,other);

    for( auto& key : keys )
    {
        int64_t v1 = (*this)[key];
        int64_t v2 = other[key];
        if( v1 > v2 )
            return false;
    }

    return true;
}
Example #2
0
bool VersionVector::operator<( const VersionVector& other ) const
{
    // build a set of all keys in both vectors
    set_t   keys;
    keyUnion(keys,other);

    bool atLeastOneLess = false;

    for( auto& key : keys )
    {
        int64_t v1 = (*this)[key];
        int64_t v2 = other[key];
        if( v1 > v2 )
            return false;
        else if( v1 < v2 )
            atLeastOneLess = true;
    }

    return atLeastOneLess;
}
Example #3
0
void partitionEntries( IndexEntry *I,   /*  input entry list to partition */
                       Int fan,         /*  fan or order of index         */
                       IndexEntry **A,  /*  1st group partitioned entries */
                       IndexEntry **B ) /*  2nd group partitioned entries */
{   /* beginning of partitionEntries()  */
    IndexEntry *entry1;        /* looping entry to find first entry of groups */
    IndexEntry *entry2;        /* looping entry to find first entry of groups */
    IndexEntry *currentEntry;  /* looping entry for input list                */
    IndexEntry *previousEntry; /* looping entry for input list                */
    IndexEntry *tempA;         /* temp entry to find first entry of group A   */
    IndexEntry *tempB;         /* temp entry to find first entry of group B   */
    IndexKey    unionAB;       /* union of first entries of group A and B     */
    Float       volumeAB;      /* volume of first entries of group A and B    */
    Int         sizeOfGroupA;  /* current size of group A                     */
    Int         sizeOfGroupB;  /* current size of group B                     */

    static Char name[] = "partitionEntries";

    assert( I && I->next );     /*  need at least two entries to partition  */
    assert( MINIMUM_FAN_SIZE > 1 );
    assert( fan >= MINIMUM_FAN_SIZE );

    /*
     *  Find "worst" combination of all entries in I.  The worst combination is 
     *  the one which produces the largest bounding index key, i.e., the 
     *  largest hyper-cube volume.  The two entries which form the worst combo 
     *  will be the first entries into the two groups, A and B.  The method 
     *  used to find the worst combo is straight forward enumeration of all 
     *  possible combinations.  Note that only forward combinations are 
     *  necessary since the volume( union( A, B ) ) is the same as the 
     *  volume( union( B, A ) ).  The first candidate pair for the worst case 
     *  are chosen as the first and second entries of the input list, I.
     */
    *A       = I;
    *B       = I->next;
    keyUnion( &(*A)->key, &(*B)->key, &unionAB );
    volumeAB = volume( unionAB );

    /*
     *  A double loop through the input list, I, is used to find all 
     *  combinations.
     */
    for ( entry1 = I; entry1 != NULL; entry1 = entry1->next ) {
        for ( entry2 = entry1->next; entry2 != NULL; entry2 = entry2->next ) {
            IndexKey    tempKey;
            Float       tempVolume;
            
            /*
             *  If this combination produces a worse penalty, then replace old 
             *  candidates with new pair.
             */
            keyUnion( &entry1->key, &entry2->key, &tempKey );
            tempVolume = volume( tempKey );

            if ( tempVolume > volumeAB ) {
               *A       = entry1;
               *B       = entry2;
               unionAB  = tempKey;
               volumeAB = tempVolume;
            }   /*  end of if ( tempVolume > volumeAB )   */
        }   /*  end of loop for entry2  */
    }   /* end of loop for entry1   */

    /*
     *  The entry pointers, A and B, now point to the first entries of the 
     *  two groups which are forming during the partition. Remove them from the 
     *  input list, I. Set the size of each group to one for the initial 
     *  entries.  The entries of I which correspond to A and B are 
     *  found by comparing pointer values.
     */
    currentEntry  = I;      /*  current entry  (starts at beginning of I)   */
    previousEntry = NULL;   /*  previous entry (NULL for first entry)       */
    while ( currentEntry != NULL ) {
        if ( currentEntry == *A || currentEntry == *B ) {
            /*
             *  Found A or B in list as currentEntry. Remove current entry from 
             *  list, checking for special case where current entry is the head 
             *  of list, i.e., no previous entry.
             */
            if ( previousEntry == NULL ) {
                /*
                 *  No previous pointer means that the current entry is the 
                 *  head of the list.  Removing the entry means updating I and 
                 *  reseting the values for currentEntry and previousEntry.
                 */
                I             = currentEntry->next;
                currentEntry  = I;
                previousEntry = NULL;
            }   /*  end of if ( previousEntry == NULL )    */
            else {
                /*
                 *  Remove current entry by setting previous entry's pointer to 
                 *  skip the current.
                 */
                previousEntry->next = currentEntry->next;
                
                /*
                 *  Setup entries for next loop. Since an entry was removed 
                 *  from the list, the previous entry, previousEntry, does not 
                 *  change.
                 */
                currentEntry = previousEntry->next;
            }   /*  end of else */           
        }   /*  end of if ( currentEntry == A || currentEntry == B )    */
        else {
            /*
             *  Did not find either A or B, so just set up for next loop
             */
            previousEntry = currentEntry;
            currentEntry  = currentEntry->next;
        }   /*  end of else */
    }   /* end of loop for currentEntry   */

    /*
     *  Finish up by fixing the next pointers for both A and B to NULL since 
     *  their the first and only entries in the lists, and setting the size of 
     *  each group to one.
     */
    (*A)->next   = NULL;
    (*B)->next   = NULL;
    sizeOfGroupA = 1;
    sizeOfGroupB = 1;

    /*
     *  The first entries of groups A and B are now assigned and removed from 
     *  the input list, I.  The "volume" for A and B is the "worst" possible 
     *  for all combinations of the entries of I.
     *
     *  Assign all remaining entries of I to each group based on penalty.  The 
     *  current implementation finds the penalty of the entry with the first 
     *  entries into the group, i.e., A or B.  Other methods are possible, 
     *  including using the penalty of the current group rather than the first 
     *  entry into that group.
     */
    tempA = *A;
    tempB = *B;
    while ( I != NULL ) {
        /*
         *  If neither group is full, add according to penalty
         */
        if ( sizeOfGroupA < fan && sizeOfGroupB < fan ) {
            if ( penalty( **A, *I ) < penalty( **B, *I ) ) {
                /*
                 *  Place current entry into group A, incrementing counter
                 */
                tempA->next = I;            /*  add current entry to group A  */
                I           = I->next;      /*  increment current entry       */
                tempA       = tempA->next;  /*  increment group A ptr         */
                tempA->next = NULL;         /*  remove new entry from group I */

                sizeOfGroupA++;
            }   /*  end of if ( penalty( I, A ) < penalty( I, B ) ) */
            else {
                /*
                 *  Place current entry into group B, incrementing counter
                 */
                tempB->next = I;            /*  add current entry to group B  */
                I           = I->next;      /*  increment current entry       */
                tempB       = tempB->next;  /*  increment group B ptr         */
                tempB->next = NULL;         /*  remove new entry from group I */

                sizeOfGroupB++;
            }   /*  end of else */
        }   /*  end of if ( sizeOfGroupA < fan && sizeOfGroupB < fan )  */
        /*
         *  If group A is full and there is room on group B, then add entry to 
         *  group B
         */
        else if ( sizeOfGroupA >= fan && sizeOfGroupB < fan ) {
            /*
             *  Place entry into group B, incrementing counter
             */
            tempB->next = I;            /*  add current entry to group B  */
            I           = I->next;      /*  increment current entry       */
            tempB       = tempB->next;  /*  increment group B ptr         */
            tempB->next = NULL;         /*  remove new entry from group I */
            
            sizeOfGroupB++;
        }   /*  end of if ( sizeOfGroupA >= fan )   */
        /*
         *  If group B is full and there is room on group A, then add entry to 
         *  group A
         */
        else if ( sizeOfGroupB >= fan && sizeOfGroupA < fan ) {
            /*
             *  Place current entry into group A, incrementing counter
             */
            tempA->next = I;            /*  add current entry to group A  */
            I           = I->next;      /*  increment current entry       */
            tempA       = tempA->next;  /*  increment group A ptr         */
            tempA->next = NULL;         /*  remove new entry from group I */

            sizeOfGroupA++;
        }   /*  end of if ( sizeOfGroupB >= fan )   */
        else {
            /*
             *  Special(error) case when both groups are full and no where to 
             *  place entry.  Simply ignore entry and try to continue.
             */
            I = I->next;
            
            errorMessage( "too many entries to partition", REPLACE );
            errorMessage( name, PREPEND );
            
        }
    }   /* end of loop for currentEntry   */
    
    return;
}   /*  end paritionEntries()   */