com.github.pojomvcc.CacheExpiryPolicy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pojo-mvcc Show documentation
Show all versions of pojo-mvcc Show documentation
A simple in-memory POJO Multi Version Concurrency Control (MVCC) cache.
The newest version!
package com.github.pojomvcc;
/**
* Defines how and when a {@code com.github.pojomvcc.CacheElement} instance's history should be removed from the
* {@code com.github.pojomvcc.RootObjectCache}.
*
* It is very important that instances of this class perform very quickly. This operation is called frequently to clean
* up the {@link RootObjectCache}, all while maintaining the write lock, so excessively long running
* expiry policies will cause issues.
*
* @author Aidan Morgan
*/
public abstract class CacheExpiryPolicy {
/**
* Never remove history from the {@code com.github.pojomvcc.RootObjectCache}.
*/
public static CacheExpiryPolicy NEVER() {
return new CacheExpiryPolicy() {
@Override
public boolean shouldRun(RootObjectCache rootObjectCache) {
return false; // No-op
}
@Override
public boolean shouldExpire(RootObjectCache rootCache, RevisionKeyList rkl) {
return false; // No-op
}
};
}
/**
* Remove history when there are no-longer any active {@code com.github.pojomvcc.RevisionObjectCache} instances
* referring to the revision.
*/
public static CacheExpiryPolicy NO_LONGER_USED() {
return new CacheExpiryPolicy() {
@Override
public boolean shouldRun(RootObjectCache rootObjectCache) {
return true;
}
@Override
public boolean shouldExpire(RootObjectCache rootCache, RevisionKeyList rkl) {
return rkl.getRevision() < getOldestActiveRevision(rootCache);
}
private long getOldestActiveRevision(RootObjectCache rootObjectCache) {
long lowestRevisionNumber = Long.MAX_VALUE;
for (RevisionObjectCache cache : rootObjectCache.getActiveRevisions()) {
lowestRevisionNumber = Math.min(lowestRevisionNumber, cache.getRevision());
}
return lowestRevisionNumber;
}
};
}
/**
* Creates a new {@link CacheExpiryPolicy} that uses the {@code NO_LONGER_USED}
* policy, but only runs it on every n'th call.
*
* @param n Number indicating each n'th call that the expiry policy should be called on.
* @return The cache expiry policy.
*/
public static CacheExpiryPolicy NO_LONGER_USED(final int n) {
return new CacheExpiryPolicy() {
//noinspection unchecked not much we can do here but cheat...
private CacheExpiryPolicy instance = (CacheExpiryPolicy) NO_LONGER_USED();
private int count = 0;
public boolean shouldRun(RootObjectCache rootObjectCache) {
count++;
return count % n == 0;
}
public boolean shouldExpire(RootObjectCache rootCache, RevisionKeyList rkl) {
return instance.shouldExpire(rootCache, rkl);
}
};
}
/**
* Remove history that is older than a certain amount of time.
*/
public static CacheExpiryPolicy TIME_BASED(final long longestAgeInMs) {
return new CacheExpiryPolicy() {
@Override
public boolean shouldRun(RootObjectCache rootObjectCache) {
return true;
}
@Override
public boolean shouldExpire(RootObjectCache rootCache, RevisionKeyList rkl) {
// NOTE : [AM] : This is gross I know, but it's the easiest (and fastest) way possible.
return (System.currentTimeMillis() - rkl.getRevisionTime().getTime() > longestAgeInMs);
}
};
}
/**
* Checks whether this {@link CacheExpiryPolicy} should be run for the specified
* {@link RootObjectCache}.
*
* @param rootObjectCache The {@code RootObjectCache} instance to check.
* @return {@code true} if the this {@code CacheExpiryPolicy} should be run, otherwise {@code false}.
*/
public abstract boolean shouldRun(RootObjectCache rootObjectCache);
/**
* Checks whether the provided {@link RevisionKeyList} should be expired from the provided
* {@link RootObjectCache}.
*
* @param rootCache The {@code RootObjectCache} instance to check.
* @param rkl The revision key list.
* @return {@code true} if the key list should expire, otherwise {@code false}.
*/
public abstract boolean shouldExpire(RootObjectCache rootCache, RevisionKeyList rkl);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy