<commit_before>package stream.flarebot.flarebot.util;

import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;

public class ExpiringMap<K, V> {

    private final TreeMap<Long, ConcurrentMap<K, V>> elem;
    private final long expireAfterMS;

    public ExpiringMap(long expireAfterMS) {
        this.expireAfterMS = expireAfterMS;
        elem = new TreeMap<>((o1, o2) -> {
            if (o1 < o2)
                return 1;
            else
                return -1;
        });
    }

    public void purge() {
        long issueMS = System.currentTimeMillis();
        Iterator<Map.Entry<Long, ConcurrentMap<K, V>>> e = elem.entrySet().iterator();
        while (e.hasNext()) {
            Map.Entry<Long, ConcurrentMap<K, V>> a = e.next();
            if (issueMS >= a.getKey()) {
                e.remove();
                System.out.println(e);
            }
            else
                break;
        }
    }

    public void put(K k, V v) {
        long ms = System.currentTimeMillis() + expireAfterMS;
        ConcurrentMap<K, V> c = elem.get(ms);
        if (c == null) {
            c = new ConcurrentHashMap<>();
            c.put(k, v);
            elem.put(ms, c);
        } else {
            c.put(k, v);
        }
    }

    public boolean containsKey(K k) {
        for(ConcurrentMap<K, V> map : elem.values()) {
            if(map.containsKey(k))
                return true;
        }
        return false;
    }

    public boolean containsValue(V v) {
        for(ConcurrentMap<K, V> map : elem.values()) {
            if(map.containsValue(v))
                return true;
        }
        return false;
    }

    public V get(K k) {
        for(ConcurrentMap<K, V> map : elem.values()) {
            if(map.get(k) != null)
                return map.get(k);
        }
        return null;
    }

    public long getValue(K k) {
        for(Long l : elem.keySet()){
            if(elem.get(l).get(k) != null)
                return l;
        }
        return -1;
    }

    public static void main(String[] args) {
        ExpiringMap<Integer, String> test = new ExpiringMap<>(1000);
        for (int i = 0; i < 1000000; i++) {
            test.put(i, String.valueOf(i));
        }

        //debug
        while (!test.elem.isEmpty()) {
            int size = test.elem.size();
            test.purge();
            if (size - test.elem.size() > 0) {
                System.out.println("Removed elements. New size: " + test.elem.size());
            }
        }
    }
}<commit_msg>Add more things for expiry map<commit_after>package stream.flarebot.flarebot.util;

import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;

public class ExpiringMap<K, V> {

    private final TreeMap<Long, ConcurrentMap<K, V>> elem;
    private final long expireAfterMS;

    public ExpiringMap(long expireAfterMS) {
        this.expireAfterMS = expireAfterMS;
        elem = new TreeMap<>();
    }

    public void purge() {
        long issueMS = System.currentTimeMillis();
        Iterator<Map.Entry<Long, ConcurrentMap<K, V>>> e = elem.entrySet().iterator();
        while (e.hasNext()) {
            Map.Entry<Long, ConcurrentMap<K, V>> a = e.next();
            if (issueMS >= a.getKey()) {
                e.remove();
                System.out.println(e);
            }
            else
                break;
        }
    }

    public void put(K k, V v) {
        long ms = System.currentTimeMillis() + expireAfterMS;
        ConcurrentMap<K, V> c = elem.get(ms);
        if (c == null) {
            c = new ConcurrentHashMap<>();
            c.put(k, v);
            elem.put(ms, c);
        } else {
            c.put(k, v);
        }
    }

    public boolean containsKey(K k) {
        for(ConcurrentMap<K, V> map : elem.values()) {
            if(map.containsKey(k))
                return true;
        }
        return false;
    }

    public boolean containsValue(V v) {
        for(ConcurrentMap<K, V> map : elem.values()) {
            if(map.containsValue(v))
                return true;
        }
        return false;
    }

    public V get(K k) {
        for(ConcurrentMap<K, V> map : elem.values()) {
            if(map.get(k) != null)
                return map.get(k);
        }
        return null;
    }

    public long getValue(K k) {
        for(Long l : elem.keySet()){
            if(elem.get(l).get(k) != null)
                return l;
        }
        return -1;
    }

    public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
        if (key == null || mappingFunction == null) {
            throw new NullPointerException();
        }

        for(ConcurrentMap<K, V> map : elem.values()) {
            if(map.get(key) != null)
                return map.get(key);
        }

        V val = mappingFunction.apply(key);

        this.put(key, val);
        return val;
    }
}
{'fraction_non_alphanumeric': 0.13003875968992248, 'fraction_numerical': 0.004069767441860465, 'mean_word_length': 1.657569515962925, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4228544', 'n_tokens_mistral': 1624, 'n_tokens_neox': 1563, 'n_words': 364}