Commit a16f4887 authored by amir.yosef's avatar amir.yosef

Adding LRU Strategy

parent eb57815b
......@@ -9,7 +9,8 @@ public class Main {
ServerBuilder builder = new ServerBuilder();
director.buildMaster(builder);
builder.port(16379);
Server server = builder.build();
server.start();
try (Server server = builder.build()) {
server.start();
}
}
}
\ No newline at end of file
......@@ -12,7 +12,6 @@ public class CommandFactory implements Factory {
}
public CommandFactory() {
}
public static CommandFactory getInstance() {
......
......@@ -2,6 +2,7 @@ package server;
import client.Client;
import client.primary.MasterClient;
import storage.StorageManager;
import java.io.IOException;
import java.net.ServerSocket;
......@@ -9,12 +10,13 @@ import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
private final int PORT ;
public class Server implements AutoCloseable {
private final int PORT;
private final ExecutorService executor;
private final String role;
StorageManager manager = new StorageManager();
private static Server instance;
private static volatile Server instance;
Server(int port, String role) {
PORT = port;
......@@ -22,9 +24,11 @@ public class Server {
this.executor = Executors.newVirtualThreadPerTaskExecutor();
}
public static synchronized Server getInstance(int PORT,String role) throws IOException {
if (instance == null) {
instance = new Server(PORT,role);
public static Server getInstance(int PORT, String role) throws IOException {
if (role.equalsIgnoreCase("master")) {
if (instance == null) {
instance = new Server(PORT, role);
}
}
return instance;
}
......@@ -51,4 +55,9 @@ public class Server {
task.run();
});
}
@Override
public void close() {
manager.shutdown();
}
}
package storage;
public interface CachePolicy<K, V> {
void add(K key, V value);
V retrieve(K key);
void delete(K key);
void runMaintenance();
}
\ No newline at end of file
package storage;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
public class LRUCachePolicy<K, V> implements CachePolicy<K, V> {
private final int maxCapacity;
private final Map<K, V> cacheMap;
private final Queue<K> accessOrder;
public LRUCachePolicy(int maxCapacity) {
this.maxCapacity = maxCapacity;
this.cacheMap = new ConcurrentHashMap<>(maxCapacity);
this.accessOrder = new ConcurrentLinkedQueue<>();
}
@Override
public void add(K key, V value) {
cacheMap.put(key, value);
updateAccessOrder(key);
}
@Override
public V retrieve(K key) {
V value = cacheMap.get(key);
if (value != null) {
updateAccessOrder(key);
}
return value;
}
@Override
public void delete(K key) {
cacheMap.remove(key);
accessOrder.remove(key);
}
@Override
public void runMaintenance() {
while (cacheMap.size() > maxCapacity) {
evictLeastRecentlyUsed();
}
}
private void updateAccessOrder(K key) {
accessOrder.remove(key);
accessOrder.offer(key);
}
private void evictLeastRecentlyUsed() {
while (!accessOrder.isEmpty()) {
K leastRecentKey = accessOrder.poll();
if (cacheMap.containsKey(leastRecentKey)) {
delete(leastRecentKey);
break;
}
}
}
}
\ No newline at end of file
package storage;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Storage {
private final Map<String, String> storage = new ConcurrentHashMap<>(10000);
private final Map<String, Long> timeToExpiration = new ConcurrentHashMap<>(10000);
private final Map<String, Long> currentTimeForKey = new ConcurrentHashMap<>(10000);
private final int capacity = 10000;
private final CachePolicy<String, String> storage;
private final Map<String, Long> timeToExpiration = new ConcurrentHashMap<>(capacity);
private final Map<String, Long> currentTimeForKey = new ConcurrentHashMap<>(capacity);
private Storage() {
// RdbFileReader reader = new RdbFileReader();
//Map<String, String> stringStringMap = reader.readFile();
// storage.putAll(stringStringMap);
//Map<String, Long> keysExpiration = reader.getKeysExpiration();
// timeToExpiration.putAll(keysExpiration);
this.storage = new LRUCachePolicy<>(capacity);
}
private static final class StorageHolder {
private static final Storage storage = new Storage();
private static final Storage instance = new Storage();
}
public static Storage getInstance() {
return StorageHolder.storage;
return StorageHolder.instance;
}
public void save(String key, String value) {
storage.put(key, value);
storage.add(key, value);
}
public void save(String key, String value, Long time) {
System.out.println("SAVE Storage: " + key);
public void save(String key, String value, Long expirationTime) {
currentTimeForKey.put(key, System.currentTimeMillis());
timeToExpiration.put(key, time);
timeToExpiration.put(key, expirationTime);
save(key, value);
}
public String get(String key) {
if (isExpired(key)) return "";
return storage.get(key);
if (isExpired(key)) {
remove(key);
return "";
}
return storage.retrieve(key);
}
private boolean isExpired(String key) {
......@@ -61,5 +57,12 @@ public class Storage {
return false;
}
}
private void remove(String key) {
storage.delete(key);
timeToExpiration.remove(key);
currentTimeForKey.remove(key);
}
void runCachePolicy() {
storage.runMaintenance();
}
}
\ No newline at end of file
package storage;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class StorageManager {
private final Storage storage;
private final ScheduledExecutorService scheduler;
public StorageManager() {
this.storage = Storage.getInstance();
this.scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(this::performMaintenance, 5, 5, TimeUnit.MINUTES);
}
public Storage getStorage() {
return storage;
}
private void performMaintenance() {
storage.runCachePolicy();
System.out.println("Maintenance performed at: " + System.currentTimeMillis());
}
public void shutdown() {
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment