Mercurial > browser-couch
changeset 37:cf2122f596c8
Separated mapReduce() into separate map() and reduce() functions.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Tue, 14 Apr 2009 09:09:57 -0700 |
parents | ca803032d3c4 |
children | 44005d894d1b |
files | browser-couch.js |
diffstat | 1 files changed, 81 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/browser-couch.js Tue Apr 14 08:55:23 2009 -0700 +++ b/browser-couch.js Tue Apr 14 09:09:57 2009 -0700 @@ -271,12 +271,37 @@ if (!options.finished) throw new Error('finished callback not provided'); - BrowserCouch._mapReduce(options.map, - options.reduce, - dict, - options.progress, - options.finished, - options.chunkSize); + // Maximum number of items to process before giving the UI a chance + // to breathe. + var DEFAULT_CHUNK_SIZE = 1000; + + // If no progress callback is given, we'll automatically give the + // UI a chance to breathe for this many milliseconds before continuing + // processing. + var DEFAULT_UI_BREATHE_TIME = 50; + + var chunkSize = options.chunkSize; + if (!chunkSize) + chunkSize = DEFAULT_CHUNK_SIZE; + + var progress = options.progress; + if (!progress) + progress = function defaultProgress(phase, percent, resume) { + window.setTimeout(resume, DEFAULT_UI_BREATHE_TIME); + }; + + BrowserCouch._map( + options.map, + dict, + progress, + chunkSize, + function(mapDict) { + BrowserCouch._reduce(options.reduce, + mapDict, + progress, + chunkSize, + options.finished); + }); }; storage.get( @@ -288,12 +313,10 @@ }); }, - _mapReduce: function BC__mapReduce(map, reduce, dict, progress, - finished, chunkSize) { + _map: function BC__map(map, dict, progress, + chunkSize, finished) { var mapDict = {}; - var mapKeys = []; var keys = dict.getKeys(); - var rows = []; var currDoc; function emit(key, value) { @@ -301,25 +324,12 @@ // an indexable value. We may have to hash the value, // though, if it's e.g. an Object. var item = mapDict[key]; - if (!item) { - mapKeys.push(key); + if (!item) item = mapDict[key] = {keys: [], values: []}; - } item.keys.push(currDoc.id); item.values.push(value); } - // Maximum number of items to process before giving the UI a chance - // to breathe. - var DEFAULT_CHUNK_SIZE = 1000; - - // If no progress callback is given, we'll automatically give the - // UI a chance to breathe for this many milliseconds before continuing - // processing. - var DEFAULT_UI_BREATHE_TIME = 50; - - if (!chunkSize) - chunkSize = DEFAULT_CHUNK_SIZE; var i = 0; function continueMap() { @@ -333,66 +343,64 @@ i < keys.length) if (i == keys.length) - doReduce(); - else { - if (progress) - progress("map", i / keys.length, continueMap); - else - window.setTimeout(continueMap, DEFAULT_UI_BREATHE_TIME); - } + finished(mapDict); + else + progress("map", i / keys.length, continueMap); } continueMap(); - - function doReduce() { - mapKeys.sort(); - - if (reduce) { - var i = 0; + }, - function continueReduce() { - var iAtStart = i; - - do { - var key = mapKeys[i]; - var item = mapDict[key]; + _reduce: function BC__reduce(reduce, mapDict, progress, + chunkSize, finished) { + var rows = []; + var mapKeys = []; + for (name in mapDict) + mapKeys.push(name); - // TODO: The map() method is only available on JS 1.6. - var keys = item.keys.map(function pairKeyWithDocId(docId) { - return [key, docId]; - }); - rows.push({key: key, - value: reduce(keys, item.values)}); - i++; - } while (i - iAtStart < chunkSize && - i < mapKeys.length) + mapKeys.sort(); + + if (reduce) { + var i = 0; - if (i == mapKeys.length) - doneWithReduce(); - else { - if (progress) - progress("reduce", i / mapKeys.length, continueReduce); - else - window.setTimeout(continueReduce, DEFAULT_UI_BREATHE_TIME); - } - } + function continueReduce() { + var iAtStart = i; - continueReduce(); - } else { - for (i = 0; i < mapKeys.length; i++) { + do { var key = mapKeys[i]; var item = mapDict[key]; - for (var j = 0; j < item.keys.length; j++) { - var id = item.keys[j]; - var value = item.values[j]; - rows.push({id: id, - key: key, - value: value}); - } + + // TODO: The map() method is only available on JS 1.6. + var keys = item.keys.map(function pairKeyWithDocId(docId) { + return [key, docId]; + }); + rows.push({key: key, + value: reduce(keys, item.values)}); + i++; + } while (i - iAtStart < chunkSize && + i < mapKeys.length) + + if (i == mapKeys.length) + doneWithReduce(); + else + progress("reduce", i / mapKeys.length, continueReduce); + } + + continueReduce(); + } else { + for (i = 0; i < mapKeys.length; i++) { + var key = mapKeys[i]; + var item = mapDict[key]; + for (var j = 0; j < item.keys.length; j++) { + var id = item.keys[j]; + var value = item.values[j]; + rows.push({id: id, + key: key, + value: value}); } + } - doneWithReduce(); - } + doneWithReduce(); } function doneWithReduce() {