void print_alternating() /* dumps the alternating automaton */ { int i; ATrans *t; fprintf(tl_out, "init :\n"); for(t = transition[0]; t; t = t->nxt) { print_set(t->to, 0); fprintf(tl_out, "\n"); } for(i = node_id - 1; i > 0; i--) { if(!label[i]) continue; fprintf(tl_out, "state %i : ", i); dump(label[i]); fprintf(tl_out, "\n"); for(t = transition[i]; t; t = t->nxt) { if (empty_set(t->pos, 1) && empty_set(t->neg, 1)) fprintf(tl_out, "1"); print_set(t->pos, 1); if (!empty_set(t->pos,1) && !empty_set(t->neg,1)) fprintf(tl_out, " & "); print_set(t->neg, 2); fprintf(tl_out, " -> "); print_set(t->to, 0); fprintf(tl_out, "\n"); } } }
/** * Stores the value in the x_table. Assumes it's not already there. */ static X_table_connector * x_table_store(int lw, int rw, Connector *le, Connector *re, unsigned int null_count, Parse_info pi) { X_table_connector *t, *n; unsigned int h; n = (X_table_connector *) xalloc(sizeof(X_table_connector)); n->set = empty_set(); n->lw = lw; n->rw = rw; n->le = le; n->re = re; n->null_count = null_count; h = pair_hash(pi->log2_x_table_size, lw, rw, le, re, null_count); t = pi->x_table[h]; n->next = t; pi->x_table[h] = n; return n; }
empty_set empty_set::operator^(empty_set const &) { return empty_set(); }
empty_set empty_set::operator-(U const &s) { return empty_set(); }
int MMKVImpl::GenericSInterDiffUnion(DBID db, int op, const DataArray& keys, const Data* dest, const StringArrayResult* res) { StdObjectSet results[2]; int result_index = 0; StringSetArray sets; sets.resize(keys.size()); int err = 0; size_t start_index = 0; StringSet* destset = NULL; StdObjectSet* result = NULL; StdObjectSet* cmp = NULL; int current_result_index = 0; ObjectAllocator allocator = m_segment.MSpaceAllocator<Object>(); StringSet empty_set(std::less<Object>(), allocator); for (size_t i = 0; i < keys.size(); i++) { StringSet* set = GetObject<StringSet>(db, keys[i], V_TYPE_SET, false, err)(); if (IS_NOT_EXISTS(err)) { sets[i] = &empty_set; continue; } if (0 != err) { return err; } sets[i] = set; } if (NULL != dest) { ObjectAllocator allocator = m_segment.MSpaceAllocator<Object>(); destset = GetObject<StringSet>(db, *dest, V_TYPE_SET, true, err)(std::less<Object>(), allocator); if (0 != err) { return err; } } if (NULL == sets[0]) { if (op == OP_DIFF || op == OP_INTER) { result_index = 0; goto _end; } } for (size_t i = 0; i < keys.size(); i++) { if (sets[i] != NULL) { start_index = i; break; } } for (size_t i = start_index + 1; i < keys.size(); i++) { result = results + current_result_index; if (sets[i]->empty()) { if (op == OP_INTER) { results->clear(); result_index = 0; goto _end; } } result->clear(); switch (op) { case OP_DIFF: { if (cmp == NULL) { std::set_difference(sets[start_index]->begin(), sets[start_index]->end(), sets[i]->begin(), sets[i]->end(), std::inserter(*result, result->end()), std::less<Object>()); } else { std::set_difference(cmp->begin(), cmp->end(), sets[i]->begin(), sets[i]->end(), std::inserter(*result, result->end()), std::less<Object>()); } if (result->empty()) { result_index = current_result_index; goto _end; } break; } case OP_INTER: { if (cmp == NULL) { std::set_intersection(sets[start_index]->begin(), sets[start_index]->end(), sets[i]->begin(), sets[i]->end(), std::inserter(*result, result->end()), std::less<Object>()); } else { std::set_intersection(cmp->begin(), cmp->end(), sets[i]->begin(), sets[i]->end(), std::inserter(*result, result->end()), std::less<Object>()); } if (result->empty()) { result_index = current_result_index; goto _end; } break; } case OP_UNION: { if (cmp == NULL) { std::set_union(sets[start_index]->begin(), sets[start_index]->end(), sets[i]->begin(), sets[i]->end(), std::inserter(*result, result->end()), std::less<Object>()); } else { std::set_union(cmp->begin(), cmp->end(), sets[i]->begin(), sets[i]->end(), std::inserter(*result, result->end()), std::less<Object>()); } break; } } current_result_index = 1 - current_result_index; cmp = result; } result_index = result == results ? 0 : 1; _end: if (NULL != res) { StdObjectSet::iterator it = results[result_index].begin(); while (it != results[result_index].end()) { it->ToString(res->Get()); it++; } } if (NULL != destset) { //remove elements not in dest set StringSet::iterator it = destset->begin(); while (it != destset->end()) { Object element = *it; StdObjectSet::iterator cit = results[result_index].find(element); if (cit != results[result_index].end()) //remove elements from results which already in dest set { results[result_index].erase(cit); it++; } else { it = destset->erase(it); DestroyObjectContent(element); } } //insert rest elements StdObjectSet::iterator cit = results[result_index].begin(); while (cit != results[result_index].end()) { Object clone = CloneStrObject(*cit); destset->insert(clone); cit++; } return destset->size(); } return 0; }
Parse_set * parse_set(Disjunct *ld, Disjunct *rd, int lw, int rw, Connector *le, Connector *re, int cost, Parse_info * pi) { /* returns NULL if there are no ways to parse, or returns a pointer to a set structure representing all the ways to parse */ Disjunct * d, * dis; int start_word, end_word, w; int lcost, rcost, Lmatch, Rmatch; int i, j; Parse_set *ls[4], *rs[4], *lset, *rset; Parse_choice * a_choice; Match_node * m, *m1; X_table_connector *xt; int count; assert(cost >= 0, "parse_set() called with cost < 0."); count = table_lookup(lw, rw, le, re, cost); /* assert(count >= 0, "parse_set() called on params that were not in the table."); Actually, we can't assert this, because of the pseudocount technique that's used in count(). It's not the case that every call to parse_set() has already been put into the table. */ if ((count == 0) || (count == -1)) return NULL; xt = x_table_pointer(lw, rw, le, re, cost, pi); if (xt == NULL) { xt = x_table_store(lw, rw, le, re, cost, empty_set(), pi); /* start it out with the empty set of options */ /* this entry must be updated before we return */ } else { return xt->set; /* we've already computed it */ } xt->set->count = count; /* the count we already computed */ /* this count is non-zero */ if (rw == 1+lw) return xt->set; if ((le == NULL) && (re == NULL)) { if (!islands_ok && (lw != -1)) { return xt->set; } if (cost == 0) { return xt->set; } else { w = lw+1; for (dis = local_sent[w].d; dis != NULL; dis = dis->next) { if (dis->left == NULL) { rs[0] = parse_set(dis, NULL, w, rw, dis->right, NULL, cost-1, pi); if (rs[0] == NULL) continue; a_choice = make_choice(dummy_set(), lw, w, NULL, NULL, rs[0], w, rw, NULL, NULL, NULL, NULL, NULL); put_choice_in_set(xt->set, a_choice); } } rs[0] = parse_set(NULL, NULL, w, rw, NULL, NULL, cost-1, pi); if (rs[0] != NULL) { a_choice = make_choice(dummy_set(), lw, w, NULL, NULL, rs[0], w, rw, NULL, NULL, NULL, NULL, NULL); put_choice_in_set(xt->set, a_choice); } return xt->set; } } if (le == NULL) { start_word = lw+1; } else { start_word = le->word; } if (re == NULL) { end_word = rw-1; } else { end_word = re->word; } for (w=start_word; w <= end_word; w++) { m1 = m = form_match_list(w, le, lw, re, rw); for (; m!=NULL; m=m->next) { d = m->d; for (lcost = 0; lcost <= cost; lcost++) { rcost = cost-lcost; /* now lcost and rcost are the costs we're assigning to those parts respectively */ /* Now, we determine if (based on table only) we can see that the current range is not parsable. */ Lmatch = (le != NULL) && (d->left != NULL) && match(le, d->left, lw, w); Rmatch = (d->right != NULL) && (re != NULL) && match(d->right, re, w, rw); for (i=0; i<4; i++) {ls[i] = rs[i] = NULL;} if (Lmatch) { ls[0] = parse_set(ld, d, lw, w, le->next, d->left->next, lcost, pi); if (le->multi) ls[1] = parse_set(ld, d, lw, w, le, d->left->next, lcost, pi); if (d->left->multi) ls[2] = parse_set(ld, d, lw, w, le->next, d->left, lcost, pi); if (le->multi && d->left->multi) ls[3] = parse_set(ld, d, lw, w, le, d->left, lcost, pi); } if (Rmatch) { rs[0] = parse_set(d, rd, w, rw, d->right->next, re->next, rcost, pi); if (d->right->multi) rs[1] = parse_set(d, rd, w,rw,d->right,re->next, rcost, pi); if (re->multi) rs[2] = parse_set(d, rd, w, rw, d->right->next, re, rcost, pi); if (d->right->multi && re->multi) rs[3] = parse_set(d, rd, w, rw, d->right, re, rcost, pi); } for (i=0; i<4; i++) { /* this ordering is probably not consistent with that needed to use list_links */ if (ls[i] == NULL) continue; for (j=0; j<4; j++) { if (rs[j] == NULL) continue; a_choice = make_choice(ls[i], lw, w, le, d->left, rs[j], w, rw, d->right, re, ld, d, rd); put_choice_in_set(xt->set, a_choice); } } if (ls[0] != NULL || ls[1] != NULL || ls[2] != NULL || ls[3] != NULL) { /* evaluate using the left match, but not the right */ rset = parse_set(d, rd, w, rw, d->right, re, rcost, pi); if (rset != NULL) { for (i=0; i<4; i++) { if (ls[i] == NULL) continue; /* this ordering is probably not consistent with that needed to use list_links */ a_choice = make_choice(ls[i], lw, w, le, d->left, rset, w, rw, NULL /* d->right */, re, /* the NULL indicates no link*/ ld, d, rd); put_choice_in_set(xt->set, a_choice); } } } if ((le == NULL) && (rs[0] != NULL || rs[1] != NULL || rs[2] != NULL || rs[3] != NULL)) { /* evaluate using the right match, but not the left */ lset = parse_set(ld, d, lw, w, le, d->left, lcost, pi); if (lset != NULL) { for (i=0; i<4; i++) { if (rs[i] == NULL) continue; /* this ordering is probably not consistent with that needed to use list_links */ a_choice = make_choice(lset, lw, w, NULL /* le */, d->left, /* NULL indicates no link */ rs[i], w, rw, d->right, re, ld, d, rd); put_choice_in_set(xt->set, a_choice); } } } } } put_match_list(m1); } xt->set->current = xt->set->first; return xt->set; }