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; }