aboutsummaryrefslogtreecommitdiff
path: root/src/enzymatic.js
diff options
context:
space:
mode:
authoralon@honor <none@none>2010-09-15 21:00:26 -0700
committeralon@honor <none@none>2010-09-15 21:00:26 -0700
commit9b369c6e57ad1f7a5f47c0198573c89aa9255d22 (patch)
tree3151804fecc13fd1e6c9edc9e61353af027b7284 /src/enzymatic.js
parent92fac9b713e3b13e5a77af2e1c89bd75040af550 (diff)
rewrite enzymatic, compilation is x2.5 faster
Diffstat (limited to 'src/enzymatic.js')
-rw-r--r--src/enzymatic.js160
1 files changed, 67 insertions, 93 deletions
diff --git a/src/enzymatic.js b/src/enzymatic.js
index c2c7979e..bb4458fe 100644
--- a/src/enzymatic.js
+++ b/src/enzymatic.js
@@ -7,29 +7,40 @@ DEBUG = false;
Substrate = function(name_) {
this.name_ = name_;
- this.items = [];
- this.zymes = [];
+ this.zymes = {};
this.currUid = 1;
};
Substrate.prototype = {
- addItem: function(item) {
- if (!item.__uid__) {
- item.__uid__ = this.currUid;
- this.currUid ++;
- }
- this.items.push(item);
+ addItem: function(item, targetZyme) {
+ this.addItems([item], targetZyme);
},
- addZyme: function(zyme) {
- var name_ = '?';
- if (typeof zyme == 'string') {
- name_ = zyme;
- zyme = arguments[1];
+ addItems: function(items, targetZyme) {
+ assert(targetZyme);
+ if (targetZyme == '/dev/null') return;
+ if (targetZyme == '/dev/stdout') {
+ this.results = this.results.concat(items);
+ return;
+ }
+ assert(this.zymes[targetZyme]);
+ for (var i = 0; i < items.length; i++) {
+ var item = items[i];
+ if (!item.__uid__) {
+ item.__uid__ = this.currUid;
+ this.currUid ++;
+ }
}
+ this.zymes[targetZyme].items = this.zymes[targetZyme].items.concat(items);
+ },
+
+ addZyme: function(name_, zyme) {
+ assert(name_ && zyme);
zyme.name_ = name_;
- this.zymes.push(zyme);
- if (!zyme.select) zyme.select = Zyme.prototype.select;
+ zyme.items = [];
+ zyme.forwardItem = bind(this, this.addItem);
+ zyme.forwardItems = bind(this, this.addItems);
+ this.zymes[name_] = zyme;
if (!zyme.process) zyme.process = Zyme.prototype.process;
},
@@ -42,7 +53,7 @@ Substrate.prototype = {
function midComment(force) {
var curr = Date.now();
if (curr - midTime > 1000 || force) {
- print('// Working on ' + that.name_ + ', so far ' + ((curr-startTime)/1000).toString().substr(0,10) + ' seconds. Have ' + that.items.length + ' items.');
+ print('// Working on ' + that.name_ + ', so far ' + ((curr-startTime)/1000).toString().substr(0,10) + ' seconds.');
midTime = curr;
}
}
@@ -50,111 +61,74 @@ Substrate.prototype = {
print('// Completed ' + that.name_ + ' in ' + ((Date.now() - startTime)/1000).toString().substr(0,10) + ' seconds.');
}
- // Naive solver - sheer brute force.
- // Assumes list of Zymes is non-changing.
- var results = [];
- while (true) {
- dprint('enzymatic', "Cycle start, " + this.items.length + " items.");
+ var finalResult = null;
+ this.results = [];
+ var finished = false;
+ var that = this;
+ while (!finished) {
+ dprint('enzymatic', "Cycle start, items: ");// + values(this.zymes).map(function(zyme) zyme.items).reduce(function(x,y) x+y, 0));
var hadProcessing = false;
- for (var z = 0; z < this.zymes.length; z++) {
+ values(this.zymes).forEach(function(zyme) {
midComment();
- var zyme = this.zymes[z];
- var selected = zyme.select(this.items);
- if (selected.length > 0) {
- if (DEBUG) print("Calling: " + (zyme.processItem ? zyme.processItem : zyme.process));
- if (DEBUG) {
- try {
- print("Inputs: \n---\n\n" + outputs.map(JSON.stringify).join('\n\n') + '\n\n---');
- } catch(e) {
- print("Inputs: \n---\n\n" + outputs + '\n\n---');
- }
- }
- hadProcessing = true;
- var outputs;
- try {
- dprint('Processing using ' + zyme.name_ + ': ' + selected.length + ' items out of ' + this.items.length);
- //PROF(true);
- outputs = zyme.process(selected);
- //PROF();
- } catch (e) {
- print("Exception, current selected are: " + selected.map(dump).join('\n\n'));
- print("Stack: " + dump(new Error().stack));
- throw e;
- }
- if (DEBUG) {
- try {
- print("Outputs: \n---\n\n" + outputs.map(JSON.stringify).join('\n\n') + '\n\n---');
- } catch(e) {
- print("Outputs: \n---\n\n" + outputs + '\n\n---');
- }
- }
+
+ if (zyme.items.length == 0) return;
+
+ var inputs = zyme.items.slice(0);
+ var outputs;
+ var currResultCount = that.results.length;
+ try {
+ dprint('Processing using ' + zyme.name_ + ': ' + inputs.length);
+ zyme.items = []; // More may be added in process(); we'll get to them next time
+ outputs = zyme.process(inputs);
+ dprint('New results: ' + (outputs.length + that.results.length - currResultCount) + ' out of ' + (that.results.length + outputs.length));
+ } catch (e) {
+ print("Exception, current selected are: " + inputs.map(dump).join('\n\n'));
+ print("Stack: " + dump(new Error().stack));
+ throw e;
+ }
+ hadProcessing = true;
+
+ if (outputs) {
if (outputs.length === 1 && outputs[0].__finalResult__) {
if (DEBUG) print("Solving complete: __finalResult__");
delete outputs[0].__finalResult__; // Might recycle this
delete outputs[0].__uid__;
finalComment();
- return outputs[0];
- }
- results = results.concat(outputs.filter(function(output) { return !!output.__result__; }))
- var nonResults = outputs.filter(function(output) { return !output.__result__; });
-
- var keptUids = {};
- for (var i = 0; i < nonResults.length; i++) {
- var s = nonResults[i];
- if (s.__uid__) {
- keptUids[s.__uid__] = true;
- } else {
- this.addItem(s);
- }
- }
- var droppedUids = {};
- for (var i = 0; i < selected.length; i++) {
- var s = selected[i];
- if (!keptUids[s.__uid__]) droppedUids[s.__uid__] = true;
+ finished = true;
+ finalResult = outputs[0];
+ } else {
+ that.results = that.results.concat(outputs);
}
- this.items = this.items.filter(function(item) {
- if (!droppedUids[item.__uid__]) {
- return true;
- } else {
- delete item.__uid__;
- }
- });
- //midComment(true);
}
- }
- if (this.items.length === 0) {
+ });
+ if (!hadProcessing) {
if (DEBUG) print("Solving complete: no remaining items");
finalComment();
- results.forEach(function(output) {
+ this.results.forEach(function(output) {
delete output.__result__; // Might recycle these
delete output.__uid__;
});
- return results;
+ return this.results;
}
- if (!hadProcessing) {
- print("Reached a dead end.");
- this.items.forEach(function(item) {
- print("remaining item:" + dump(item));
- });
- throw "failure";
+ if (finalResult) {
+ return finalResult;
}
midComment();
- this.items = this.items.filter(function(item) { return item !== null; });
}
},
};
Zyme = function() { };
Zyme.prototype = {
- select: function(items) {
- return items.filter(this.selectItem, this);
- },
process: function(items) {
var ret = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
try {
- ret = ret.concat(this.processItem(item));
+ var outputs = this.processItem(item);
+ if (outputs) {
+ ret = ret.concat(outputs);
+ }
} catch (e) {
print("Exception in process(), current item is: " + dump(item));
throw e;