/* FALSE means, there is no further element */ static Bool set_range_iter_next( SetIter* iter, const Set* set, Tuple* tuple, int offset) { int val; Numb* numb; assert(set_range_iter_is_valid(iter)); assert(set_range_is_valid(set)); assert(tuple_is_valid(tuple)); assert(offset >= 0); assert(offset < tuple_get_dim(tuple)); if (iter->range.now > iter->range.last) return FALSE; val = idx_to_val(set->range.begin, set->range.step, iter->range.now); numb = numb_new_integer(val); tuple_set_elem(tuple, offset, elem_new_numb(numb)); numb_free(numb); iter->range.now++; return TRUE; }
/* Initialise Iterator. Write into iter */ static SetIter* set_prod_iter_init( const Set* set, const Tuple* pattern, int offset) { SetIter* iter; assert(set_prod_is_valid(set)); assert(pattern == NULL || tuple_is_valid(pattern)); assert(offset >= 0); assert(pattern == NULL || offset < tuple_get_dim(pattern)); iter = calloc(1, sizeof(*iter)); assert(iter != NULL); iter->prod.elem = calloc(set->head.dim, sizeof(*iter->prod.elem)); assert(iter->prod.elem != NULL); iter->prod.first = TRUE; iter->prod.iter_a = set_iter_init_intern(set->prod.set_a, pattern, offset); iter->prod.iter_b = set_iter_init_intern(set->prod.set_b, pattern, offset + set->prod.set_a->head.dim); SID_set2(iter->prod, SET_PROD_ITER_SID); assert(set_prod_iter_is_valid(iter)); return iter; }
/* Initialise Iterator. Write into iter */ static SetIter* set_range_iter_init( const Set* set, const Tuple* pattern, int offset) { const Elem* elem; SetIter* iter; assert(set_range_is_valid(set)); assert(pattern == NULL || tuple_is_valid(pattern)); assert(offset >= 0); assert(pattern == NULL || offset < tuple_get_dim(pattern)); iter = calloc(1, sizeof(*iter)); assert(iter != NULL); if (pattern == NULL) { iter->range.first = 0; iter->range.last = val_to_idx(set->range.begin, set->range.step, set->range.end); } else { elem = tuple_get_elem(pattern, offset); switch(elem_get_type(elem)) { case ELEM_NAME : iter->range.first = 0; iter->range.last = val_to_idx(set->range.begin, set->range.step, set->range.end); break; case ELEM_NUMB : iter->range.first = set_range_lookup_idx(set, pattern, offset); if (iter->range.first >= 0) iter->range.last = iter->range.first; else { iter->range.first = 1; iter->range.last = 0; } break; case ELEM_STRG : /* This should not happen. Probably a set with mixed * numbers and string was generated. */ default : abort(); } } iter->range.now = iter->range.first; SID_set2(iter->range, SET_RANGE_ITER_SID); assert(set_range_iter_is_valid(iter)); return iter; }
/*ARGSUSED*/ static int set_pseudo_lookup_idx(const Set* set, const Tuple* tuple, int offset) { assert(set_pseudo_is_valid(set)); assert(tuple_is_valid(tuple)); assert(offset == 0); assert(tuple_get_dim(tuple) == 0); return 0; }
/*ARGSUSED*/ static void set_pseudo_get_tuple( const Set* set, int idx, Tuple* tuple, int offset) { assert(set_pseudo_is_valid(set)); assert(idx == 0); assert(tuple_is_valid(tuple)); assert(offset == 0); assert(tuple_get_dim(tuple) == 0); }
/*ARGSUSED*/ static void set_empty_get_tuple( const Set* set, int idx, Tuple* tuple, int offset) { assert(set_empty_is_valid(set)); assert(idx >= 0); assert(idx <= set->head.members); assert(tuple_is_valid(tuple)); assert(offset >= 0); assert(offset + set->head.dim <= tuple_get_dim(tuple)); fprintf(stderr, "internal_error: set_empty_get_tuple called\n"); abort(); }
static int set_range_lookup_idx(const Set* set, const Tuple* tuple, int offset) { const Elem* elem; const Numb* numb; int val; assert(set_range_is_valid(set)); assert(tuple_is_valid(tuple)); assert(offset >= 0); assert(offset < tuple_get_dim(tuple)); elem = tuple_get_elem(tuple, offset); /* If this fails, this means we have a set with mixed number * and integer types. */ assert(elem_get_type(elem) == ELEM_NUMB); numb = elem_get_numb(elem); assert(numb_is_int(numb)); val = numb_toint(numb); if (set->range.step > 0) { if ( val < set->range.begin || val > set->range.end || ((val - set->range.begin) % set->range.step) != 0) return -1; } else { assert(set->range.step < 0); if ( val > set->range.begin || val < set->range.end || ((set->range.begin - val) % set->range.step) != 0) return -1; } return val_to_idx(set->range.begin, set->range.step, val); }
/* ------------------------------------------------------------------------- * --- get_tuple * ------------------------------------------------------------------------- */ static void set_range_get_tuple( const Set* set, int idx, Tuple* tuple, int offset) { int val; Numb* numb; assert(set_range_is_valid(set)); assert(idx >= 0); assert(idx <= set->head.members); assert(tuple_is_valid(tuple)); assert(offset >= 0); assert(offset < tuple_get_dim(tuple)); val = idx_to_val(set->range.begin, set->range.step, idx); numb = numb_new_integer(val); tuple_set_elem(tuple, offset, elem_new_numb(numb)); numb_free(numb); }
/* ------------------------------------------------------------------------- * --- get_tuple * ------------------------------------------------------------------------- */ static void set_prod_get_tuple( const Set* set, int idx, Tuple* tuple, int offset) { const Set* a; const Set* b; int offset2; assert(set_prod_is_valid(set)); assert(idx >= 0); assert(idx <= set->head.members); assert(tuple_is_valid(tuple)); assert(offset >= 0); assert(offset + set->head.dim <= tuple_get_dim(tuple)); a = set->prod.set_a; b = set->prod.set_b; offset2 = offset + a->head.dim; set_get_tuple_intern(a, idx / b->head.members, tuple, offset); set_get_tuple_intern(b, idx % b->head.members, tuple, offset2); }
/* Return index number of element. -1 if not present */ static int set_prod_lookup_idx(const Set* set, const Tuple* tuple, int offset) { int idx_a; int idx_b; assert(set_prod_is_valid(set)); assert(tuple_is_valid(tuple)); assert(offset >= 0); assert(offset < tuple_get_dim(tuple)); idx_a = set_lookup_idx(set->prod.set_a, tuple, offset); if (idx_a < 0) return -1; offset += set->prod.set_a->head.dim; idx_b = set_lookup_idx(set->prod.set_b, tuple, offset); if (idx_b < 0) return -1; return idx_a * set->prod.set_b->head.members + idx_b; }
/*ARGSUSED*/ static SetIter* iter_init( const Set* set, const Tuple* pattern, int offset) { SetIter* iter; assert(set_pseudo_is_valid(set)); assert(pattern == NULL || tuple_is_valid(pattern)); assert(pattern == NULL || tuple_get_dim(pattern) == 0); assert(offset == 0); iter = calloc(1, sizeof(*iter)); assert(iter != NULL); iter->pseudo.first = TRUE; SID_set2(iter->pseudo, SET_PSEUDO_ITER_SID); assert(set_pseudo_iter_is_valid(iter)); return iter; }
/*ARGSUSED*/ static Bool set_prod_iter_next( SetIter* iter, const Set* set, Tuple* tuple, int offset) { Set* a; Set* b; SetIter* iter_a; SetIter* iter_b; int offset2; int i; assert(set_prod_iter_is_valid(iter)); assert(set_prod_is_valid(set)); assert(tuple_is_valid(tuple)); assert(offset >= 0); assert(offset + set->head.dim <= tuple_get_dim(tuple)); a = set->prod.set_a; b = set->prod.set_b; iter_a = iter->prod.iter_a; iter_b = iter->prod.iter_b; offset2 = offset + a->head.dim; if (iter->prod.first) { iter->prod.first = FALSE; return get_both_parts(a, b, iter, iter_a, iter_b, tuple, offset, offset2); } assert(!iter->prod.first); /* Get back part */ if (set_iter_next_intern(iter_b, b, tuple, offset2)) { /* copy fore part */ for(i = 0; i < a->head.dim; i++) tuple_set_elem(tuple, i + offset, elem_copy(iter->prod.elem[i])); return TRUE; } /* No back part, so reset it */ set_iter_reset_intern(iter_b, b); /* Clear elem cache */ for(i = 0; i < set->head.dim; i++) { if (iter->prod.elem[i] != NULL) { elem_free(iter->prod.elem[i]); iter->prod.elem[i] = NULL; } } return get_both_parts(a, b, iter, iter_a, iter_b, tuple, offset, offset2); }