Получить 3 верхних элемента из кеша памяти - PullRequest
0 голосов
/ 04 марта 2019

Когда мне нужно получить top 3 элементы из Map, я могу написать код:

private static Map<String, Integer> SortMapBasedOnValues(Map<String, Integer> map, int n) {

        Map<String, Integer> sortedDecreasingly = map.entrySet().stream()
                .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).limit(n)
                .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));

        return sortedDecreasingly;
    }

У меня есть кэш памяти, который я использую для отслеживания некоторых данных приложения,

public class MemoryCache<K, T> {


    private long timeToLive;
    private LRUMap map;

    protected class CacheObject {

        public long lastAccessed = System.currentTimeMillis();
        public T value;

        protected CacheObject(T value) {
            this.value = value;
        }
    }

    public MemoryCache(long timeToLive, final long timerInterval, int maxItems) {

        this.timeToLive = timeToLive * 1000;

        map = new LRUMap(maxItems);

        if (this.timeToLive > 0 && timerInterval > 0) {

            Thread t = new Thread(new Runnable() {

                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(timerInterval * 1000);
                        } catch (InterruptedException ex) {
                        }
                        cleanup();
                    }
                }
            });

            t.setDaemon(true);
            t.start();
        }
    }

    public void put(K key, T value) {
        synchronized (map) {
            map.put(key, new CacheObject(value));
        }
    }

    @SuppressWarnings("unchecked")
    public T get(K key) {

        synchronized (map) {

            CacheObject c = (CacheObject) map.get(key);

            if (c == null)
                return null;
            else {
                c.lastAccessed = System.currentTimeMillis();
                return c.value;
            }
        }
    }

    public void remove(K key) {
        synchronized (map) {
            map.remove(key);
        }
    }

    public int size() {
        synchronized (map) {
            return map.size();
        }
    }

    @SuppressWarnings("unchecked")
    public void cleanup() {

        long now = System.currentTimeMillis();
        ArrayList<K> deleteKey = null;

        synchronized (map) {
            MapIterator itr = map.mapIterator();

            deleteKey = new ArrayList<K>((map.size() / 2) + 1);
            K key = null;
            CacheObject c = null;

            while (itr.hasNext()) {
                key = (K) itr.next();
                c = (CacheObject) itr.getValue();

                if (c != null && (now > (timeToLive + c.lastAccessed))) {
                    deleteKey.add(key);
                }
            }
        }

        for (K key : deleteKey) {
            synchronized (map) {
                map.remove(key);
            }

            Thread.yield();
        }
    }

}

Внутри приложения я инициализирую его,

MemoryCache<String, Integer> cache = new MemoryCache<String, Integer>(200, 500, 100);

Затем я могу добавить данные,

cache.put("productId", 500);

Я хотел бы добавить функциональность вMemoryCache class, поэтому при вызове вернет HashMap из трех лучших элементов в зависимости от значения.

Есть ли у вас какие-либо советы, как это реализовать?

1 Ответ

0 голосов
/ 04 марта 2019

Хотя у меня нет хорошего ответа, я конвертирую MemoryCache в HashMap с дополнительным функционалом, реализованным в классе MemoryCache и позже, использую его с функцией, предоставленной ранее, для получения верхнего3 элемента в зависимости от значения,

Вот мой обновленный код,

/**
 * convert the cache full of items to regular HashMap with the same
 * key and value pair
 *
 * @return
 */
public Map<Product, Integer> convertToMap() {

    synchronized (lruMap) {

        Map<Product, Integer> convertedMap = new HashMap<>();

        MapIterator iterator = lruMap.mapIterator();

        K k = null;
        V v = null;

        CacheObject o = null;

        while (iterator.hasNext()) {

            k = (K) iterator.next();
            v = (V) iterator.getValue();

            Product product = (Product) k;

            o = (CacheObject) v;
            int itemsSold = Integer.valueOf((o.value).toString());

            convertedMap.put(product, itemsSold);
        }

        return convertedMap;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...