
com.path.android.jobqueue.nonPersistentQueue.NonPersistentJobSet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of android-priority-jobqueue Show documentation
Show all versions of android-priority-jobqueue Show documentation
a Job Queue specifically written for Android to easily schedule jobs (tasks) that run in the background, improving UX and application stability.
package com.path.android.jobqueue.nonPersistentQueue;
import com.path.android.jobqueue.JobHolder;
import com.path.android.jobqueue.log.JqLog;
import java.util.*;
/**
* This is the default implementation of JobSet.
* It uses TreeSet as the underlying data structure. Is currently inefficient, should be replaced w/ a more efficient
* version
*/
public class NonPersistentJobSet implements JobSet {
TreeSet set;
//groupId -> # of jobs in that group
Map existingGroups;
public NonPersistentJobSet(Comparator comparator) {
this.set = new TreeSet(comparator);
this.existingGroups = new HashMap();
}
private JobHolder safeFirst() {
if(set.size() < 1) {
return null;
}
return set.first();
}
@Override
public JobHolder peek(Collection excludeGroupIds) {
if(excludeGroupIds == null || excludeGroupIds.size() == 0) {
return safeFirst();
}
//there is an exclude list, we have to itereate :/
for (JobHolder holder : set) {
if (holder.getGroupId() == null) {
return holder;
}
//we have to check if it is excluded
if (excludeGroupIds.contains(holder.getGroupId())) {
continue;
}
return holder;
}
return null;
}
private JobHolder safePeek() {
if(set.size() == 0) {
return null;
}
return safeFirst();
}
@Override
public JobHolder poll(Collection excludeGroupIds) {
JobHolder peek = peek(excludeGroupIds);
if(peek != null) {
remove(peek);
}
return peek;
}
@Override
public boolean offer(JobHolder holder) {
if(holder.getId() == null) {
throw new RuntimeException("cannot add job holder w/o an ID");
}
boolean result = set.add(holder);
if(result == false) {
//remove the existing element and add new one
remove(holder);
result = set.add(holder);
}
if(result && holder.getGroupId() != null) {
incGroupCount(holder.getGroupId());
}
return result;
}
private void incGroupCount(String groupId) {
if(existingGroups.containsKey(groupId) == false) {
existingGroups.put(groupId, 1);
} else {
existingGroups.put(groupId, existingGroups.get(groupId) + 1);
}
}
private void decGroupCount(String groupId) {
Integer val = existingGroups.get(groupId);
if(val == null || val == 0) {
//TODO should we crash?
JqLog.e("detected inconsistency in NonPersistentJobSet's group id hash");
return;
}
val -= 1;
if(val == 0) {
existingGroups.remove(groupId);
}
}
@Override
public boolean remove(JobHolder holder) {
boolean removed = set.remove(holder);
if(removed && holder.getGroupId() != null) {
decGroupCount(holder.getGroupId());
}
return removed;
}
@Override
public void clear() {
set.clear();
existingGroups.clear();
}
@Override
public int size() {
return set.size();
}
@Override
public CountWithGroupIdsResult countReadyJobs(long now, Collection excludeGroups) {
//TODO we can cache most of this
int total = 0;
int groupCnt = existingGroups.keySet().size();
Set groupIdSet = null;
if(groupCnt > 0) {
groupIdSet = new HashSet();//we have to track :/
}
for(JobHolder holder : set) {
if(holder.getDelayUntilNs() < now) {
//we should not need to check groupCnt but what if sth is wrong in hashmap, be defensive till
//we write unit tests around NonPersistentJobSet
if(holder.getGroupId() != null) {
if(excludeGroups != null && excludeGroups.contains(holder.getGroupId())) {
continue;
}
//we should not need to check groupCnt but what if sth is wrong in hashmap, be defensive till
//we write unit tests around NonPersistentJobSet
if(groupCnt > 0) {
if(groupIdSet.add(holder.getGroupId())) {
total++;
}
}
//else skip, we already counted this group
} else {
total ++;
}
}
}
return new CountWithGroupIdsResult(total, groupIdSet);
}
@Override
public CountWithGroupIdsResult countReadyJobs(Collection excludeGroups) {
if(existingGroups.size() == 0) {
return new CountWithGroupIdsResult(set.size(), null);
} else {
//todo we can actually count from existingGroups set if we start counting numbers there as well
int total = 0;
Set existingGroupIds = null;
for(JobHolder holder : set) {
if(holder.getGroupId() != null) {
if(excludeGroups != null && excludeGroups.contains(holder.getGroupId())) {
continue;
} else if(existingGroupIds == null) {
existingGroupIds = new HashSet();
existingGroupIds.add(holder.getGroupId());
} else if(existingGroupIds.add(holder.getGroupId()) == false) {
continue;
}
}
total ++;
}
return new CountWithGroupIdsResult(total, existingGroupIds);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy