コード例 #1
0
ファイル: connection_pool.cpp プロジェクト: triendeau/sprout
void ConnectionPool::recycle_connections()
{
  // The recycler periodically recycles the connections so that any new nodes
  // in the upstream proxy cluster get used reasonably soon after they are
  // active.  To avoid mucking around with variable length waits, the
  // algorithm waits for a fixed period (one second) then recycles a 
  // number of connections.
  //
  // Logically the algorithm runs an independent trial for each hash slot
  // with a success probability of (1/_recycle_period).  For efficiency this
  // is implemented by using a binomially distributed random number to find
  // the number of successful trials, then selecting that number of hash slots
  // at random.
  //
  // Currently the selection is done with replacement which raises the possibility
  // that one connection may be recycled twice in the same schedule, but this
  // should only introduce a small error in the recycling rate.

  std::default_random_engine rand;
  std::binomial_distribution<int> rbinomial(_num_connections, 1.0/_recycle_period);

  while (!_terminated) 
  {
    sleep(1);

    int recycle = rbinomial(rand);

    LOG_INFO("Recycling %d connections to %.*s:%d", recycle, _target.host.slen, _target.host.ptr, _target.port);

    for (int ii = 0; ii < recycle; ++ii) 
    {
      // Pick a hash slot at random, and quiesce the connection (if active).
      int hash_slot = rand() % _num_connections;
      quiesce_connection(hash_slot);

      // Create a new connection for this hash slot. 
      create_connection(hash_slot);
    }

    int index = 0;

    // Walk the hash table, attempting to fill in any gaps caused by transports failing.
    //
    // It is safe to walk the vector without the lock since:
    //
    //  * The vector never changes size
    //  * We only care about the value of the entry being NULL (atomic check)
    //  * Only we can change a NULL value to a non-NULL value
    //  * If we just miss a change from non-NULL to NULL (a transport suddenly dies), we'll catch it in a second.
    for (std::vector<tp_hash_slot>::iterator it = _tp_hash.begin();
         it != _tp_hash.end();
         ++it)
    {
      if (it->tp == NULL)
      {
        create_connection(index);
      }
      index++;
    }
  }
}
コード例 #2
0
void SparseGenome::init_mutations(ISet &is) {
  int p = 2*is.size();		// number of "strands" = 2 * #individuals
  int i, j, k, l;		// counters and temp indices
  int n;			// number of individuals in set
  mutation_t si;		// mutation effect of a single gene
  fitness_t xw;			// change in fitness due to this gene
  double qi;			// frequency of gene
  double gu;			// genic mutation rate
  int x, nx;			// id of individual, #individuals
  int nl = 0;			// for debugging, keep track of #loci and
  int nm = 0;			// #mutations affected by this step
  int *bin;			// also keep track of distribution of mutation values
  IP *v;
  SparseGenome *sgp;

  n = is.size();
  v = new IP[n];
  for (i=0; i<n; i++)		// copy individuals to local vector for faster access
    v[i] = is.remove(0);

  bin = new int[p+1];
  //  cout << "Placing initial mutations in " << p << " strands...." << endl;

  for (i=0; i<=p; i++)
    bin[i] = 0;

  gu = u/(2*gl);		// genic rate = individual rate / number of genes

  //  cout << "Genic mutation rate (U/2N) = " << gu << endl;

  // Iterate over all loci; pick a mutation effect for that locus, figure
  // out the expected frequency of a gene with that effect, and then add it
  // to selected individuals.  In this loop 'i' is the locus index,  'j'
  // is the chromosome number for that locus, and 'k' is the index of the locus
  // within the chromosome.

  // optimization: knowing that get_gene() and set_gene() in Strand scan
  // from "left to right", start with the higher locus indices and count
  // down to 0 -- this way the lookups and insertions will all be done
  // in one step....

  for (i = gl-1; i >= 0; i--) {
    j = i / chrlength;
    k = i % chrlength;
    si = new_mutation_value(s,rs); 	// get mutation effect
    qi = gu/hs(si);			// frequency of allele with effect si
    if (qi > 1.0)
      qi = 1.0;
    nx = int(rbinomial(qi,p));   	// number of genes expected to have this mutation
   
    if (nx > p)
      nx = p;

    //    if (qi) {
    //      cout << "locus " << i << ": ";
    //      cout << ", si = " << si;
    //      cout << ", hs = " << hs(si,0.0);
    //      cout << ", qi = " << qi;
    //      cout << ", nx = " << nx << endl;
    //    }

    nm += nx;				// record info on this mutation
    bin[nx] += 1;
    if (nx)
      nl += 1;

    while (nx) {
      x = rword(n);
      l = rword(2);
      sgp = (SparseGenome *)v[x]->genes;
      if (sgp->sa[j].get_gene(k,l) == 0.0) {
	xw = sgp->sa[j].set_gene(k,l,si);
	sgp->w *= xw;
	nx--;
      }
    }
  }

  // cout << "Distributed " << nm << " mutations across " << nl << " loci" << endl;
  // for (i=0; i<=p; i++)
  //   cout << i << ": " << bin[i] << endl;
}