117 lines
3.8 KiB
Java
117 lines
3.8 KiB
Java
package org.warp.jcwdb;
|
|
|
|
public class Cleaner {
|
|
|
|
public static final boolean DISABLE_CLEANER = false;
|
|
public static final boolean ENABLE_CLEANER_LOGGING = false;
|
|
private static final double MAXIMUM_SLEEP_INTERVAL = 8d * 1000d; // 8 seconds
|
|
private static final double MINIMUM_SLEEP_INTERVAL = 1d * 1000d; // 1 second
|
|
private static final double NORMAL_REMOVED_ITEMS = 2500l;
|
|
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() {
|
|
if (!DISABLE_CLEANER) {
|
|
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 {
|
|
if (ENABLE_CLEANER_LOGGING) System.out.println("[CLEANER] Waiting " + sleepInterval + "ms.");
|
|
sleepFor(sleepInterval);
|
|
final long time1 = System.currentTimeMillis();
|
|
final double removedItems = clean();
|
|
final long time2 = System.currentTimeMillis();
|
|
if (ENABLE_CLEANER_LOGGING) System.out.println("[CLEANER] CLEAN_TIME " + (time2 - time1));
|
|
double suggestedExecutionTimeByItemsCalculations = (sleepInterval + MAXIMUM_SLEEP_INTERVAL) / 2;
|
|
|
|
if (ENABLE_CLEANER_LOGGING) System.out.println("[CLEANER] REMOVED_ITEMS: " + removedItems);
|
|
if (removedItems > 0) {
|
|
final double removedItemsRatio = removedItems / NORMAL_REMOVED_ITEMS;
|
|
if (ENABLE_CLEANER_LOGGING) System.out.println("[CLEANER] REMOVED_ITEMS_RATIO: " + removedItemsRatio);
|
|
if (removedItemsRatio < 1d / REMOVED_ITEMS_RATIO || removedItemsRatio >= REMOVED_ITEMS_RATIO) {
|
|
suggestedExecutionTimeByItemsCalculations = sleepInterval / removedItemsRatio;
|
|
}
|
|
}
|
|
|
|
if (ENABLE_CLEANER_LOGGING) System.out.println("[CLEANER] Items: SUGGESTING SLEEP_INTERVAL FROM " + sleepInterval + "ms TO " + suggestedExecutionTimeByItemsCalculations + "ms");
|
|
|
|
double newSleepInterval = suggestedExecutionTimeByItemsCalculations;
|
|
if (ENABLE_CLEANER_LOGGING) 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 {
|
|
if (ENABLE_CLEANER_LOGGING) System.out.println("[CLEANER] CHANGED SLEEP_INTERVAL FROM " + sleepInterval + "ms TO " + newSleepInterval + "ms");
|
|
sleepInterval = (int) newSleepInterval;
|
|
}
|
|
|
|
|
|
if (ENABLE_CLEANER_LOGGING) System.out.println("[CLEANER] Cleaned " + removedItems + " items.");
|
|
}catch (InterruptedException e) {
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
private void sleepFor(int sleepInterval) throws InterruptedException {
|
|
int lastI = (int) Math.ceil(((double) sleepInterval) / 1000d);
|
|
for (int i = 0; i < lastI; i++) {
|
|
if (stopRequest) {
|
|
return;
|
|
}
|
|
if (i == lastI) {
|
|
Thread.sleep(sleepInterval % 1000);
|
|
} else {
|
|
Thread.sleep(lastI);
|
|
}
|
|
Thread.sleep(sleepInterval);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|