void LIST_Append(t_List *p_NewList, t_List *p_Head) { t_List *p_First = NCSW_LIST_FIRST(p_NewList); if (p_First != p_NewList) { t_List *p_Last = LIST_LAST(p_NewList); t_List *p_Cur = NCSW_LIST_NEXT(p_Head); NCSW_LIST_PREV(p_First) = p_Head; NCSW_LIST_FIRST(p_Head) = p_First; NCSW_LIST_NEXT(p_Last) = p_Cur; LIST_LAST(p_Cur) = p_Last; } }
int QueryGetIndexesToUse(BinaryStr* query,ListNode* head){ LIST_INIT(head); bson_iterator q,o; bson_type qType,tType; bson_iterator_from_buffer(&q, query->data); while((qType =bson_iterator_next(&q))) { const char* key = bson_iterator_key(&q); if (qType != BSON_ARRAY && qType != BSON_OBJECT ) { ListNode* node2 = (ListNode*) malloc(sizeof(*node2)); node2->data = strdup(key); LIST_ADD_AFTER(node2,LIST_LAST(head)); } } return 0; }
/** * paxos_commit - Commit a value for an instance of the Paxos protocol. * * We totally order calls to paxos_learn by instance number in order to make * the join and greet protocols behave properly. This also gives our chat * clients an easy mechanism for totally ordering their logs without extra * work on their part. * * It is possible that failed DEC_PART decrees (i.e., decrees in which the * proposer attempts to disconnect an acceptor who a majority of acceptors * believe is still alive) could delay the learning of committed chat * messages. To avoid this, once a proposer receives enough rejections * of the decree, the part decree is replaced with a null decree. The * proposer can then issue the part again with a higher instance number * if desired. */ int paxos_commit(struct paxos_instance *inst) { int r; struct paxos_request *req = NULL; struct paxos_instance *it; // Mark the commit. inst->pi_committed = true; // Pull the request from the request cache if applicable. if (request_needs_cached(inst->pi_val.pv_dkind)) { req = request_find(&pax->rcache, inst->pi_val.pv_reqid); // If we can't find a request and need one, send out a retrieve to the // request originator and defer the commit. if (req == NULL) { return paxos_retrieve(inst); } } // Mark the cache. inst->pi_cached = true; // We should already have committed and learned everything before the hole. assert(inst->pi_hdr.ph_inum >= pax->ihole); // Since we want our learns to be totally ordered, if we didn't just fill // the hole, we cannot learn. if (inst->pi_hdr.ph_inum != pax->ihole) { // If we're the proposer, we have to just wait it out. if (is_proposer()) { return 0; } // If the hole has committed but is just waiting on a retrieve, we'll learn // when we receive the resend. if (pax->istart->pi_hdr.ph_inum == pax->ihole && pax->istart->pi_committed) { assert(!pax->istart->pi_cached); return 0; } // The hole is either missing or uncommitted and we are not the proposer, // so issue a retry. return acceptor_retry(pax->ihole); } // Set pax->istart to point to the instance numbered pax->ihole. if (pax->istart->pi_hdr.ph_inum != pax->ihole) { pax->istart = LIST_NEXT(pax->istart, pi_le); } assert(pax->istart->pi_hdr.ph_inum == pax->ihole); // Now learn as many contiguous commits as we can. This function is the // only path by which we learn commits, and we always learn in contiguous // blocks. Therefore, it is an invariant of our system that all the // instances numbered lower than pax->ihole are learned and committed, and // none of the instances geq to pax->ihole are learned (although some may // be committed). // // We iterate over the instance list, detecting and breaking if we find a // hole and learning whenever we don't. for (it = pax->istart; ; it = LIST_NEXT(it, pi_le), ++pax->ihole) { // If we reached the end of the list, set pax->istart to the last existing // instance. if (it == (void *)&pax->ilist) { pax->istart = LIST_LAST(&pax->ilist); break; } // If we skipped over an instance number because we were missing an // instance, set pax->istart to the last instance before the hole. if (it->pi_hdr.ph_inum != pax->ihole) { pax->istart = LIST_PREV(it, pi_le); break; } // If we found an uncommitted or uncached instance, set pax->istart to it. if (!it->pi_committed || !it->pi_cached) { pax->istart = it; break; } // By our invariant, since we are past our original hole, no instance // should be learned. assert(!it->pi_learned); // Grab its associated request. This is guaranteed to exist because we // have checked that pi_cached holds. req = NULL; if (request_needs_cached(it->pi_val.pv_dkind)) { req = request_find(&pax->rcache, it->pi_val.pv_reqid); assert(req != NULL); } // Learn the value. ERR_RET(r, paxos_learn(it, req)); } return 0; }