docs: @SuppressWarnings("unchecked")
      void cleanup(Ringbuffer ringbuffer) {
          if (ringbuffer.headSequence() > ringbuffer.tailSequence()) {
              return;
          }
  
          long now = currentTimeMillis();
          while (ringbuffer.headSequence() <= ringbuffer.tailSequence()) {
              final long headSequence = ringbuffer.headSequence();
  
              if (ringExpirationMs[toIndex(headSequence)] > now) {
                  return;
              }
  
              // we null the slot and allow the gc to take care of the object.
              // if we don't clean it, we'll have a potential memory leak.
              ringbuffer.set(headSequence, null);
  
              // we don't need to 0 the ringExpirationMs slot since it contains a long value.
  
              // and we move the head to the next item.
              // if nothing remains in the ringbuffer, then the head will be 1 larger than the tail.
              ringbuffer.setHeadSequence(ringbuffer.headSequence() + 1);
          }
      }