127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney/* 227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * Copyright (C) 2010 The Android Open Source Project 327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * 427d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * Licensed under the Apache License, Version 2.0 (the "License"); 527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * you may not use this file except in compliance with the License. 627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * You may obtain a copy of the License at 727d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * 827d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * http://www.apache.org/licenses/LICENSE-2.0 927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * 1027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * Unless required by applicable law or agreed to in writing, software 1127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * distributed under the License is distributed on an "AS IS" BASIS, 1227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * See the License for the specific language governing permissions and 1427d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * limitations under the License. 1527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney */ 1627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 17a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringertpackage com.android.quicksearchbox.util; 18a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert 1927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 2027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinneyimport android.util.Log; 2127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 2227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinneyimport java.util.ArrayList; 2327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinneyimport java.util.List; 2427d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 2527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney/** 2639bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney * Executes NamedTasks in batches of a given size. Tasks are queued until 2739bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney * executeNextBatch is called. 2827d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney */ 29a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringertpublic class BatchingNamedTaskExecutor implements NamedTaskExecutor { 3027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 31b5fc08b7f16a32d3865f44b7f26d8aaa5304a2adBjorn Bringert private static final boolean DBG = false; 32a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert private static final String TAG = "QSB.BatchingNamedTaskExecutor"; 3327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 34a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert private final NamedTaskExecutor mExecutor; 3527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 3627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney /** Queue of tasks waiting to be dispatched to mExecutor **/ 37a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert private final ArrayList<NamedTask> mQueuedTasks = new ArrayList<NamedTask>(); 3827d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 3927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney /** 4027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * Creates a new BatchingSourceTaskExecutor. 4127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * 4227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * @param executor A SourceTaskExecutor for actually executing the tasks. 4327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney */ 4439bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney public BatchingNamedTaskExecutor(NamedTaskExecutor executor) { 4527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney mExecutor = executor; 4627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 4727d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 48a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert public void execute(NamedTask task) { 4927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney synchronized (mQueuedTasks) { 5039bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney if (DBG) Log.d(TAG, "Queuing " + task); 5139bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney mQueuedTasks.add(task); 5227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 5327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 5427d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 55a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert private void dispatch(NamedTask task) { 5627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney if (DBG) Log.d(TAG, "Dispatching " + task); 5727d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney mExecutor.execute(task); 5827d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 5927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 6027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney /** 6127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * Instructs the executor to submit the next batch of results. 6239bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney * @param batchSize the maximum number of entries to execute. 6327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney */ 6439bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney public void executeNextBatch(int batchSize) { 65a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert NamedTask[] batch = new NamedTask[0]; 6627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney synchronized (mQueuedTasks) { 6739bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney int count = Math.min(mQueuedTasks.size(), batchSize); 68a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert List<NamedTask> nextTasks = mQueuedTasks.subList(0, count); 6927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney batch = nextTasks.toArray(batch); 7027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney nextTasks.clear(); 7127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney if (DBG) Log.d(TAG, "Dispatching batch of " + count); 7227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 7327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 74a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert for (NamedTask task : batch) { 7527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney dispatch(task); 7627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 7727d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 7827d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 7927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney /** 8027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * Cancel any unstarted tasks running in this executor. This instance 8127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney * should not be re-used after calling this method. 8227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney */ 8327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney public void cancelPendingTasks() { 8427d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney synchronized (mQueuedTasks) { 8527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney mQueuedTasks.clear(); 8627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 8727d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 8827d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 8927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney public void close() { 9027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney cancelPendingTasks(); 9127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney mExecutor.close(); 9227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 9327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney} 94