| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 var overallTestStartTime = Date.now(); | 5 var overallTestStartTime = Date.now(); |
| 6 var kUseIndex = true; | 6 var kUseIndex = true; |
| 7 var kDontUseIndex = false; | 7 var kDontUseIndex = false; |
| 8 var kReadKeysOnly = true; | 8 var kReadKeysOnly = true; |
| 9 var kReadDataToo = false; | 9 var kReadDataToo = false; |
| 10 var kWriteToo = true; | 10 var kWriteToo = true; |
| 11 var kDontWrite = false; | 11 var kDontWrite = false; |
| 12 var kWriteSameStore = true; |
| 13 var kWriteDifferentStore = false; |
| 14 var kPlaceholderArg = false; |
| 12 | 15 |
| 13 var tests = [ | 16 var tests = [ |
| 17 // Create a single small item in a single object store, then delete everything. |
| 18 [testCreateAndDeleteDatabase, 1, 1, 1], |
| 19 // Create a single small item in a single object store, then delete everything. |
| 20 [testCreateAndDeleteDatabase, 100, 1, 1], |
| 21 // Create a single small item in a single object store, then delete everything. |
| 22 [testCreateAndDeleteDatabase, 1, 100, 1], |
| 23 // Create a single small item in a single object store, then delete everything. |
| 24 [testCreateAndDeleteDatabase, 100, 1, 10000], |
| 14 // Create a single small item in a single object store. | 25 // Create a single small item in a single object store. |
| 15 [testCreateKeysInStores, 1, 1, 1], | 26 [testCreateKeysInStores, 1, 1, 1], |
| 16 // Create many small items in a single object store. | 27 // Create many small items in a single object store. |
| 17 [testCreateKeysInStores, 100, 1, 1], | 28 [testCreateKeysInStores, 100, 1, 1], |
| 18 // Create a single small item in many object stores. | 29 // Create a single small item in many object stores. |
| 19 [testCreateKeysInStores, 1, 100, 1], | 30 [testCreateKeysInStores, 1, 100, 1], |
| 20 // Create many large items in a single object store. | 31 // Create many large items in a single object store. |
| 21 [testCreateKeysInStores, 100, 1, 10000], | 32 [testCreateKeysInStores, 100, 1, 10000], |
| 22 // Read a few random items in each of many transactions. | 33 // Read a few random items in each of many transactions. |
| 23 [testRandomReadsAndWrites, 1000, 5, 0, 50, kDontUseIndex], | 34 [testRandomReadsAndWrites, 1000, 5, 0, 50, kDontUseIndex], |
| 24 // Read many random items in each of a few transactions. | 35 // Read many random items in each of a few transactions. |
| 25 [testRandomReadsAndWrites, 1000, 50, 0, 5, kDontUseIndex], | 36 [testRandomReadsAndWrites, 1000, 50, 0, 5, kDontUseIndex], |
| 26 // Read many random items in each of a few transactions, in a large store. | 37 // Read many random items in each of a few transactions, in a large store. |
| 27 [testRandomReadsAndWrites, 5000, 50, 0, 5, kDontUseIndex], | 38 [testRandomReadsAndWrites, 5000, 50, 0, 5, kDontUseIndex], |
| 28 // Read a few random items from an index, in each of many transactions. | 39 // Read a few random items from an index, in each of many transactions. |
| 29 [testRandomReadsAndWrites, 1000, 5, 0, 50, kUseIndex], | 40 [testRandomReadsAndWrites, 1000, 5, 0, 50, kUseIndex], |
| 30 // Read many random items from an index, in each of a few transactions. | 41 // Read many random items from an index, in each of a few transactions. |
| 31 [testRandomReadsAndWrites, 1000, 50, 0, 5, kUseIndex], | 42 [testRandomReadsAndWrites, 1000, 50, 0, 5, kUseIndex], |
| 32 // Read many random items from an index, in each of a few transactions, in a | 43 // Read many random items from an index, in each of a few transactions, in a |
| 33 // large store. | 44 // large store. |
| 34 [testRandomReadsAndWrites, 5000, 50, 0, 5, kUseIndex], | 45 [testRandomReadsAndWrites, 5000, 50, 0, 5, kUseIndex], |
| 35 // Read and write a few random items in each of many transactions. | 46 // Read and write a few random items in each of many transactions. |
| 36 [testRandomReadsAndWrites, 1000, 5, 5, 50, kDontUseIndex], | 47 [testRandomReadsAndWrites, 1000, 5, 5, 50, kDontUseIndex], |
| 37 // Read and write a few random items, reading from an index, in each of many | 48 // Read and write a few random items, reading from an index, in each of many |
| 38 // transactions. | 49 // transactions. |
| 39 [testRandomReadsAndWrites, 1000, 5, 5, 50, kUseIndex], | 50 [testRandomReadsAndWrites, 1000, 5, 5, 50, kUseIndex], |
| 40 // Read a long, contiguous sequence of an object store via a cursor. | 51 // Read a long, contiguous sequence of an object store via a cursor. |
| 41 [testCursorReadsAndRandomWrites, kReadDataToo, kDontUseIndex, kDontWrite], | 52 [testCursorReadsAndRandomWrites, kReadDataToo, kDontUseIndex, kDontWrite, |
| 53 kPlaceholderArg], |
| 42 // Read a sequence of an object store via a cursor, writing | 54 // Read a sequence of an object store via a cursor, writing |
| 43 // transformed values into another. | 55 // transformed values into another. |
| 44 [testCursorReadsAndRandomWrites, kReadDataToo, kDontUseIndex, kWriteToo], | 56 [testCursorReadsAndRandomWrites, kReadDataToo, kDontUseIndex, kWriteToo, |
| 57 kWriteDifferentStore], |
| 58 // Read a sequence of an object store via a cursor, writing |
| 59 // transformed values into another. |
| 60 [testCursorReadsAndRandomWrites, kReadDataToo, kDontUseIndex, kWriteToo, |
| 61 kWriteSameStore], |
| 45 // Read a sequence of an index into an object store via a cursor. | 62 // Read a sequence of an index into an object store via a cursor. |
| 46 [testCursorReadsAndRandomWrites, kReadDataToo, kUseIndex, kDontWrite], | 63 [testCursorReadsAndRandomWrites, kReadDataToo, kUseIndex, kDontWrite, |
| 64 kPlaceholderArg], |
| 47 // Read a sequence of an index into an object store via a key cursor. | 65 // Read a sequence of an index into an object store via a key cursor. |
| 48 [testCursorReadsAndRandomWrites, kReadKeysOnly, kUseIndex, kDontWrite], | 66 [testCursorReadsAndRandomWrites, kReadKeysOnly, kUseIndex, kDontWrite, |
| 67 kPlaceholderArg], |
| 49 // Make batches of random writes into a store, triggered by periodic setTimeout | 68 // Make batches of random writes into a store, triggered by periodic setTimeout |
| 50 // calls. | 69 // calls. |
| 51 [testSporadicWrites, 5, 0], | 70 [testSporadicWrites, 5, 0], |
| 52 // Make large batches of random writes into a store, triggered by periodic | 71 // Make large batches of random writes into a store, triggered by periodic |
| 53 // setTimeout calls. | 72 // setTimeout calls. |
| 54 [testSporadicWrites, 50, 0], | 73 [testSporadicWrites, 50, 0], |
| 55 // Make batches of random writes into a store with many indices, triggered by | 74 // Make batches of random writes into a store with many indices, triggered by |
| 56 // periodic setTimeout calls. | 75 // periodic setTimeout calls. |
| 57 [testSporadicWrites, 5, 10], | 76 [testSporadicWrites, 5, 10], |
| 58 // Make large batches of random writes into a store with many indices, triggered | 77 // Make large batches of random writes into a store with many indices, triggered |
| (...skipping 20 matching lines...) Expand all Loading... |
| 79 onAllTestsComplete(); | 98 onAllTestsComplete(); |
| 80 } | 99 } |
| 81 } | 100 } |
| 82 | 101 |
| 83 function onAllTestsComplete() { | 102 function onAllTestsComplete() { |
| 84 var overallDuration = Date.now() - overallTestStartTime; | 103 var overallDuration = Date.now() - overallTestStartTime; |
| 85 automation.addResult("OverallTestDuration", overallDuration); | 104 automation.addResult("OverallTestDuration", overallDuration); |
| 86 automation.setDone(); | 105 automation.setDone(); |
| 87 } | 106 } |
| 88 | 107 |
| 108 // This is the only test that includes database creation and deletion in its |
| 109 // results; the others just test specific operations. To see only the |
| 110 // creation/deletion without the specific operations used to build up the data |
| 111 // in the object stores here, subtract off the results of |
| 112 // testCreateKeysInStores. |
| 113 function testCreateAndDeleteDatabase( |
| 114 numKeys, numStores, payloadLength, onTestComplete) { |
| 115 var testName = getDisplayName(arguments); |
| 116 assert(numKeys >= 0); |
| 117 assert(numStores >= 1); |
| 118 var objectStoreNames = []; |
| 119 for (var i=0; i < numStores; ++i) { |
| 120 objectStoreNames.push("store " + i); |
| 121 } |
| 122 var value = stringOfLength(payloadLength); |
| 123 function getValue() { |
| 124 return value; |
| 125 } |
| 126 |
| 127 automation.setStatus("Creating database."); |
| 128 var startTime = Date.now(); |
| 129 |
| 130 createDatabase(testName, objectStoreNames, onCreated, onError); |
| 131 |
| 132 function onCreated(db) { |
| 133 automation.setStatus("Constructing transaction."); |
| 134 var transaction = |
| 135 getTransaction(db, objectStoreNames, "readwrite", |
| 136 function() { onValuesWritten(db); }); |
| 137 putLinearValues(transaction, objectStoreNames, numKeys, null, getValue); |
| 138 } |
| 139 |
| 140 function onValuesWritten(db) { |
| 141 automation.setStatus("Deleting database."); |
| 142 db.close(); |
| 143 deleteDatabase(testName, onDeleted); |
| 144 } |
| 145 |
| 146 function onDeleted() { |
| 147 var duration = Date.now() - startTime; |
| 148 automation.addResult(testName, duration); |
| 149 automation.setStatus("Deleted database."); |
| 150 onTestComplete(); |
| 151 } |
| 152 } |
| 153 |
| 89 function testCreateKeysInStores( | 154 function testCreateKeysInStores( |
| 90 numKeys, numStores, payloadLength, onTestComplete) { | 155 numKeys, numStores, payloadLength, onTestComplete) { |
| 91 var testName = getDisplayName(arguments); | 156 var testName = getDisplayName(arguments); |
| 92 assert(numKeys >= 0); | 157 assert(numKeys >= 0); |
| 93 assert(numStores >= 1); | 158 assert(numStores >= 1); |
| 94 var objectStoreNames = []; | 159 var objectStoreNames = []; |
| 95 for (var i=0; i < numStores; ++i) { | 160 for (var i=0; i < numStores; ++i) { |
| 96 objectStoreNames.push("store " + i); | 161 objectStoreNames.push("store " + i); |
| 97 } | 162 } |
| 98 var value = stringOfLength(payloadLength); | 163 var value = stringOfLength(payloadLength); |
| 99 function getValue() { | 164 function getValue() { |
| 100 return value; | 165 return value; |
| 101 } | 166 } |
| 102 | 167 |
| 103 automation.setStatus("Creating database."); | 168 automation.setStatus("Creating database."); |
| 104 createDatabase(testName, objectStoreNames, onCreated, onError); | 169 createDatabase(testName, objectStoreNames, onCreated, onError); |
| 105 | 170 |
| 106 function onCreated(db) { | 171 function onCreated(db) { |
| 107 automation.setStatus("Constructing transaction."); | 172 automation.setStatus("Constructing transaction."); |
| 108 var completionFunc = | 173 var completionFunc = |
| 109 getCompletionFunc(testName, Date.now(), onTestComplete); | 174 getCompletionFunc(db, testName, Date.now(), onTestComplete); |
| 110 var transaction = | 175 var transaction = |
| 111 getTransaction(db, objectStoreNames, "readwrite", completionFunc); | 176 getTransaction(db, objectStoreNames, "readwrite", completionFunc); |
| 112 putLinearValues(transaction, objectStoreNames, numKeys, null, getValue); | 177 putLinearValues(transaction, objectStoreNames, numKeys, null, getValue); |
| 113 } | 178 } |
| 114 } | 179 } |
| 115 | 180 |
| 116 function testRandomReadsAndWrites( | 181 function testRandomReadsAndWrites( |
| 117 numKeys, numReadsPerTransaction, numWritesPerTransaction, numTransactions, | 182 numKeys, numReadsPerTransaction, numWritesPerTransaction, numTransactions, |
| 118 useIndexForReads, onTestComplete) { | 183 useIndexForReads, onTestComplete) { |
| 119 var indexName; | 184 var indexName; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 140 automation.setStatus("Setting up test database."); | 205 automation.setStatus("Setting up test database."); |
| 141 var transaction = getTransaction(db, objectStoreNames, "readwrite", | 206 var transaction = getTransaction(db, objectStoreNames, "readwrite", |
| 142 function() { onSetupComplete(db); }); | 207 function() { onSetupComplete(db); }); |
| 143 putLinearValues(transaction, objectStoreNames, numKeys, null, | 208 putLinearValues(transaction, objectStoreNames, numKeys, null, |
| 144 function () { return "test value"; }); | 209 function () { return "test value"; }); |
| 145 } | 210 } |
| 146 | 211 |
| 147 var completionFunc; | 212 var completionFunc; |
| 148 function onSetupComplete(db) { | 213 function onSetupComplete(db) { |
| 149 automation.setStatus("Setup complete."); | 214 automation.setStatus("Setup complete."); |
| 150 completionFunc = getCompletionFunc(testName, Date.now(), onTestComplete); | 215 completionFunc = |
| 216 getCompletionFunc(db, testName, Date.now(), onTestComplete); |
| 151 runOneBatch(db); | 217 runOneBatch(db); |
| 152 } | 218 } |
| 153 | 219 |
| 154 function runOneBatch(db) { | 220 function runOneBatch(db) { |
| 155 if (numTransactionsLeft <= 0) { | 221 if (numTransactionsLeft <= 0) { |
| 156 return; | 222 return; |
| 157 } | 223 } |
| 158 --numTransactionsLeft; | 224 --numTransactionsLeft; |
| 159 ++numTransactionsRunning; | 225 ++numTransactionsRunning; |
| 160 var mode = "readonly"; | 226 var mode = "readonly"; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 }; | 271 }; |
| 206 alterObjectStores(testName, objectStoreNames, f, onIndexCreated, onError); | 272 alterObjectStores(testName, objectStoreNames, f, onIndexCreated, onError); |
| 207 } | 273 } |
| 208 | 274 |
| 209 var completionFunc; | 275 var completionFunc; |
| 210 function onIndexCreated(db) { | 276 function onIndexCreated(db) { |
| 211 db.close(); | 277 db.close(); |
| 212 var indexCreationCompleteTime = Date.now(); | 278 var indexCreationCompleteTime = Date.now(); |
| 213 automation.addResult("testCreateIndex", | 279 automation.addResult("testCreateIndex", |
| 214 indexCreationCompleteTime - startTime); | 280 indexCreationCompleteTime - startTime); |
| 215 completionFunc = getCompletionFunc("testDeleteIndex", | 281 completionFunc = getCompletionFunc(db, "testDeleteIndex", |
| 216 indexCreationCompleteTime, onTestComplete); | 282 indexCreationCompleteTime, onTestComplete); |
| 217 var f = function(objectStore) { | 283 var f = function(objectStore) { |
| 218 objectStore.deleteIndex("index"); | 284 objectStore.deleteIndex("index"); |
| 219 }; | 285 }; |
| 220 automation.setStatus("Deleting index."); | 286 automation.setStatus("Deleting index."); |
| 221 alterObjectStores(testName, objectStoreNames, f, completionFunc, onError); | 287 alterObjectStores(testName, objectStoreNames, f, completionFunc, onError); |
| 222 } | 288 } |
| 223 } | 289 } |
| 224 | 290 |
| 225 // TODO: Add a version that writes back to the same store, to see how that | |
| 226 // affects cursor speed w.r.t. invalidated caches. | |
| 227 function testCursorReadsAndRandomWrites( | 291 function testCursorReadsAndRandomWrites( |
| 228 readKeysOnly, useIndexForReads, writeToAnotherStore, onTestComplete) { | 292 readKeysOnly, useIndexForReads, writeAlso, sameStoreForWrites, |
| 293 onTestComplete) { |
| 229 // There's no key cursor unless you're reading from an index. | 294 // There's no key cursor unless you're reading from an index. |
| 230 assert(useIndexForReads || !readKeysOnly); | 295 assert(useIndexForReads || !readKeysOnly); |
| 231 // If we're writing to another store, having an index would constrain our | 296 // If we're writing to another store, having an index would constrain our |
| 232 // writes, as we create both object stores with the same configurations. | 297 // writes, as we create both object stores with the same configurations. |
| 233 // We could do that if needed, but it's simpler not to. | 298 // We could do that if needed, but it's simpler not to. |
| 234 assert(!useIndexForReads || !writeToAnotherStore); | 299 assert(!useIndexForReads || !writeAlso); |
| 235 var numKeys = 1000; | 300 var numKeys = 1000; |
| 236 var numReadsPerTransaction = 100; | 301 var numReadsPerTransaction = 100; |
| 237 var testName = getDisplayName(arguments); | 302 var testName = getDisplayName(arguments); |
| 238 var objectStoreNames = ["input store"]; | 303 var objectStoreNames = ["input store"]; |
| 239 if (writeToAnotherStore) | 304 var outputStoreName; |
| 240 objectStoreNames.push("output store"); | 305 if (writeAlso) { |
| 306 if (sameStoreForWrites) { |
| 307 outputStoreName = objectStoreNames[0]; |
| 308 } else { |
| 309 outputStoreName = "output store"; |
| 310 objectStoreNames.push(outputStoreName); |
| 311 } |
| 312 } |
| 241 var getKeyForRead = getSimpleKey; | 313 var getKeyForRead = getSimpleKey; |
| 242 var indexName; | 314 var indexName; |
| 243 if (useIndexForReads) { | 315 if (useIndexForReads) { |
| 244 indexName = "index"; | 316 indexName = "index"; |
| 245 getKeyForRead = function(i) { | 317 getKeyForRead = function(i) { |
| 246 // This depends on the implementations of getValuesFromCursor and | 318 // This depends on the implementations of getValuesFromCursor and |
| 247 // getObjectValue. We reverse the order of the iteration here so that | 319 // getObjectValue. We reverse the order of the iteration here so that |
| 248 // setting up bounds from k to k+n with n>0 works. Without this reversal, | 320 // setting up bounds from k to k+n with n>0 works. Without this reversal, |
| 249 // the upper bound is below the lower bound. | 321 // the upper bound is below the lower bound. |
| 250 return getBackwardIndexKey(numKeys - i); | 322 return getBackwardIndexKey(numKeys - i); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 266 function onCreated(db) { | 338 function onCreated(db) { |
| 267 automation.setStatus("Setting up test database."); | 339 automation.setStatus("Setting up test database."); |
| 268 var transaction = getTransaction(db, objectStoreNames, "readwrite", | 340 var transaction = getTransaction(db, objectStoreNames, "readwrite", |
| 269 function() { onSetupComplete(db); }); | 341 function() { onSetupComplete(db); }); |
| 270 putLinearValues(transaction, objectStoreNames, numKeys, getSimpleKey, | 342 putLinearValues(transaction, objectStoreNames, numKeys, getSimpleKey, |
| 271 getObjectValue); | 343 getObjectValue); |
| 272 } | 344 } |
| 273 function onSetupComplete(db) { | 345 function onSetupComplete(db) { |
| 274 automation.setStatus("Setup complete."); | 346 automation.setStatus("Setup complete."); |
| 275 var completionFunc = | 347 var completionFunc = |
| 276 getCompletionFunc(testName, Date.now(), onTestComplete); | 348 getCompletionFunc(db, testName, Date.now(), onTestComplete); |
| 277 var mode = "readonly"; | 349 var mode = "readonly"; |
| 278 if (writeToAnotherStore) | 350 if (writeAlso) |
| 279 mode = "readwrite"; | 351 mode = "readwrite"; |
| 280 var transaction = | 352 var transaction = |
| 281 getTransaction(db, objectStoreNames, mode, completionFunc); | 353 getTransaction(db, objectStoreNames, mode, completionFunc); |
| 282 | 354 |
| 283 getValuesFromCursor( | 355 getValuesFromCursor( |
| 284 transaction, objectStoreNames[0], numReadsPerTransaction, numKeys, | 356 transaction, objectStoreNames[0], numReadsPerTransaction, numKeys, |
| 285 indexName, getKeyForRead, readKeysOnly, objectStoreNames[1]); | 357 indexName, getKeyForRead, readKeysOnly, outputStoreName); |
| 286 } | 358 } |
| 287 } | 359 } |
| 288 | 360 |
| 289 function testSporadicWrites( | 361 function testSporadicWrites( |
| 290 numWritesPerTransaction, numIndices, onTestComplete) { | 362 numWritesPerTransaction, numIndices, onTestComplete) { |
| 291 var numKeys = 1000; | 363 var numKeys = 1000; |
| 292 // With 30 transactions, spaced 50ms apart, we'll need at least 1.5s. | 364 // With 30 transactions, spaced 50ms apart, we'll need at least 1.5s. |
| 293 var numTransactions = 30; | 365 var numTransactions = 30; |
| 294 var delayBetweenBatches = 50; | 366 var delayBetweenBatches = 50; |
| 295 var indexName; | 367 var indexName; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 317 function onCreated(db) { | 389 function onCreated(db) { |
| 318 automation.setStatus("Setting up test database."); | 390 automation.setStatus("Setting up test database."); |
| 319 var transaction = getTransaction(db, objectStoreNames, "readwrite", | 391 var transaction = getTransaction(db, objectStoreNames, "readwrite", |
| 320 function() { onSetupComplete(db); }); | 392 function() { onSetupComplete(db); }); |
| 321 putLinearValues(transaction, objectStoreNames, numKeys, getSimpleKey, | 393 putLinearValues(transaction, objectStoreNames, numKeys, getSimpleKey, |
| 322 getValue); | 394 getValue); |
| 323 } | 395 } |
| 324 var completionFunc; | 396 var completionFunc; |
| 325 function onSetupComplete(db) { | 397 function onSetupComplete(db) { |
| 326 automation.setStatus("Setup complete."); | 398 automation.setStatus("Setup complete."); |
| 327 completionFunc = getCompletionFunc(testName, Date.now(), onTestComplete); | 399 completionFunc = |
| 400 getCompletionFunc(db, testName, Date.now(), onTestComplete); |
| 328 runOneBatch(db); | 401 runOneBatch(db); |
| 329 } | 402 } |
| 330 | 403 |
| 331 function runOneBatch(db) { | 404 function runOneBatch(db) { |
| 332 assert(numTransactionsLeft); | 405 assert(numTransactionsLeft); |
| 333 if (--numTransactionsLeft) { | 406 if (--numTransactionsLeft) { |
| 334 setTimeout(function () { runOneBatch(db); }, delayBetweenBatches); | 407 setTimeout(function () { runOneBatch(db); }, delayBetweenBatches); |
| 335 } | 408 } |
| 336 ++numTransactionsRunning; | 409 ++numTransactionsRunning; |
| 337 | 410 |
| 338 function batchComplete() { | 411 function batchComplete() { |
| 339 assert(numTransactionsRunning); | 412 assert(numTransactionsRunning); |
| 340 if (!--numTransactionsRunning && !numTransactionsLeft) | 413 if (!--numTransactionsRunning && !numTransactionsLeft) |
| 341 completionFunc(); | 414 completionFunc(); |
| 342 } | 415 } |
| 343 | 416 |
| 344 var mode = "readonly"; | 417 var mode = "readonly"; |
| 345 if (numWritesPerTransaction) | 418 if (numWritesPerTransaction) |
| 346 mode = "readwrite"; | 419 mode = "readwrite"; |
| 347 | 420 |
| 348 var transaction = getTransaction(db, objectStoreNames, mode, batchComplete); | 421 var transaction = getTransaction(db, objectStoreNames, mode, batchComplete); |
| 349 putRandomValues(transaction, objectStoreNames, numWritesPerTransaction, | 422 putRandomValues(transaction, objectStoreNames, numWritesPerTransaction, |
| 350 numKeys); | 423 numKeys); |
| 351 } | 424 } |
| 352 } | 425 } |
| OLD | NEW |