Beispiel #1
0
virNWFilterVarCombIterPtr
virNWFilterVarCombIterNext(virNWFilterVarCombIterPtr ci)
{
    size_t i;

    for (i = 0; i < ci->nIter; i++) {
next:
        ci->iter[i].curValue++;
        if (ci->iter[i].curValue <= ci->iter[i].maxValue) {
            if (!virNWFilterVarCombIterEntryAreUniqueEntries(
                                              &ci->iter[i], ci->hashTable))
                goto next;
            break;
        } else {
            ci->iter[i].curValue = ci->iter[i].minValue;
        }
    }

    if (ci->nIter == i) {
        virNWFilterVarCombIterFree(ci);
        return NULL;
    }

    return ci;
}
/*
 * Create an iterator over the contents of the given variables. All variables
 * must have entries in the hash table.
 * The iterator that is created processes all given variables in parallel,
 * meaning it will access $ITEM1[0] and $ITEM2[0] then $ITEM1[1] and $ITEM2[1]
 * up to $ITEM1[n] and $ITEM2[n]. For this to work, the cardinality of all
 * processed lists must be the same.
 * The notation $ITEM1 and $ITEM2 (in one rule) therefore will always have to
 * process the items in parallel. This will be an implicit notation for
 * $ITEM1[@0] and $ITEM2[@0] to 'lock' the two together. Future notations of
 * $ITEM1[@1] and $ITEM2[@2] will make them be processed independently,
 * which then would cause all combinations of the items of the two lists to
 * be created.
 */
virNWFilterVarCombIterPtr
virNWFilterVarCombIterCreate(virNWFilterHashTablePtr hash,
                             virNWFilterVarAccessPtr *varAccess,
                             size_t nVarAccess)
{
    virNWFilterVarCombIterPtr res;
    size_t i;
    unsigned int iterId;
    int iterIndex = -1;
    unsigned int nextIntIterId = VIR_NWFILTER_MAX_ITERID + 1;

    if (VIR_ALLOC_VAR(res, virNWFilterVarCombIterEntry, 1 + nVarAccess) < 0)
        return NULL;

    res->hashTable = hash;

    /* create the default iterator to support @0 */
    iterId = 0;

    res->nIter = 1;
    virNWFilterVarCombIterEntryInit(&res->iter[0], iterId);

    for (i = 0; i < nVarAccess; i++) {
        switch (virNWFilterVarAccessGetType(varAccess[i])) {
        case VIR_NWFILTER_VAR_ACCESS_ITERATOR:
            iterId = virNWFilterVarAccessGetIterId(varAccess[i]);
            iterIndex = virNWFilterVarCombIterGetIndexByIterId(res, iterId);
            if (iterIndex < 0) {
                iterIndex = res->nIter;
                virNWFilterVarCombIterEntryInit(&res->iter[iterIndex], iterId);
                res->nIter++;
            }
            break;
        case VIR_NWFILTER_VAR_ACCESS_ELEMENT:
            iterIndex = res->nIter;
            virNWFilterVarAccessSetIntIterId(varAccess[i], nextIntIterId);
            virNWFilterVarCombIterEntryInit(&res->iter[iterIndex],
                                            nextIntIterId);
            nextIntIterId++;
            res->nIter++;
            break;
        case VIR_NWFILTER_VAR_ACCESS_LAST:
            goto err_exit;
        }

        if (virNWFilterVarCombIterAddVariable(&res->iter[iterIndex],
                                              hash, varAccess[i]) < 0)
            goto err_exit;
    }

    return res;

err_exit:
    virNWFilterVarCombIterFree(res);
    return NULL;
}