Bug 844558 - Send contacts from parent to child in chunks. r=gwagner

--HG--
extra : rebase_source : 928477208d46757a64ab337dd9f1448790ac7f32
This commit is contained in:
Reuben Morais 2013-02-23 03:41:41 -08:00
parent bf88fdb64b
commit 8e8194cdc1
3 changed files with 39 additions and 21 deletions

View File

@ -398,6 +398,10 @@ ContactManager.prototype = {
}
},
_pushArray: function(aArr1, aArr2) {
aArr1.push.apply(aArr1, aArr2);
},
receiveMessage: function(aMessage) {
if (DEBUG) debug("receiveMessage: " + aMessage.name);
let msg = aMessage.json;
@ -416,14 +420,16 @@ ContactManager.prototype = {
break;
case "Contacts:GetAll:Next":
let data = this._cursorData[msg.cursorId];
let contact = msg.contact ? this._convertContact(msg.contact) : null;
let result = contacts ? this._convertContacts(contacts) : [null];
if (data.waitingForNext) {
if (DEBUG) debug("cursor waiting for contact, sending");
data.waitingForNext = false;
let contact = result.shift();
this._pushArray(data.cachedContacts, result);
this._fireSuccessOrDone(data.cursor, contact);
} else {
if (DEBUG) debug("cursor not waiting, saving");
data.cachedContacts.push(contact);
this._pushArray(data.cachedContacts, result);
}
break;
case "Contacts:GetSimContacts:Return:OK":
@ -637,7 +643,8 @@ ContactManager.prototype = {
let data = this._cursorData[aCursorId];
if (data.cachedContacts.length > 0) {
if (DEBUG) debug("contact in cache");
this._fireSuccessOrDone(data.cursor, data.cachedContacts.shift());
let contact = data.cachedContacts.shift();
this._fireSuccessOrDone(data.cursor, contact);
} else {
if (DEBUG) debug("waiting for contact");
data.waitingForNext = true;

View File

@ -16,11 +16,13 @@ const Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
const DB_NAME = "contacts";
const DB_VERSION = 8;
const STORE_NAME = "contacts";
const SAVED_GETALL_STORE_NAME = "getallcache";
const CHUNK_SIZE = 20;
this.ContactDB = function ContactDB(aGlobal) {
if (DEBUG) debug("Constructor");
@ -503,7 +505,6 @@ ContactDB.prototype = {
req.onsuccess = function(e) {
if (e.target.result) {
if (DEBUG) debug("cache exists");
debug("sending: " + JSON.stringify(e.target.result));
aSuccessCb(e.target.result, false);
} else {
if (DEBUG) debug("creating cache for query " + aQuery);
@ -517,6 +518,7 @@ ContactDB.prototype = {
},
getAll: function CDB_getAll(aSuccessCb, aFailureCb, aOptions) {
if (DEBUG) debug("getAll")
let optionStr = JSON.stringify(aOptions);
this.getCacheForQuery(optionStr, function(aCachedResults, aFullContacts) {
// aFullContacts is true if the cache didn't exist and had to be created.
@ -524,26 +526,35 @@ ContactDB.prototype = {
// in memory to create the cache anyway. This allows us to avoid accessing
// the main object store again.
if (aCachedResults && aCachedResults.length > 0) {
if (DEBUG) debug("query returned at least one contact");
if (DEBUG) debug("query returned " + aCachedResults.length + " contacts");
if (aFullContacts) {
if (DEBUG) debug("full contacts: " + aCachedResults.length);
for (let i = 0; i < aCachedResults.length; ++i) {
aSuccessCb(aCachedResults[i]);
while(aCachedResults.length) {
aSuccessCb(aCachedResults.splice(0, CHUNK_SIZE));
}
aSuccessCb(null);
} else {
let count = 0;
this.newTxn("readonly", STORE_NAME, function(txn, store) {
for (let i = 0; i < aCachedResults.length; ++i) {
store.get(aCachedResults[i]).onsuccess = function(e) {
aSuccessCb(e.target.result);
count++;
if (count == aCachedResults.length) {
aSuccessCb(null);
}
};
}
});
let sendChunk = function(start) {
let chunk = [];
this.newTxn("readonly", STORE_NAME, function(txn, store) {
for (let i = start; i < Math.min(start+CHUNK_SIZE, aCachedResults.length); ++i) {
store.get(aCachedResults[i]).onsuccess = function(e) {
chunk.push(e.target.result);
count++;
if (count == aCachedResults.length) {
aSuccessCb(chunk);
aSuccessCb(null);
} else if (chunk.length == CHUNK_SIZE) {
aSuccessCb(chunk);
chunk.length = 0;
setTimeout(sendChunk.bind(this, start+CHUNK_SIZE), 0);
}
};
}
});
}.bind(this);
sendChunk(0);
}
} else { // no contacts
if (DEBUG) debug("query returned no contacts");

View File

@ -111,11 +111,11 @@ this.DOMContactManager = {
return null;
}
this._db.getAll(
function(aContact) {
mm.sendAsyncMessage("Contacts:GetAll:Next", {cursorId: msg.cursorId, contact: aContact});
function(aContacts) {
mm.sendAsyncMessage("Contacts:GetAll:Next", {cursorId: msg.cursorId, contacts: aContacts});
},
function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Find:Return:KO", { errorMsg: aErrorMsg }); },
msg.findOptions, msg.cursorId);
msg.findOptions);
break;
case "Contact:Save":
if (msg.options.reason === "create") {