
com.path.android.jobqueue.cachedQueue.CachedJobQueue Maven / Gradle / Ivy
package com.path.android.jobqueue.cachedQueue;
import com.path.android.jobqueue.JobHolder;
import com.path.android.jobqueue.JobQueue;
import java.util.Collection;
/**
* a class that implements {@link JobQueue} interface, wraps another {@link JobQueue} and caches
* results to avoid unnecessary queries to wrapped JobQueue.
* does very basic caching but should be sufficient for most of the repeated cases
* element
*/
public class CachedJobQueue implements JobQueue {
JobQueue delegate;
private Cache cache;
public CachedJobQueue(JobQueue delegate) {
this.delegate = delegate;
this.cache = new Cache();
}
@Override
public long insert(JobHolder jobHolder) {
cache.invalidateAll();
return delegate.insert(jobHolder);
}
@Override
public long insertOrReplace(JobHolder jobHolder) {
cache.invalidateAll();
return delegate.insertOrReplace(jobHolder);
}
@Override
public void remove(JobHolder jobHolder) {
cache.invalidateAll();
delegate.remove(jobHolder);
}
@Override
public int count() {
if(cache.count == null) {
cache.count = delegate.count();
}
return cache.count;
}
@Override
public int countReadyJobs(boolean hasNetwork, Collection excludeGroups) {
if(cache.count != null && cache.count < 1) {
//we know count is zero, why query?
return 0;
}
int count = delegate.countReadyJobs(hasNetwork, excludeGroups);
if(count == 0) {
//warm up cache if this is an empty queue case. if not, we are creating an unncessary query.
count();
}
return count;
}
@Override
public JobHolder nextJobAndIncRunCount(boolean hasNetwork, Collection excludeGroups) {
if(cache.count != null && cache.count < 1) {
return null;//we know we are empty, no need for querying
}
JobHolder holder = delegate.nextJobAndIncRunCount(hasNetwork, excludeGroups);
//if holder is null, there is a good chance that there aren't any jobs in queue try to cache it by calling count
if(holder == null) {
//warm up empty state cache
count();
} else if(cache.count != null) {
//no need to invalidate cache for count
cache.count--;
}
return holder;
}
@Override
public Long getNextJobDelayUntilNs(boolean hasNetwork) {
if(cache.delayUntil == null) {
cache.delayUntil = new Cache.DelayUntil(hasNetwork, delegate.getNextJobDelayUntilNs(hasNetwork));
} else if(!cache.delayUntil.isValid(hasNetwork)) {
cache.delayUntil.set(hasNetwork, delegate.getNextJobDelayUntilNs(hasNetwork));
}
return cache.delayUntil.value;
}
@Override
public void clear() {
cache.invalidateAll();
delegate.clear();
}
@Override
public JobHolder findJobById(long id) {
return delegate.findJobById(id);
}
private static class Cache {
Integer count;
DelayUntil delayUntil;
public void invalidateAll() {
count = null;
delayUntil = null;
}
private static class DelayUntil {
//can be null, is OK
Long value;
boolean hasNetwork;
private DelayUntil(boolean hasNetwork, Long value) {
this.value = value;
this.hasNetwork = hasNetwork;
}
private boolean isValid(boolean hasNetwork) {
return this.hasNetwork == hasNetwork;
}
public void set(boolean hasNetwork, Long value) {
this.value = value;
this.hasNetwork = hasNetwork;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy