/* 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; }
Bool symbol_has_entry(const Symbol* sym, const Tuple* tuple) { assert(symbol_is_valid(sym)); assert(tuple_is_valid(tuple)); return hash_has_entry(sym->hash, tuple) || (sym->deflt != NULL && set_lookup(sym->set, tuple)); }
/*ARGSUSED*/ static int set_empty_lookup_idx(const Set* set, const Tuple* tuple, int offset) { assert(set_empty_is_valid(set)); assert(tuple_is_valid(tuple)); assert(offset >= 0); return -1; }
void define_set_param( Define* def, Tuple* param) { assert(define_is_valid(def)); assert(tuple_is_valid(param)); def->param = param; }
/*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; }
List* list_new_tuple(const Tuple* tuple) { ListData data; assert(tuple_is_valid(tuple)); data.tuple = tuple_copy(tuple); return list_new(LIST_TUPLE, &data); }
void list_insert_tuple(List* list, const Tuple* tuple) { ListData data; assert(list_is_valid(list)); assert(tuple_is_valid(tuple)); assert(list->type == LIST_TUPLE); data.tuple = tuple_copy(tuple); list_insert_data(list, &data); }
/*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); }
Bool hash_has_entry(const Hash* hash, const Tuple* tuple) { unsigned int hcode = tuple_hash(tuple) % hash->size; HElem* he; assert(hash_is_valid(hash)); assert(tuple_is_valid(tuple)); for(he = hash->bucket[hcode]; he != NULL; he = he->next) if (!entry_cmp(he->value.entry, tuple)) break; return he != NULL; }
/* Liefert NULL wenn nicht gefunden. * Falls ein default zurueckgegeben wird, stimmt "tuple" nicht mit * entry->tuple ueberein. */ const Entry* symbol_lookup_entry(const Symbol* sym, const Tuple* tuple) { const Entry* entry; assert(symbol_is_valid(sym)); assert(tuple_is_valid(tuple)); entry = hash_lookup_entry(sym->hash, tuple); if (NULL == entry && sym->deflt != NULL && set_lookup(sym->set, tuple)) entry = sym->deflt; return entry; }
void hash_add_tuple(Hash* hash, const Tuple* tuple) { HElem* he = blk_alloc(sizeof(*he)); unsigned int hcode; assert(hash_is_valid(hash)); assert(tuple_is_valid(tuple)); assert(hash->type == HASH_TUPLE); assert(he != NULL); hcode = tuple_hash(tuple) % hash->size; he->value.tuple = tuple; he->next = hash->bucket[hcode]; hash->bucket[hcode] = he; hash->elems++; }
/*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); }
/*ARGSUSED*/ static SetIter* iter_init( const Set* set, const Tuple* pattern, int offset) { SetIter* iter; assert(set_empty_is_valid(set)); assert(pattern == NULL || tuple_is_valid(pattern)); assert(offset == 0); iter = calloc(1, sizeof(*iter)); assert(iter != NULL); SID_set2(iter->empty, SET_EMPTY_ITER_SID); assert(set_empty_iter_is_valid(iter)); return iter; }
/* ------------------------------------------------------------------------- * --- 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); }