code: private State updateStateWithBackOff(final long timeoutInNanos) {
          AtomicRateLimiter.State prev;
          AtomicRateLimiter.State next;
          do {
              prev = state.get();
              next = calculateNextState(timeoutInNanos, prev);
          } while (!compareAndSet(prev, next));
          return next;
      }
docs: Atomically updates the current {@link State} with the results of
  applying the {@link AtomicRateLimiter#calculateNextState}, returning the updated {@link State}.
  It differs from {@link AtomicReference#updateAndGet(UnaryOperator)} by constant back off.
  It means that after one try to {@link AtomicReference#compareAndSet(Object, Object)}
  this method will wait for a while before try one more time.
  This technique was originally described in this
  <a href="https://arxiv.org/abs/1305.5800"> paper</a>
  and showed great results with {@link AtomicRateLimiter} in benchmark tests.
  
  @param timeoutInNanos a side-effect-free function
  @return the updated value