Browse Source

Refs #3045 updated AvgAccumulator to 2.5.4

Mike McCarty 11 years ago
parent
commit
c3b0c9c9d6

+ 42 - 7
lib/pipeline/accumulators/AvgAccumulator.js

@@ -11,23 +11,58 @@ var AvgAccumulator = module.exports = function AvgAccumulator(){
 	this.subTotalName = "subTotal";
 	this.countName = "count";
 	this.totalIsANumber = true;
+	this.total = 0;
+	this.count = 0;
 	base.call(this);
-}, klass = AvgAccumulator, SumAccumulator = require("./SumAccumulator"), base = SumAccumulator, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+}, klass = AvgAccumulator, Accumulator = require("./Accumulator"), base = Accumulator, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+
+//DEPENDENCIES
+var Value = require("../Value");
+
+klass.create = function create() {
+	return new AvgAccumulator();
+};
 
 proto.getFactory = function getFactory(){
 	return klass;	// using the ctor rather than a separate .create() method
 };
 
-proto.getValue = function getValue(){
-	if (this.totalIsANumber && this.count > 0) {
-		return this.total / this.count;
-	} else if (this.count === 0) {
-		return 0;
+proto.processInternal = function processInternal(input, merging) {
+	if (!merging) {
+		if (typeof input !== "number") {
+			return;
+		}
+		this.total += input;
+		this.count += 1;
 	} else {
-		throw new Error("$sum resulted in a non-numeric type");
+		Value.verifyDocument(input);
+		this.total += input[this.subTotalName];
+		this.count += input[this.countName];
 	}
 };
 
+proto.getValue = function getValue(toBeMerged){
+	if (!toBeMerged) {
+		if (this.totalIsANumber && this.count > 0) {
+			return this.total / this.count;
+		} else if (this.count === 0) {
+			return 0;
+		} else {
+			throw new Error("$sum resulted in a non-numeric type");
+		}
+	} else {
+		return {
+			subTotalName : this.total,
+			countName : this.count
+		};
+	}
+};
+
+proto.reset = function reset() {
+	this.total = 0;
+	this.count = 0;
+};
+
 proto.getOpName = function getOpName(){
 	return "$avg";
 };

+ 18 - 23
test/lib/pipeline/accumulators/AvgAccumulator.js

@@ -1,16 +1,11 @@
 "use strict";
 var assert = require("assert"),
-	AvgAccumulator = require("../../../../lib/pipeline/accumulators/AvgAccumulator"),
-	FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression");
-
+	AvgAccumulator = require("../../../../lib/pipeline/accumulators/AvgAccumulator");
 
 function createAccumulator(){
-	var avgAccumulator = new AvgAccumulator();
-	avgAccumulator.addOperand(new FieldPathExpression("b") );
-	return avgAccumulator;
+	return new AvgAccumulator();
 }
 
-
 module.exports = {
 
 	"AvgAccumulator": {
@@ -33,7 +28,7 @@ module.exports = {
 
 		},
 
-		"#evaluate()": {
+		"#processInternal()": {
 
 			"should evaluate no documents": function testStuff(){
 				var avgAccumulator = createAccumulator();
@@ -42,7 +37,7 @@ module.exports = {
 
 			"should evaluate one document with a field that is NaN": function testStuff(){
 				var avgAccumulator = createAccumulator();
-				avgAccumulator.evaluate({b:Number("foo")});
+				avgAccumulator.processInternal(Number("foo"));
 				// NaN is unequal to itself
 				assert.notStrictEqual(avgAccumulator.getValue(), avgAccumulator.getValue());
 			},
@@ -50,7 +45,7 @@ module.exports = {
 
 			"should evaluate one document and avg it's value": function testStuff(){
 				var avgAccumulator = createAccumulator();
-				avgAccumulator.evaluate({b:5});
+				avgAccumulator.processInternal(5);
 				assert.strictEqual(avgAccumulator.getValue(), 5);
 
 			},
@@ -58,53 +53,53 @@ module.exports = {
 
 			"should evaluate and avg two ints": function testStuff(){
 				var avgAccumulator = createAccumulator();
-				avgAccumulator.evaluate({b:5});
-				avgAccumulator.evaluate({b:7});
+				avgAccumulator.processInternal(5);
+				avgAccumulator.processInternal(7);
 				assert.strictEqual(avgAccumulator.getValue(), 6);
 			},
 
 			"should evaluate and avg two ints overflow": function testStuff(){
 				var avgAccumulator = createAccumulator();
-				avgAccumulator.evaluate({b:Number.MAX_VALUE});
-				avgAccumulator.evaluate({b:Number.MAX_VALUE});
+				avgAccumulator.processInternal(Number.MAX_VALUE);
+				avgAccumulator.processInternal(Number.MAX_VALUE);
 				assert.strictEqual(Number.isFinite(avgAccumulator.getValue()), false);
 			},
 
 
 			"should evaluate and avg two negative ints": function testStuff(){
 				var avgAccumulator = createAccumulator();
-				avgAccumulator.evaluate({b:-5});
-				avgAccumulator.evaluate({b:-7});
+				avgAccumulator.processInternal(-5);
+				avgAccumulator.processInternal(-7);
 				assert.strictEqual(avgAccumulator.getValue(), -6);
 			},
 
 //TODO Not sure how to do this in Javascript
 //			"should evaluate and avg two negative ints overflow": function testStuff(){
 //				var avgAccumulator = createAccumulator();
-//				avgAccumulator.evaluate({b:Number.MIN_VALUE});
-//				avgAccumulator.evaluate({b:7});
+//				avgAccumulator.processInternal(Number.MIN_VALUE);
+//				avgAccumulator.processInternal(7);
 //				assert.strictEqual(avgAccumulator.getValue(), Number.MAX_VALUE);
 //			},
 //
 
 			"should evaluate and avg int and float": function testStuff(){
 				var avgAccumulator = createAccumulator();
-				avgAccumulator.evaluate({b:8.5});
-				avgAccumulator.evaluate({b:7});
+				avgAccumulator.processInternal(8.5);
+				avgAccumulator.processInternal(7);
 				assert.strictEqual(avgAccumulator.getValue(), 7.75);
 			},
 
 			"should evaluate and avg one Number and a NaN sum to NaN": function testStuff(){
 				var avgAccumulator = createAccumulator();
-				avgAccumulator.evaluate({b:8});
-				avgAccumulator.evaluate({b:Number("bar")});
+				avgAccumulator.processInternal(8);
+				avgAccumulator.processInternal(Number("bar"));
 				// NaN is unequal to itself
 				assert.notStrictEqual(avgAccumulator.getValue(), avgAccumulator.getValue());
 			},
 
 			"should evaluate and avg a null value to 0": function testStuff(){
 				var avgAccumulator = createAccumulator();
-				avgAccumulator.evaluate({b:null});
+				avgAccumulator.processInternal(null);
 				assert.strictEqual(avgAccumulator.getValue(), 0);
 			}