From 1d5a41092ee9a3a5c3a89a04a9f4a85c672637cf Mon Sep 17 00:00:00 2001
From: Amanda Ghassaei <amandaghassaei@gmail.com>
Date: Mon, 12 Jan 2015 17:04:52 -0500
Subject: [PATCH] task are deallocated after they are finished

---
 js/main.js              |  8 +++--
 js/persistentWorkers.js | 67 +++++++++++++++++++++++++++++------------
 2 files changed, 53 insertions(+), 22 deletions(-)

diff --git a/js/main.js b/js/main.js
index 23b22303..b21a8993 100644
--- a/js/main.js
+++ b/js/main.js
@@ -7,12 +7,16 @@ $(function(){
 
     three = Three();
     setupNavBar();
-    workers = persistentWorkers(4);
+    workers = persistentWorkers(8);
 
-    workers.map([11,12,13,14,15, 18, 30], executable, {});
+    workers.map([11,12], executable, {}, incrCallback);
 
     function executable(){
         return arg*arg;
     }
 
+    function incrCallback(result){
+        console.log(result);
+    }
+
 });
diff --git a/js/persistentWorkers.js b/js/persistentWorkers.js
index a269ffc8..289fb28b 100644
--- a/js/persistentWorkers.js
+++ b/js/persistentWorkers.js
@@ -17,55 +17,82 @@ function persistentWorkers(numWorkers){
     var workerURL = makeBlobURL(URL, myWorker);
     for (var i=0;i<numWorkers;i++){
         var worker = new Worker(workerURL);
-        worker.onmessage = workerCallback;
+        worker.onmessage = onMessage;
         worker.postMessage({url: document.location.toString()});
         allWorkers.push(worker);
     }
     URL.revokeObjectURL(workerURL);
 
-    function map(data, executable, env){
+    function map(data, executable, env, incrCallback){
 
         //save args in map queue
-        mapQueue.push({data:data, executable:executable, env:env, index:0});
+        mapQueue.push({data:data, executable:executable, env:env, index:0, incrCallback:incrCallback, finished:false, activeThreads:0});
 
         for (var i=0;i<allWorkers.length;i++){
             allWorkers[i].postMessage({isWorking:true});//ask workers if they are busy
         }
     }
 
-    function workerCallback(e){
+    function onMessage(e){
 
-        if (e.data.result) console.log(e.data.result);//handle result first
+        if (e.data.result){//handle result first
 
-        if (e.data.isWorking === false){
-            //get next work item off queue
+            //get current work item off queue
             if (mapQueue.length == 0) return;
-
             var currentTask = mapQueue[0];
-            var currentIndex = currentTask.index;
-            currentTask.index = currentTask.index+1;
+            currentTask.activeThreads--;//decrement active threads
 
-            //check that the index is not out of bounds
-            if (currentTask.data.length<=currentIndex){
+            currentTask.incrCallback(e.data.result);//incremental callback
+            if (currentTask.finished && currentTask.activeThreads == 0){
                 mapQueue.shift();//remove first element
-
-                e.data.result = null;//remove result so it doesn't get handled twice
-                workerCallback(e);//try again in case there is another item in the queue
-                return;
+                console.log("end of task");
             }
+        }
+
+        var nextTask = getNextTask(mapQueue[0], 0);
+        if (!nextTask) return;
+
+        var currentIndex = nextTask.index;
+        nextTask.index++;
+        //check that the index is not out of bounds
+        if (nextTask.data.length<=currentIndex){
+            nextTask.finished = true;
+
+            e.data.result = null;//remove result so it doesn't get handled twice
+            onMessage(e);//try again in case there is another item in the queue to start
+            return;
+        }
 
+        if (e.data.isWorking === false){
+            nextTask.activeThreads++;
             e.target.postMessage({
-                arg:currentTask.data[currentIndex],
-                localEnv:currentTask.env,
-                executable:currentTask.executable.toString()});
+                arg:nextTask.data[currentIndex],
+                localEnv:nextTask.env,
+                executable:nextTask.executable.toString()});
+        }
+    }
+
+    function getNextTask(currentTask, index){
+        if (!currentTask) return null;
+        if (currentTask.finished){
+            var nextIndex = index+1;
+            if (mapQueue.length<=nextIndex) return null;
+            return getNextTask(mapQueue[nextIndex]);
+        } else {
+            return currentTask;
         }
     }
 
+
+    function incrementalCallback(){
+
+    }
+
     function makeBlobURL(URL, someFunction) {
         var blob = new Blob(["(" + someFunction.toString() + ")()"], { type: "text/javascript" });
         return URL.createObjectURL(blob);
     }
 
-    return {map:map}//return all public methods and vars
+    return {map:map};//return all public methods and vars
 
 }
\ No newline at end of file
-- 
GitLab