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

net.guizhanss.guizhanlib.common.RateLimit Maven / Gradle / Ivy

package net.guizhanss.guizhanlib.common;

import java.util.HashMap;
import java.util.Map;

/**
 * This package provides rate limit feature.
 *
 * @param  The type of key.
 * @author ybw0014
 */
public final class RateLimit {
    private final long limitTime;
    private final int limitVisits;
    /**
     * This map records the first visit time.
     */
    private final Map timeMap = new HashMap<>();
    /**
     * This map records the times of visits.
     */
    private final Map visitMap = new HashMap<>();

    /**
     * Constructor.
     *
     * @param time   Time period in milliseconds.
     * @param visits The limit times of visits.
     */
    public RateLimit(long time, int visits) {
        this.limitTime = time;
        this.limitVisits = visits;
    }

    /**
     * Get the overall limit of visits.
     *
     * @return The overall limit of visits.
     */
    public int getLimit() {
        return this.limitVisits;
    }

    /**
     * Get the used visits.
     *
     * @param key The query key.
     * @return Used times of visits.
     */
    public int getUsed(K key) {
        Long time = timeMap.get(key);
        Integer visits = visitMap.get(key);

        // Lack of record, this should not happen
        if (time == null || visits == null) {
            return 0;
        }

        // Time out
        if (System.nanoTime() - time >= limitTime) {
            return 0;
        }

        return visits;
    }

    /**
     * Get remaining times of visits
     *
     * @param key The query key.
     * @return Remaining times of visits
     */
    public int getRemaining(K key) {
        return getLimit() - getUsed(key);
    }

    /**
     * Increases the times of visits.
     *
     * @param key    The query key.
     * @param visits The times of visits
     * @return Whether the action succeeds.
     */
    public boolean add(K key, int visits) {
        Long time = timeMap.get(key);
        Integer visited = visitMap.get(key);

        // Lack of record, just init
        if (time == null || visited == null) {
            reset(key);
            timeMap.put(key, System.nanoTime());
            visitMap.put(key, visits);
            return true;
        }

        if (getRemaining(key) < visits) {
            return false;
        } else {
            visitMap.put(key, visited + visits);
            return true;
        }
    }

    /**
     * Increases the times of visits by 1.
     *
     * @param key The query key.
     * @return Whether the action succeeds.
     */
    public boolean add(K key) {
        return add(key, 1);
    }

    /**
     * Reset rate limit
     *
     * @param key The query key.
     */
    public void reset(K key) {
        timeMap.remove(key);
        visitMap.remove(key);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy