📄 deltablue.js.svn-base
字号:
// Copyright 2008 the V8 project authors. All rights reserved.// Copyright 1996 John Maloney and Mario Wolczko.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA// This implementation of the DeltaBlue benchmark is derived // from the Smalltalk implementation by John Maloney and Mario // Wolczko. Some parts have been translated directly, whereas // others have been modified more aggresively to make it feel // more like a JavaScript program.var DeltaBlue = new BenchmarkSuite('DeltaBlue', 71104, [ new Benchmark('DeltaBlue', deltaBlue)]);/** * A JavaScript implementation of the DeltaBlue constrain-solving * algorithm, as described in: * * "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver" * Bjorn N. Freeman-Benson and John Maloney * January 1990 Communications of the ACM, * also available as University of Washington TR 89-08-06. * * Beware: this benchmark is written in a grotesque style where * the constraint model is built by side-effects from constructors. * I've kept it this way to avoid deviating too much from the original * implementation. *//* --- O b j e c t M o d e l --- */Object.prototype.inherits = function (shuper) { function Inheriter() { } Inheriter.prototype = shuper.prototype; this.prototype = new Inheriter(); this.superConstructor = shuper;}function OrderedCollection() { this.elms = new Array();}OrderedCollection.prototype.add = function (elm) { this.elms.push(elm);}OrderedCollection.prototype.at = function (index) { return this.elms[index];}OrderedCollection.prototype.size = function () { return this.elms.length;}OrderedCollection.prototype.removeFirst = function () { return this.elms.pop();}OrderedCollection.prototype.remove = function (elm) { var index = 0, skipped = 0; for (var i = 0; i < this.elms.length; i++) { var value = this.elms[i]; if (value != elm) { this.elms[index] = value; index++; } else { skipped++; } } for (var i = 0; i < skipped; i++) this.elms.pop();}/* --- * * S t r e n g t h * --- *//** * Strengths are used to measure the relative importance of constraints. * New strengths may be inserted in the strength hierarchy without * disrupting current constraints. Strengths cannot be created outside * this class, so pointer comparison can be used for value comparison. */function Strength(strengthValue, name) { this.strengthValue = strengthValue; this.name = name;}Strength.stronger = function (s1, s2) { return s1.strengthValue < s2.strengthValue;}Strength.weaker = function (s1, s2) { return s1.strengthValue > s2.strengthValue;}Strength.weakestOf = function (s1, s2) { return this.weaker(s1, s2) ? s1 : s2;}Strength.strongest = function (s1, s2) { return this.stronger(s1, s2) ? s1 : s2;}Strength.prototype.nextWeaker = function () { switch (this.strengthValue) { case 0: return Strength.WEAKEST; case 1: return Strength.WEAK_DEFAULT; case 2: return Strength.NORMAL; case 3: return Strength.STRONG_DEFAULT; case 4: return Strength.PREFERRED; case 5: return Strength.REQUIRED; }}// Strength constants.Strength.REQUIRED = new Strength(0, "required");Strength.STONG_PREFERRED = new Strength(1, "strongPreferred");Strength.PREFERRED = new Strength(2, "preferred");Strength.STRONG_DEFAULT = new Strength(3, "strongDefault");Strength.NORMAL = new Strength(4, "normal");Strength.WEAK_DEFAULT = new Strength(5, "weakDefault");Strength.WEAKEST = new Strength(6, "weakest");/* --- * * C o n s t r a i n t * --- *//** * An abstract class representing a system-maintainable relationship * (or "constraint") between a set of variables. A constraint supplies * a strength instance variable; concrete subclasses provide a means * of storing the constrained variables and other information required * to represent a constraint. */function Constraint(strength) { this.strength = strength;}/** * Activate this constraint and attempt to satisfy it. */Constraint.prototype.addConstraint = function () { this.addToGraph(); planner.incrementalAdd(this);}/** * Attempt to find a way to enforce this constraint. If successful, * record the solution, perhaps modifying the current dataflow * graph. Answer the constraint that this constraint overrides, if * there is one, or nil, if there isn't. * Assume: I am not already satisfied. */Constraint.prototype.satisfy = function (mark) { this.chooseMethod(mark); if (!this.isSatisfied()) { if (this.strength == Strength.REQUIRED) alert("Could not satisfy a required constraint!"); return null; } this.markInputs(mark); var out = this.output(); var overridden = out.determinedBy; if (overridden != null) overridden.markUnsatisfied(); out.determinedBy = this; if (!planner.addPropagate(this, mark)) alert("Cycle encountered"); out.mark = mark; return overridden;}Constraint.prototype.destroyConstraint = function () { if (this.isSatisfied()) planner.incrementalRemove(this); else this.removeFromGraph();}/** * Normal constraints are not input constraints. An input constraint * is one that depends on external state, such as the mouse, the * keybord, a clock, or some arbitraty piece of imperative code. */Constraint.prototype.isInput = function () { return false;}/* --- * * U n a r y C o n s t r a i n t * --- *//** * Abstract superclass for constraints having a single possible output * variable. */function UnaryConstraint(v, strength) { UnaryConstraint.superConstructor.call(this, strength); this.myOutput = v; this.satisfied = false; this.addConstraint();}UnaryConstraint.inherits(Constraint);/** * Adds this constraint to the constraint graph */UnaryConstraint.prototype.addToGraph = function () { this.myOutput.addConstraint(this); this.satisfied = false;}/** * Decides if this constraint can be satisfied and records that * decision. */UnaryConstraint.prototype.chooseMethod = function (mark) { this.satisfied = (this.myOutput.mark != mark) && Strength.stronger(this.strength, this.myOutput.walkStrength);}/** * Returns true if this constraint is satisfied in the current solution. */UnaryConstraint.prototype.isSatisfied = function () { return this.satisfied;}UnaryConstraint.prototype.markInputs = function (mark) { // has no inputs}/** * Returns the current output variable. */UnaryConstraint.prototype.output = function () { return this.myOutput;}/** * Calculate the walkabout strength, the stay flag, and, if it is * 'stay', the value for the current output of this constraint. Assume * this constraint is satisfied. */UnaryConstraint.prototype.recalculate = function () { this.myOutput.walkStrength = this.strength; this.myOutput.stay = !this.isInput(); if (this.myOutput.stay) this.execute(); // Stay optimization}/** * Records that this constraint is unsatisfied */UnaryConstraint.prototype.markUnsatisfied = function () { this.satisfied = false;}UnaryConstraint.prototype.inputsKnown = function () { return true;}UnaryConstraint.prototype.removeFromGraph = function () { if (this.myOutput != null) this.myOutput.removeConstraint(this); this.satisfied = false;}/* --- * * S t a y C o n s t r a i n t * --- *//** * Variables that should, with some level of preference, stay the same. * Planners may exploit the fact that instances, if satisfied, will not * change their output during plan execution. This is called "stay * optimization". */function StayConstraint(v, str) { StayConstraint.superConstructor.call(this, v, str);}StayConstraint.inherits(UnaryConstraint);StayConstraint.prototype.execute = function () { // Stay constraints do nothing}/* --- * * E d i t C o n s t r a i n t * --- *//** * A unary input constraint used to mark a variable that the client * wishes to change. */function EditConstraint(v, str) { EditConstraint.superConstructor.call(this, v, str);}EditConstraint.inherits(UnaryConstraint);/** * Edits indicate that a variable is to be changed by imperative code. */EditConstraint.prototype.isInput = function () { return true;}EditConstraint.prototype.execute = function () { // Edit constraints do nothing}/* --- * * B i n a r y C o n s t r a i n t * --- */var Direction = new Object();Direction.NONE = 0;Direction.FORWARD = 1;Direction.BACKWARD = -1;/** * Abstract superclass for constraints having two possible output * variables. */function BinaryConstraint(var1, var2, strength) { BinaryConstraint.superConstructor.call(this, strength); this.v1 = var1; this.v2 = var2; this.direction = Direction.NONE; this.addConstraint();}BinaryConstraint.inherits(Constraint);/** * Decides if this constratint can be satisfied and which way it * should flow based on the relative strength of the variables related, * and record that decision. */BinaryConstraint.prototype.chooseMethod = function (mark) { if (this.v1.mark == mark) { this.direction = (this.v1.mark != mark && Strength.stronger(this.strength, this.v2.walkStrength)) ? Direction.FORWARD : Direction.NONE; } if (this.v2.mark == mark) { this.direction = (this.v1.mark != mark && Strength.stronger(this.strength, this.v1.walkStrength)) ? Direction.BACKWARD : Direction.NONE; } if (Strength.weaker(this.v1.walkStrength, this.v2.walkStrength)) { this.direction = Strength.stronger(this.strength, this.v1.walkStrength) ? Direction.BACKWARD : Direction.NONE; } else { this.direction = Strength.stronger(this.strength, this.v2.walkStrength) ? Direction.FORWARD : Direction.BACKWARD }}/** * Add this constraint to the constraint graph */BinaryConstraint.prototype.addToGraph = function () { this.v1.addConstraint(this); this.v2.addConstraint(this); this.direction = Direction.NONE;}/** * Answer true if this constraint is satisfied in the current solution. */BinaryConstraint.prototype.isSatisfied = function () { return this.direction != Direction.NONE;}/** * Mark the input variable with the given mark. */BinaryConstraint.prototype.markInputs = function (mark) { this.input().mark = mark;}/** * Returns the current input variable */BinaryConstraint.prototype.input = function () { return (this.direction == Direction.FORWARD) ? this.v1 : this.v2;}/** * Returns the current output variable */BinaryConstraint.prototype.output = function () { return (this.direction == Direction.FORWARD) ? this.v2 : this.v1;}/** * Calculate the walkabout strength, the stay flag, and, if it is * 'stay', the value for the current output of this * constraint. Assume this constraint is satisfied. */BinaryConstraint.prototype.recalculate = function () { var ihn = this.input(), out = this.output(); out.walkStrength = Strength.weakestOf(this.strength, ihn.walkStrength); out.stay = ihn.stay; if (out.stay) this.execute();}/** * Record the fact that this constraint is unsatisfied. */BinaryConstraint.prototype.markUnsatisfied = function () { this.direction = Direction.NONE;}BinaryConstraint.prototype.inputsKnown = function (mark) { var i = this.input(); return i.mark == mark || i.stay || i.determinedBy == null;}BinaryConstraint.prototype.removeFromGraph = function () { if (this.v1 != null) this.v1.removeConstraint(this); if (this.v2 != null) this.v2.removeConstraint(this);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -