@@ -17,9 +17,17 @@ import java.util.logging.Level
17
17
import java.util.logging.Logger
18
18
19
19
class BatchOperation (
20
- private val providerClient : ContentProviderClient
20
+ private val providerClient : ContentProviderClient ,
21
+ private val maxOperationsPerYieldPoint : Int? = null
21
22
) {
22
-
23
+
24
+ companion object {
25
+
26
+ /* * Maximum number of operations per yield point in task providers that are based on SQLiteContentProvider. */
27
+ const val TASKS_OPERATIONS_PER_YIELD_POINT = 499
28
+
29
+ }
30
+
23
31
private val logger = Logger .getLogger(javaClass.name)
24
32
25
33
private val queue = LinkedList <CpoBuilder >()
@@ -96,7 +104,6 @@ class BatchOperation(
96
104
97
105
try {
98
106
val ops = toCPO(start, end)
99
- logger.fine(" Running ${ops.size} operations ($start .. ${end - 1 } )" )
100
107
val partResults = providerClient.applyBatch(ops)
101
108
102
109
val n = end - start
@@ -133,6 +140,7 @@ class BatchOperation(
133
140
* 2. If a back reference points to a row outside of start/end,
134
141
* replace it by the actual result, which has already been calculated. */
135
142
143
+ var currentIdx = 0
136
144
for (cpoBuilder in queue.subList(start, end)) {
137
145
for ((backrefKey, backref) in cpoBuilder.valueBackrefs) {
138
146
val originalIdx = backref.originalIndex
@@ -148,17 +156,22 @@ class BatchOperation(
148
156
backref.setIndex(originalIdx - start)
149
157
}
150
158
159
+ // Set a possible yield point every MAX_OPERATIONS_PER_YIELD_POINT operations for SQLiteContentProvider
160
+ currentIdx + = 1
161
+ if (maxOperationsPerYieldPoint != null && currentIdx.mod(maxOperationsPerYieldPoint) == 0 )
162
+ cpoBuilder.withYieldAllowed()
163
+
151
164
cpo + = cpoBuilder.build()
152
165
}
153
166
return cpo
154
167
}
155
168
156
169
157
170
class BackReference (
158
- /* * index of the referenced row in the original, nonsplitted transaction */
159
- val originalIndex : Int
171
+ /* * index of the referenced row in the original, non-splitted transaction */
172
+ val originalIndex : Int
160
173
) {
161
- /* * overriden index, i.e. index within the splitted transaction */
174
+ /* * overridden index, i.e. index within the splitted transaction */
162
175
private var index: Int? = null
163
176
164
177
/* *
@@ -182,8 +195,8 @@ class BatchOperation(
182
195
* value back references.
183
196
*/
184
197
class CpoBuilder private constructor(
185
- val uri : Uri ,
186
- val type : Type
198
+ val uri : Uri ,
199
+ val type : Type
187
200
) {
188
201
189
202
enum class Type { INSERT , UPDATE , DELETE }
@@ -197,11 +210,13 @@ class BatchOperation(
197
210
}
198
211
199
212
200
- var selection: String? = null
201
- var selectionArguments: Array <String >? = null
213
+ private var selection: String? = null
214
+ private var selectionArguments: Array <String >? = null
215
+
216
+ internal val values = mutableMapOf<String , Any ?>()
217
+ internal val valueBackrefs = mutableMapOf<String , BackReference >()
202
218
203
- val values = mutableMapOf<String , Any ?>()
204
- val valueBackrefs = mutableMapOf<String , BackReference >()
219
+ private var yieldAllowed = false
205
220
206
221
207
222
fun withSelection (select : String , args : Array <String >): CpoBuilder {
@@ -226,6 +241,10 @@ class BatchOperation(
226
241
return this
227
242
}
228
243
244
+ fun withYieldAllowed () {
245
+ yieldAllowed = true
246
+ }
247
+
229
248
230
249
fun build (): ContentProviderOperation {
231
250
val builder = when (type) {
@@ -242,6 +261,9 @@ class BatchOperation(
242
261
for ((key, backref) in valueBackrefs)
243
262
builder.withValueBackReference(key, backref.getIndex())
244
263
264
+ if (yieldAllowed)
265
+ builder.withYieldAllowed(true )
266
+
245
267
return builder.build()
246
268
}
247
269
0 commit comments