All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.map.impl.ExpirationTimeSetter Maven / Gradle / Ivy

/*
 * Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.map.impl;

import com.hazelcast.config.MapConfig;
import com.hazelcast.map.impl.record.Record;
import com.hazelcast.map.impl.record.RecordStatistics;

import java.util.concurrent.TimeUnit;

import static com.hazelcast.util.Preconditions.checkNotNegative;

/**
 * Utility methods for setting TTL and max idle seconds.
 */
public final class ExpirationTimeSetter {

    private ExpirationTimeSetter() {
    }

    /**
     * Sets expiration time if statistics are enabled.
     */
    public static void setExpirationTime(Record record, long maxIdleMillis) {
        final RecordStatistics statistics = record.getStatistics();
        if (statistics == null) {
            return;
        }
        final long expirationTime = calculateExpirationTime(record, maxIdleMillis);
        statistics.setExpirationTime(expirationTime);
    }

    private static long calculateExpirationTime(Record record, long maxIdleMillis) {
        // 1. Calculate TTL expiration time.
        final long ttl = checkedTime(record.getTtl());
        final long ttlExpirationTime = sumForExpiration(ttl, getLifeStartTime(record));

        // 2. Calculate idle expiration time.
        maxIdleMillis = checkedTime(maxIdleMillis);
        final long idleExpirationTime = sumForExpiration(maxIdleMillis, getIdlenessStartTime(record));

        // 3. Select most nearest expiration time.
        return Math.min(ttlExpirationTime, idleExpirationTime);
    }

    /**
     * Returns last-access-time of an entry if it was accessed before, otherwise it returns creation-time of the entry.
     * This calculation is required for max-idle-seconds expiration, because after first creation of an entry via
     * {@link com.hazelcast.core.IMap#put}, the {@code lastAccessTime} is zero till the first access.
     * Any subsequent get or update operation after first put will increase the {@code lastAccessTime}.
     */
    public static long getIdlenessStartTime(Record record) {
        long lastAccessTime = record.getLastAccessTime();
        return lastAccessTime == 0L ? record.getCreationTime() : lastAccessTime;
    }

    /**
     * Returns last-update-time of an entry if it was updated before, otherwise it returns creation-time of the entry.
     * This calculation is required for time-to-live expiration, because after first creation of an entry via
     * {@link com.hazelcast.core.IMap#put}, the {@code lastUpdateTime} is zero till the first update.
     */
    public static long getLifeStartTime(Record record) {
        long lastUpdateTime = record.getLastUpdateTime();
        return lastUpdateTime == 0L ? record.getCreationTime() : lastUpdateTime;
    }

    private static long checkedTime(long time) {
        return time <= 0L ? Long.MAX_VALUE : time;
    }

    private static long sumForExpiration(long criteriaTime, long now) {
        if (criteriaTime < 0 || now < 0) {
            throw new IllegalArgumentException("Parameters can not have negative values");
        }
        if (criteriaTime == 0) {
            return Long.MAX_VALUE;
        }
        final long expirationTime = criteriaTime + now;
        // detect potential overflow.
        if (expirationTime < 0L) {
            return Long.MAX_VALUE;
        }
        return expirationTime;
    }

    /**
     * Picks right TTL value.
     * 

* Decides which TTL to set; * TTL from config or put operation. */ public static long pickTTL(long ttlMillis, long ttlMillisFromConfig) { if (ttlMillis < 0L && ttlMillisFromConfig > 0L) { return ttlMillisFromConfig; } if (ttlMillis > 0L) { return ttlMillis; } return 0L; } public static long calculateMaxIdleMillis(MapConfig mapConfig) { final int maxIdleSeconds = mapConfig.getMaxIdleSeconds(); if (maxIdleSeconds == 0) { return Long.MAX_VALUE; } return TimeUnit.SECONDS.toMillis(maxIdleSeconds); } public static long calculateTTLMillis(MapConfig mapConfig) { final int timeToLiveSeconds = mapConfig.getTimeToLiveSeconds(); if (timeToLiveSeconds == 0) { return Long.MAX_VALUE; } return TimeUnit.SECONDS.toMillis(timeToLiveSeconds); } /** * Updates records TTL and expiration time. */ public static void updateExpiryTime(Record record, long ttl, MapConfig mapConfig) { // Preserve previously set TTL, if TTL < 0. if (ttl < 0) { ttl = record.getTtl(); } // If TTL == 0, convert it to Long.MAX_VALUE. ttl = checkedTime(ttl); record.setTtl(ttl); long maxIdleMillis = calculateMaxIdleMillis(mapConfig); setExpirationTime(record, maxIdleMillis); } /** * On backup partitions, this method delays key`s expiration. */ public static long calculateExpirationWithDelay(long timeInMillis, long delayMillis, boolean backup) { checkNotNegative(timeInMillis, "timeInMillis can't be negative"); if (backup) { final long delayedTime = timeInMillis + delayMillis; // check for a potential long overflow. if (delayedTime < 0L) { return Long.MAX_VALUE; } else { return delayedTime; } } return timeInMillis; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy