1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.quicksearchbox.util 18 19 import android.util.Log 20 21 /** 22 * Executes NamedTasks in batches of a given size. Tasks are queued until executeNextBatch is 23 * called. 24 * @param executor A SourceTaskExecutor for actually executing the tasks. 25 */ 26 class BatchingNamedTaskExecutor(private val mExecutor: NamedTaskExecutor) : NamedTaskExecutor { 27 /** Queue of tasks waiting to be dispatched to mExecutor */ 28 private val mQueuedTasks: ArrayList<NamedTask?> = arrayListOf() executenull29 override fun execute(task: NamedTask?) { 30 synchronized(mQueuedTasks) { 31 if (DBG) Log.d(TAG, "Queuing $task") 32 mQueuedTasks.add(task) 33 } 34 } 35 dispatchnull36 private fun dispatch(task: NamedTask?) { 37 if (DBG) Log.d(TAG, "Dispatching $task") 38 mExecutor.execute(task) 39 } 40 41 /** 42 * Instructs the executor to submit the next batch of results. 43 * @param batchSize the maximum number of entries to execute. 44 */ executeNextBatchnull45 fun executeNextBatch(batchSize: Int) { 46 var batch = arrayOfNulls<NamedTask?>(0) 47 synchronized(mQueuedTasks) { 48 val count: Int = Math.min(mQueuedTasks.size, batchSize) 49 val nextTasks: ArrayList<NamedTask?> = mQueuedTasks.subList(0, count) as ArrayList<NamedTask?> 50 batch = nextTasks.toArray(batch) 51 nextTasks.clear() 52 if (DBG) Log.d(TAG, "Dispatching batch of $count") 53 } 54 for (task in batch) { 55 dispatch(task) 56 } 57 } 58 59 /** 60 * Cancel any un-started tasks running in this executor. This instance should not be re-used after 61 * calling this method. 62 */ cancelPendingTasksnull63 override fun cancelPendingTasks() { 64 synchronized(mQueuedTasks) { mQueuedTasks.clear() } 65 } 66 closenull67 override fun close() { 68 cancelPendingTasks() 69 mExecutor.close() 70 } 71 72 companion object { 73 private const val DBG = false 74 private const val TAG = "QSB.BatchingNamedTaskExecutor" 75 } 76 } 77