Skip to content

Instantly share code, notes, and snippets.

@fermopili
Created May 20, 2017 19:25
Show Gist options
  • Save fermopili/4eb632a92568595710b3fe208dcc1772 to your computer and use it in GitHub Desktop.
Save fermopili/4eb632a92568595710b3fe208dcc1772 to your computer and use it in GitHub Desktop.
com.javarush.task.task37.task3708 Кеширующий Proxy
package com.javarush.task.task37.task3708.cache;
import java.util.LinkedHashMap;
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
@Override
protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
// Remove the eldest element whenever size of cache exceeds the capacity
return (size() > this.capacity);
}
public LRUCache(int capacity) {
// Call constructor of LinkedHashMap with accessOrder set to true to
// achieve LRU Cache behavior
super(capacity + 1, 1.0f, true);
this.capacity = capacity;
}
public V find(K key) {
return super.get(key);
}
public void set(K key, V value) {
super.put(key, value);
}
}
package com.javarush.task.task37.task3708.retrievers;
import com.javarush.task.task37.task3708.cache.LRUCache;
import com.javarush.task.task37.task3708.storage.Storage;
/**
* Created by Administrator on 20.05.2017.
*/
public class CachingProxyRetriever implements Retriever
{
private Storage storage;
private OriginalRetriever originalRetriever;
private LRUCache<Long, Object> lruCache;
public CachingProxyRetriever(Storage storage)
{
this.storage = storage;
this.originalRetriever = new OriginalRetriever ( storage );
lruCache = new LRUCache<> ( 16 );
}
@Override
public Object retrieve(long id)
{
Object obj = lruCache.find ( id );
if (obj == null)
{
obj = originalRetriever.retrieve ( id );
lruCache.set ( id, obj );
}
return obj;
}
}
package com.javarush.task.task37.task3708.retrievers;
import com.javarush.task.task37.task3708.storage.Storage;
public class OriginalRetriever implements Retriever
{
Storage storage;
public OriginalRetriever(Storage storage)
{
this.storage = storage;
}
@Override
public Object retrieve(long id)
{
return storage.get ( id );
}
}
package com.javarush.task.task37.task3708.retrievers;
public interface Retriever {
Object retrieve(long id);
}
package com.javarush.task.task37.task3708;
import com.javarush.task.task37.task3708.retrievers.CachingProxyRetriever;
import com.javarush.task.task37.task3708.retrievers.OriginalRetriever;
import com.javarush.task.task37.task3708.retrievers.Retriever;
import com.javarush.task.task37.task3708.storage.FarAwayStorage;
import com.javarush.task.task37.task3708.storage.Storage;
/*
Кеширующий Proxy
*/
public class Solution {
private static final int n = 10;
public static void main(String[] args) {
Storage storage = new FarAwayStorage();
fillStorage(storage);
System.out.println("Testing OriginalRetriever: ");
testRetriever(new OriginalRetriever (storage));
System.out.println("\n\n\n\n\n\n\n\n\n\nTesting CachingProxyRetriever: ");
testRetriever(new CachingProxyRetriever(storage));
}
private static void fillStorage(Storage storage) {
for (int i = 0; i < n; i++) {
storage.add("Resource #" + i);
}
}
private static void testRetriever(Retriever retriever) {
for (int i = 0; i < n * 4; i++) {
System.out.println("Loaded value : " + retriever.retrieve((long) (Math.random() * n)));
}
}
}
package com.javarush.task.task37.task3708.storage;
import java.util.HashMap;
public class FarAwayStorage implements Storage {
private long id = 0;
private HashMap<Long, Object> storageMap = new HashMap<>();
@Override
public void add(Object o) {
storageMap.put(id++, o);
}
@Override
public Object get(long id) {
System.out.println("Getting a value for id #" + id + " from FarAwayStorage...");
try {
Thread.sleep(2000);
} catch (InterruptedException ignored) {
}
return storageMap.get(id);
}
}
package com.javarush.task.task37.task3708.storage;
public interface Storage {
void add(Object storedObject);
Object get(long id);
}
taskKey="com.javarush.task.task37.task3708"
Кеширующий Proxy
Реализация паттерна Proxy предоставляет объект, который контролирует доступ к другому объекту.
Тебе необходимо создать класс CachingProxyRetriever в пакете retrievers, который будет обеспечивать ту же
функциональность что и класс OriginalRetriever, но с одним важным дополнением. Необходимо всегда пробовать
сначала получить объект из кеша, и только если его там нет - выполнять дорогостоящую операцию загрузки из
storage. После получения необходимого объекта из хранилища storage, его необходимо кешировать
с помощью объекта типа LRUCache.
Для клиента (в данном случае класс Solution) использование CachingProxyRetriever ничем не должно отличаться
от использования класса OriginalRetriever.
P.S. Тебе понадобятся поля типов LRUCache и OriginalRetriever в классе CachingProxyRetriever.
Требования:
1. В классе CachingProxyRetriever должно быть создано поле типа OriginalRetriever.
2. В классе CachingProxyRetriever должно быть создано поле типа LRUCache.
3. Конструктор класса CachingProxyRetriever должен принимать один параметр типа Storage и инициализировать поле типа OriginalRetriever.
4. Метод retrieve класса CachingProxyRetriever должен выполнять поиск подходящего объекта в кеше с помощью метода find.
5. Метод retrieve класса CachingProxyRetriever должен получать объект из хранилища с помощью метода retrieve объекта типа OriginalRetriever и добавлять в кеш, если он не был там найден.
6. Метод retrieve класса CachingProxyRetriever не должен вызывать метод retrieve класса OriginalRetriever, если объект был найден в кеше.
7. Метод retrieve класса CachingProxyRetriever должен возвращать объект, которому в хранилище соответствует id, полученный в качестве параметра.
8. Класс CachingProxyRetriever должен поддерживать интерфейс Retriever.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment