You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tasks/src/main/java/org/tasks/filters/FilterCounter.java

81 lines
2.9 KiB
Java

package org.tasks.filters;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.api.PermaSql;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
public class FilterCounter {
// Previous solution involved a queue of filters and a filterSizeLoadingThread. The filterSizeLoadingThread had
// a few problems: how to make sure that the thread is resumed when the controlling activity is resumed, and
// how to make sure that the the filterQueue does not accumulate filters without being processed. I am replacing
// both the queue and a the thread with a thread pool, which will shut itself off after a second if it has
// nothing to do (corePoolSize == 0, which makes it available for garbage collection), and will wake itself up
// if new filters are queued (obviously it cannot be garbage collected if it is possible for new filters to
// be added).
private final ExecutorService executorService;
private final Map<Filter, Integer> filterCounts = new ConcurrentHashMap<>();
private final TaskDao taskDao;
@Inject
public FilterCounter(TaskDao taskDao) {
this(taskDao, new ThreadPoolExecutor(0, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>()));
}
FilterCounter(TaskDao taskDao, ExecutorService executorService) {
this.taskDao = taskDao;
this.executorService = executorService;
}
public void refreshFilterCounts(final Runnable onComplete) {
executorService.submit(() -> {
for (Filter filter : filterCounts.keySet()) {
int size = countTasks(filter);
filterCounts.put(filter, size);
}
if (onComplete != null) {
onComplete.run();
}
});
}
public void registerFilter(Filter filter) {
if (!filterCounts.containsKey(filter)) {
filterCounts.put(filter, 0);
}
}
public boolean containsKey(FilterListItem filter) {
return filterCounts.containsKey(filter);
}
public Integer get(FilterListItem filter) {
return filterCounts.get(filter);
}
private int countTasks(Filter filter) {
String queryTemplate = PermaSql.replacePlaceholders(filter.getSqlQuery());
TodorooCursor<Task> cursor = taskDao.query(
Query.select(Task.ID).withQueryTemplate(queryTemplate));
try {
return cursor.getCount();
} finally {
cursor.close();
}
}
}