rpc_state* handle_msg_accept(const msg_accept_t *msg_accp) { SAFE_ASSERT(msg_accp->h->t == MPAXOS__MSG_HEADER__MSGTYPE_T__ACCEPT); // This is the msg_accepted for response msg_accepted_t msg_accd = MPAXOS__MSG_ACCEPTED__INIT; msg_header_t msg_header = MPAXOS__MSG_HEADER__INIT; msg_accd.h = &msg_header; msg_accd.h->t = MPAXOS__MSG_HEADER__MSGTYPE_T__ACCEPTED; msg_accd.h->tid = msg_accp->h->tid; msg_accd.h->nid = get_local_nid(); msg_accd.n_ress = 0; msg_accd.ress = (response_t **) malloc(msg_accp->prop->n_rids * sizeof(response_t *)); for (int i = 0; i < msg_accp->prop->n_rids; i++) { roundid_t *rid = msg_accp->prop->rids[i]; if (!is_in_group(rid->gid)) { continue; } // For those I belong to, add resoponse. response_t *response = (response_t *) malloc(sizeof(response_t)); msg_accd.ress[msg_accd.n_ress] = response; mpaxos__response_t__init(response); response->rid = rid; accp_info_t *ainfo = get_accp_info(rid->gid, rid->sid); SAFE_ASSERT(ainfo != NULL); apr_thread_mutex_lock(ainfo->mx); // Check if the ballot id is larger. ballotid_t maxbid = ainfo->bid_max; if (rid->bid >= maxbid) { response->ack = MPAXOS__ACK_ENUM__SUCCESS; record_accepted(rid, msg_accp->prop); proposal_t **p = apr_array_push(ainfo->arr_prop); // *p = apr_pcalloc(ainfo->mp, sizeof(proposal_t)); // prop_cpy(*p, msg_accp->prop, ainfo->mp); *p = prop_copy(msg_accp->prop); } else if (rid->bid < maxbid) { response->ack = MPAXOS__ACK_ENUM__ERR_BID; } else { SAFE_ASSERT(0); } //FIXME whether or not to add proposals in the message. //now not msg_accd.n_ress++; apr_thread_mutex_unlock(ainfo->mx); } // send back the msg_accepted. size_t len = mpaxos__msg_accepted__get_packed_size(&msg_accd); log_message_res("send", "ACCEPTED", msg_accd.h, msg_accd.ress, msg_accd.n_ress, len); uint8_t *buf = (uint8_t *) malloc(len); mpaxos__msg_accepted__pack(&msg_accd, buf); for (int i = 0; i < msg_accd.n_ress; i++) { free(msg_accd.ress[i]); } free(msg_accd.ress); rpc_state *ret_state = (rpc_state*) malloc(sizeof(rpc_state)); ret_state->raw_output = buf; ret_state->sz_output = len; return ret_state; }
static sql_rel * replica(mvc *sql, sql_rel *rel, char *uri) { if (!rel) return rel; if (rel_is_ref(rel)) { if (has_remote_or_replica(rel)) { sql_rel *nrel = rel_copy(sql->sa, rel); if (nrel && rel->p) nrel->p = prop_copy(sql->sa, rel->p); rel_destroy(rel); rel = nrel; } else { return rel; } } switch (rel->op) { case op_basetable: { sql_table *t = rel->l; if (isReplicaTable(t)) { node *n; if (uri) { /* replace by the replica which matches the uri */ for (n = t->tables.set->h; n; n = n->next) { sql_table *p = n->data; if (isRemote(p) && strcmp(uri, p->query) == 0) { rel = rewrite_replica(sql, rel, t, p); break; } } } else { /* no match, use first */ sql_table *p = NULL; if (t->tables.set) { p = t->tables.set->h->data; rel = rewrite_replica(sql, rel, t, p); } else { rel = NULL; } } } } case op_table: break; case op_join: case op_left: case op_right: case op_full: case op_apply: case op_semi: case op_anti: case op_union: case op_inter: case op_except: rel->l = replica(sql, rel->l, uri); rel->r = replica(sql, rel->r, uri); break; case op_project: case op_select: case op_groupby: case op_topn: case op_sample: rel->l = replica(sql, rel->l, uri); break; case op_ddl: rel->l = replica(sql, rel->l, uri); if (rel->r) rel->r = replica(sql, rel->r, uri); break; case op_insert: case op_update: case op_delete: rel->r = replica(sql, rel->r, uri); break; } return rel; }
static sql_rel * distribute(mvc *sql, sql_rel *rel) { sql_rel *l = NULL, *r = NULL; prop *p, *pl, *pr; if (!rel) return rel; if (rel_is_ref(rel)) { if (has_remote_or_replica(rel)) { sql_rel *nrel = rel_copy(sql->sa, rel); if (nrel && rel->p) nrel->p = prop_copy(sql->sa, rel->p); rel_destroy(rel); rel = nrel; } else { return rel; } } switch (rel->op) { case op_basetable: { sql_table *t = rel->l; /* set_remote() */ if (isRemote(t)) { char *uri = t->query; p = rel->p = prop_create(sql->sa, PROP_REMOTE, rel->p); p->value = uri; } } case op_table: break; case op_join: case op_left: case op_right: case op_full: case op_apply: case op_semi: case op_anti: case op_union: case op_inter: case op_except: l = rel->l = distribute(sql, rel->l); r = rel->r = distribute(sql, rel->r); if (l && (pl = find_prop(l->p, PROP_REMOTE)) != NULL && r && (pr = find_prop(r->p, PROP_REMOTE)) == NULL) { r = rel->r = distribute(sql, replica(sql, rel->r, pl->value)); } else if (l && (pl = find_prop(l->p, PROP_REMOTE)) == NULL && r && (pr = find_prop(r->p, PROP_REMOTE)) != NULL) { l = rel->l = distribute(sql, replica(sql, rel->l, pr->value)); } if (l && (pl = find_prop(l->p, PROP_REMOTE)) != NULL && r && (pr = find_prop(r->p, PROP_REMOTE)) != NULL && strcmp(pl->value, pr->value) == 0) { l->p = prop_remove(l->p, pl); r->p = prop_remove(r->p, pr); pl->p = rel->p; rel->p = pl; } break; case op_project: case op_select: case op_groupby: case op_topn: case op_sample: rel->l = distribute(sql, rel->l); l = rel->l; if (l && (p = find_prop(l->p, PROP_REMOTE)) != NULL) { l->p = prop_remove(l->p, p); p->p = rel->p; rel->p = p; } break; case op_ddl: rel->l = distribute(sql, rel->l); if (rel->r) rel->r = distribute(sql, rel->r); break; case op_insert: case op_update: case op_delete: rel->r = distribute(sql, rel->r); break; } return rel; }
sql_exp * exp_copy( sql_allocator *sa, sql_exp * e) { sql_exp *l, *r, *r2, *ne = NULL; switch(e->type){ case e_column: ne = exp_column(sa, e->l, e->r, exp_subtype(e), e->card, has_nil(e), is_intern(e)); ne->flag = e->flag; break; case e_cmp: if (e->flag == cmp_or) { list *l = exps_copy(sa, e->l); list *r = exps_copy(sa, e->r); if (l && r) ne = exp_or(sa, l,r); } else if (e->flag == cmp_in || e->flag == cmp_notin || get_cmp(e) == cmp_filter) { sql_exp *l = exp_copy(sa, e->l); list *r = exps_copy(sa, e->r); if (l && r) { if (get_cmp(e) == cmp_filter) ne = exp_filter(sa, l, r, e->f, is_anti(e)); else ne = exp_in(sa, l, r, e->flag); } } else { l = exp_copy(sa, e->l); r = exp_copy(sa, e->r); if (e->f) { r2 = exp_copy(sa, e->f); if (l && r && r2) ne = exp_compare2(sa, l, r, r2, e->flag); } else if (l && r) { ne = exp_compare(sa, l, r, e->flag); } } break; case e_convert: l = exp_copy(sa, e->l); if (l) ne = exp_convert(sa, l, exp_fromtype(e), exp_totype(e)); break; case e_aggr: case e_func: { list *l = e->l, *nl = NULL; if (!l) { return e; } else { nl = exps_copy(sa, l); if (!nl) return NULL; } if (e->type == e_func) ne = exp_op(sa, nl, e->f); else ne = exp_aggr(sa, nl, e->f, need_distinct(e), need_no_nil(e), e->card, has_nil(e)); break; } case e_atom: if (e->l) ne = exp_atom(sa, e->l); else if (!e->r) ne = exp_atom_ref(sa, e->flag, &e->tpe); else ne = exp_param(sa, e->r, &e->tpe, e->flag); break; case e_psm: if (e->flag == PSM_SET) ne = exp_set(sa, e->name, exp_copy(sa, e->l), GET_PSM_LEVEL(e->flag)); break; } if (ne && e->p) ne->p = prop_copy(sa, e->p); if (e->name) exp_setname(sa, ne, exp_find_rel_name(e), exp_name(e)); return ne; }