Не могу понять логику работы вот сам код. Как сделать поктокобезопасность кода? - вопрос №2495770

есть код в java работы LFU-cache алгоритма. Не могу понять логику работы вот сам код:

Класс LFU-cach

import java.util.LinkedHashMap;

import java.util.Map;

import java.util.Objects;

public class LFUCache<K, V> implements Cache<K, V> {

private final LinkedHashMap<K, Node> storage;

private final int capacity;

public LFUCache(int capacity) {

if (capacity <= 0) {

throw new IllegalArgumentException(«Capacity should be more than 0»);

}

this.capacity = capacity;

this.storage = new LinkedHashMap<>(capacity, 1);

}

@Override

public V get(K key) {

Node node = storage.get(key);

if (node == null) {

return null;

}

return node.incrementFrequency().getValue();

}

@Override

public V put(K key, V value) {

doEvictionIfNeeded(key);

Node oldNode = storage.put(key, new Node(value));

if (oldNode == null) {

return null;

}

return oldNode.getValue();

}

private void doEvictionIfNeeded(K putKey) {

if (storage.size() < capacity) {

return;

}

long minFrequency = Long.MAX_VALUE;

K keyToRemove = null;

for (Map.Entry<K, Node> entry: storage.entrySet()) {

if (Objects.equals(entry.getKey(), putKey)) {

//no eviction required cause element already exists, we just need to replace it

return;

}

if (minFrequency >= entry.getValue().getFrequency()) {

minFrequency = entry.getValue().getFrequency();

keyToRemove = entry.getKey();

}

}

storage.remove(keyToRemove);

}

private class Node {

private final V value;

private long frequency;

public Node(V value) {

this.value = value;

this.frequency = 1;

}

public V getValue() {

return value;

}

public long getFrequency() {

return frequency;

}

public Node incrementFrequency() {

++frequency;

return this;

}

@Override

public String toString() {

return «Node [value=» + value + ", frequency=" + frequency + "]";

}

}

@Override

public String toString() {

return «storage = „+ storage + “, capacity=» + capacity ;

}

}

LRU cache такой:

import java.util.LinkedHashMap;

import java.util.Map;

public class LRUAlgoritm<K, V> implements Cache<K, V>{

private LRUStorage storage;

public LRUAlgoritm(int capacity) {

this.storage = new LRUStorage(capacity);

}

@Override

public V get(K key) {

return storage.get(key);

}

@Override

public V put(K key, V value) {

return storage.put(key,value);

}

private class LRUStorage extends LinkedHashMap<K, V>{

private final int capacity;

private LRUStorage (int capacity){

this.capacity = capacity;

}

@Override

protected boolean removeEldestEntry(Map.Entry<K, V> eldest){

return size()>capacity;

}

}

@Override

public String toString() {

return «storage= » + storage ;

}

}

ну и самый простой раннер для его запуска

import java.util.LinkedHashMap;

import java.util.Map;

public class Runner {

public static void main (String[] args){

LRUAlgoritm<String, String> lruAlgoritm = new LRUAlgoritm(2);

lruAlgoritm.put(«1»,«1»);

lruAlgoritm.put(«2»,«2»);

lruAlgoritm.put(«3»,«3»);

lruAlgoritm.put(«4»,«4»);

System.out.println(lruAlgoritm);

LFUCache<String, String> lfualogoritm = new LFUCache<>(3);

lfualogoritm.put(«1», «1»);

lfualogoritm.put(«2», «2»);

lfualogoritm.put(«3», «3»);

lfualogoritm.put(«4», «4»);

lfualogoritm.put(«5», «5»);

lfualogoritm.put(«2», «2»);

lfualogoritm.put("","");

lfualogoritm.get(«1»);

lfualogoritm.get(«2»);

lfualogoritm.get(«1»);

lfualogoritm.get(«10»);

System.out.println(lfualogoritm);

}

}

Правильно ли я понимаю по LFU cache, что при вставке нового ключа(вернее ключа с таким значением которое уже есть в кэше) само фреквенси(frequency), если было больше единицы, становится снова 1?
Если да то как сосздать блокировку что при такой ситуации не сбрасывалось фрекуенси?
как в этом коде сделать потокобезопасность. с чего начать какя методика перехода на потокобезопасный код?
17.06.17
0 ответов
Ответов пока нет

Виталий

Читать ответы
Посмотреть всех экспертов из раздела Технологии > Java/J2EE
Пользуйтесь нашим приложением Доступно на Google Play Загрузите в App Store