Commit a5c95824 authored by ericu@google.com's avatar ericu@google.com

Add IDB perf tests for random read, with and without an index.

BUG=137764
TEST=self

Review URL: https://chromiumcodereview.appspot.com/10790041

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148630 0039d316-1c4b-4281-b951-d872f2087c98
parent 15dd901f
......@@ -40,51 +40,65 @@ function assert(t) {
}
function onError(e) {
console.log(e);
var s = "Caught error.";
if (e.target && e.target.webkitErrorMessage)
s += "\n" + e.target.webkitErrorMessage;
console.log(s);
automation.setStatus(s);
e.stopPropagation();
throw new Error(e);
}
var version = 2; // The version with our object stores.
var db;
function createDatabase(name, objectStores, handler, errorHandler) {
// Valid options fields:
// indexName: the name of an index to create on each object store
// indexKeyPath: likewise
// indexIsUnique: the "unique" option for IDBIndexParameters
// indexIsMultiEntry: the "multiEntry" option for IDBIndexParameters
//
function createDatabase(
name, objectStoreNames, handler, errorHandler, options) {
var openRequest = indexedDB.open(name, version);
openRequest.onblocked = errorHandler;
function createObjectStores(db) {
for (var store in objectStores) {
var name = objectStores[store];
for (var store in objectStoreNames) {
var name = objectStoreNames[store];
assert(!db.objectStoreNames.contains(name));
db.createObjectStore(name);
var os = db.createObjectStore(name);
if (options && options.indexName) {
assert('indexKeyPath' in options);
os.createIndex(options.indexName, options.indexKeyPath,
{ unique: options.indexIsUnique,
multiEntry: options.indexIsMultiEntry });
}
}
}
openRequest.onupgradeneeded = function(ev) {
// TODO: This is the spec-compliant path, which doesn't yet work in Chrome,
// and isn't yet tested, as this function won't currently be called.
assert(openRequest == ev.target);
db = openRequest.result;
createObjectStores(db);
createObjectStores(openRequest.result);
// onsuccess will get called after this exits.
};
openRequest.onsuccess = function(ev) {
assert(openRequest == ev.target);
db = openRequest.result;
var db = openRequest.result;
db.onerror = function(ev) {
console.log("db error", arguments, openRequest.webkitErrorMessage);
errorHandler();
}
};
if (db.version != version) {
// This is the current Chrome path.
var setVersionRequest = db.setVersion(version);
setVersionRequest.onfailure = errorHandler;
setVersionRequest.onsuccess =
function(e) {
assert(setVersionRequest == e.target);
createObjectStores(db);
var versionTransaction = setVersionRequest.result;
versionTransaction.oncomplete = function() {handler(db); };
versionTransaction.onerror = onError;
}
setVersionRequest.onsuccess = function(e) {
assert(setVersionRequest == e.target);
createObjectStores(db);
var versionTransaction = setVersionRequest.result;
versionTransaction.oncomplete = function() {handler(db); };
versionTransaction.onerror = onError;
};
} else {
handler(db);
}
......@@ -109,10 +123,19 @@ function deleteDatabase(name, opt_handler) {
}
}
function cleanUp(opt_handler) {
if (db) {
deleteDatabase(db, opt_handler);
db = null;
function getCompletionFunc(testName, startTime, onTestComplete) {
function onDeleted() {
automation.setStatus("Deleted database.");
onTestComplete();
}
return function() {
var duration = Date.now() - startTime;
// Ignore the cleanup time for this test.
automation.addResult(testName, duration);
automation.setStatus("Deleting database.");
// TODO: Turn on actual deletion; for now it's way too slow.
// deleteDatabase(testName, onDeleted);
onTestComplete();
}
}
......
......@@ -15,41 +15,123 @@ function testCreateKeysInStores(
objectStoreNames.push("store " + i);
}
var value = stringOfLength(payloadLength);
var start;
function onCreated(db) {
automation.setStatus("Constructing transaction.");
start = Date.now(); // Ignore the setup time for this test.
var completionFunc =
getCompletionFunc(testName, Date.now(), onTestComplete);
var transaction = getTransaction(db, objectStoreNames, "readwrite",
function() { onTransactionComplete(db); });
function() { completionFunc(); });
for (var i in objectStoreNames) {
var os = transaction.objectStore(objectStoreNames[i]);
assert(os);
for (var j = 0; j < numKeys; ++j) {
os.put("key " + j, value);
os.put(value, "key " + j);
}
}
}
function onTransactionComplete(db) {
var duration = Date.now() - start;
// Ignore the cleanup time for this test.
automation.addResult(testName, duration);
automation.setStatus("Deleting.");
deleteDatabase(db, onDeleted);
automation.setStatus("Creating database.");
createDatabase(testName, objectStoreNames, onCreated, onError);
}
function testRandomReads(numKeys, numReadsPerTransaction, numTransactions,
useIndex, onTestComplete) {
var indexText = "_bare";
var indexName;
if (useIndex) {
indexText = "_index";
indexName = "index";
}
function onDeleted() {
automation.setStatus("Deleted.");
onTestComplete();
var testName = "testRandomReads_" + numKeys + "_" + numReadsPerTransaction +
"_" + numTransactions + indexText;
var numTransactionsLeft = numTransactions;
var storeName = "store";
var objectStoreNames = [storeName];
var numTransactionsRunning;
function getKey(i) {
return "key " + i;
}
automation.setStatus("Creating.");
createDatabase(testName, objectStoreNames, onCreated, onError);
function getValue(i) {
return "value " + i;
}
function onCreated(db) {
automation.setStatus("Setting up test database.");
var transaction = getTransaction(db, objectStoreNames, "readwrite",
function() { onSetupComplete(db); });
var os = transaction.objectStore(storeName);
assert(os);
for (var j = 0; j < numKeys; ++j) {
os.put(getValue(i), getKey(j));
}
}
var completionFunc;
function onSetupComplete(db) {
automation.setStatus("Setup complete.");
runOneBatch(db);
completionFunc = getCompletionFunc(testName, Date.now(), onTestComplete);
}
function runOneBatch(db) {
if (numTransactionsLeft <= 0) {
return;
}
--numTransactionsLeft;
++numTransactionsRunning;
var valuesToRead = numReadsPerTransaction;
var transaction = getTransaction(db, objectStoreNames, "readonly",
function() {
assert(!--numTransactionsRunning);
assert(!valuesToRead);
if (numTransactionsLeft <= 0) {
completionFunc();
} else {
runOneBatch(db);
}
});
var queryObject = transaction.objectStore(storeName);
if (useIndex) {
queryObject = queryObject.index(indexName);
}
assert(queryObject);
for (var i = 0; i < numReadsPerTransaction; ++i) {
var rand = Math.floor(Math.random() * numKeys);
var request = queryObject.get(getKey(rand));
request.onerror = onError;
request.onsuccess = function () {
assert(valuesToRead--);
}
}
}
automation.setStatus("Creating database.");
var options = {};
if (useIndex) {
options.indexName = indexName;
options.indexKeyPath = "";
options.indexIsUnique = true;
options.indexIsMultiEntry = false;
}
createDatabase(testName, objectStoreNames, onCreated, onError, options);
}
var kUseIndex = true;
var kDontUseIndex = false;
var tests = [
[testCreateKeysInStores, 1, 1, 1],
[testCreateKeysInStores, 100, 1, 1],
[testCreateKeysInStores, 1, 100, 1],
[testCreateKeysInStores, 100, 1, 100000]
[testCreateKeysInStores, 1, 1, 1],
[testCreateKeysInStores, 100, 1, 1],
[testCreateKeysInStores, 1, 100, 1],
[testCreateKeysInStores, 100, 1, 10000],
[testRandomReads, 1000, 5, 50, kDontUseIndex],
[testRandomReads, 1000, 50, 5, kDontUseIndex],
[testRandomReads, 5000, 50, 5, kDontUseIndex],
[testRandomReads, 1000, 5, 50, kUseIndex],
[testRandomReads, 1000, 50, 5, kUseIndex],
[testRandomReads, 5000, 50, 5, kUseIndex]
];
var currentTest = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment