synchronized void add(long value) {
   assert tLast >= 0;
   if (tLast > 0L) {
     long interArrivalTime = (value - tLast);
     if (interArrivalTime <= MAX_INTERVAL_IN_NANO) arrivalIntervals.add(interArrivalTime);
     else logger.debug("Ignoring interval time of {}", interArrivalTime);
   } else {
     // We use a very large initial interval since the "right" average depends on the cluster
     // size
     // and it's better to err high (false negatives, which will be corrected by waiting a bit
     // longer)
     // than low (false positives, which cause "flapping").
     arrivalIntervals.add(FailureDetector.INITIAL_VALUE_NANOS);
   }
   tLast = value;
 }
 @Override
 public String toString() {
   return StringUtils.join(arrivalIntervals.iterator(), " ");
 }
 // see lealone-2597 for an explanation of the math at work here.
 double phi(long tnow) {
   assert arrivalIntervals.size() > 0
       && tLast > 0; // should not be called before any samples arrive
   long t = tnow - tLast;
   return t / mean();
 }
 double mean() {
   return arrivalIntervals.mean();
 }