101 lines
3.1 KiB
Java
101 lines
3.1 KiB
Java
package org.warp.jcwdb;
|
|
|
|
import java.io.IOException;
|
|
import java.lang.ref.WeakReference;
|
|
import java.nio.channels.ClosedChannelException;
|
|
|
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
|
|
|
|
public class Cleaner {
|
|
|
|
private static final double MAXIMUM_SLEEP_INTERVAL = 20d * 1000d; // 20 minutes
|
|
private static final double MINIMUM_SLEEP_INTERVAL = 1d * 1000d; // 1 second
|
|
private static final double NORMAL_REMOVED_ITEMS = 1000l;
|
|
private static final double REMOVED_ITEMS_RATIO = 2.5d; // 250%
|
|
|
|
private final Cleanable[] objectsToClean;
|
|
private final Thread cleanerThread;
|
|
private int sleepInterval = (int) MINIMUM_SLEEP_INTERVAL;
|
|
private volatile boolean stopRequest = false;
|
|
|
|
public Cleaner(Cleanable... objectsToClean) {
|
|
this.objectsToClean = objectsToClean;
|
|
this.cleanerThread = new Thread(new CleanLoop());
|
|
this.cleanerThread.setName("Cleaner thread");
|
|
this.cleanerThread.setDaemon(true);
|
|
}
|
|
|
|
public void start() {
|
|
this.cleanerThread.start();
|
|
}
|
|
|
|
/**
|
|
* Clean
|
|
* @return number of removed items
|
|
*/
|
|
private long clean() {
|
|
long cleanedItems = 0;
|
|
for (Cleanable cleanable : objectsToClean) {
|
|
cleanedItems += cleanable.clean();
|
|
}
|
|
System.gc();
|
|
return cleanedItems;
|
|
}
|
|
|
|
public void stop() {
|
|
if (cleanerThread != null) {
|
|
stopRequest = true;
|
|
while (cleanerThread.isAlive()) {
|
|
try {
|
|
Thread.sleep(100);
|
|
} catch (InterruptedException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private class CleanLoop implements Runnable {
|
|
|
|
@Override
|
|
public void run() {
|
|
while(!stopRequest) {
|
|
try {
|
|
System.out.println("[CLEANER] Waiting " + sleepInterval + "ms.");
|
|
Thread.sleep(sleepInterval);
|
|
final double removedItems = clean();
|
|
double suggestedExecutionTimeByItemsCalculations = sleepInterval;
|
|
|
|
System.out.println("[CLEANER] REMOVED_ITEMS: " + removedItems);
|
|
if (removedItems > 0) {
|
|
final double removedItemsRatio = removedItems / NORMAL_REMOVED_ITEMS;
|
|
System.out.println("[CLEANER] REMOVED_ITEMS_RATIO: " + removedItemsRatio);
|
|
if (removedItemsRatio < 1d / REMOVED_ITEMS_RATIO || removedItemsRatio > REMOVED_ITEMS_RATIO) {
|
|
suggestedExecutionTimeByItemsCalculations = sleepInterval / removedItemsRatio;
|
|
}
|
|
}
|
|
|
|
System.out.println("[CLEANER] Items: SUGGESTING SLEEP_INTERVAL FROM " + sleepInterval + "ms TO " + suggestedExecutionTimeByItemsCalculations + "ms");
|
|
|
|
double newSleepInterval = suggestedExecutionTimeByItemsCalculations;
|
|
System.out.println("[CLEANER] Total: SUGGESTING SLEEP_INTERVAL FROM " + sleepInterval + "ms TO " + newSleepInterval + "ms");
|
|
if (newSleepInterval > MAXIMUM_SLEEP_INTERVAL) {
|
|
sleepInterval = (int) MAXIMUM_SLEEP_INTERVAL;
|
|
} else if (newSleepInterval < MINIMUM_SLEEP_INTERVAL) {
|
|
sleepInterval = (int) MINIMUM_SLEEP_INTERVAL;
|
|
} else {
|
|
System.out.println("[CLEANER] CHANGED SLEEP_INTERVAL FROM " + sleepInterval + "ms TO " + newSleepInterval + "ms");
|
|
sleepInterval = (int) newSleepInterval;
|
|
}
|
|
|
|
|
|
System.out.println("[CLEANER] Cleaned " + removedItems + " items.");
|
|
}catch (InterruptedException e) {
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|