Ejemplo n.º 1
0
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;
    }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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;
}