private void ProcessKeyExpiryDates()
        {
            var nowTicks = TicksHelper.GetTicks64();
            var nowTicksDividedBy1024 = (int)(nowTicks >> 10);

            while (_keysToBePutIntoExpiryHeapReader.TryRead(out var keyAndExpiry))
            {
                if (keyAndExpiry.ExpiryTicksDividedBy1024 < nowTicksDividedBy1024)
                {
                    RemoveExpiredKey(keyAndExpiry, nowTicks);
                }
                else
                {
                    _keysToExpireHeap.Add(keyAndExpiry);
                }
            }

            while (
                _keysToExpireHeap.TryPeek(out var nextPeek) &&
                nextPeek.ExpiryTicksDividedBy1024 < nowTicksDividedBy1024 &&
                _keysToExpireHeap.TryTake(out var next))
            {
                RemoveExpiredKey(next, nowTicks);
            }

            _keyExpiryProcessorTimer.Change((int)_keyExpiryProcessorInterval.TotalMilliseconds, -1);
        }
        protected bool RemoveImpl(TKey key, out TValue value)
        {
            if (!_values.TryRemove(key, out var valueAndExpiry) ||
                valueAndExpiry.ExpiryTicks < TicksHelper.GetTicks64())
            {
                value = default;
                return(false);
            }

            value = valueAndExpiry.Value;
            return(true);
        }