00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00035 #include "aggregatefunctmedianexpression.h"
00036
00037 AggregateFunctMedianExpression::AggregateFunctMedianExpression(VarExpression * _var):
00038 AggregateFunctExpression(et_aggregatefunctmedian, _var) {
00039 }
00040
00041 AggregateFunctMedianExpression::AggregateFunctMedianExpression(VarStepExpression * _varstep):
00042 AggregateFunctExpression(et_aggregatefunctmedian, _varstep) {
00043 }
00044
00045 AggregateFunctMedianExpression::~AggregateFunctMedianExpression() {
00046 }
00047
00048 void AggregateFunctMedianExpression::eval(OutputStream & eos,
00049 Environment * env, unsigned modus) {
00050
00051 switch (modus) {
00052
00053 case EVAL_QUERY:
00054 {
00055 bool empty_sequence = true;
00056 long double median_val =
00057 calculateValue(eos, env, modus, empty_sequence);
00058 if (!empty_sequence) {
00059 const char *median_str =
00060 MiscFunctions::getStringFromNumerical(median_val);
00061 eos << median_str;
00062 delete[]median_str;
00063 } else {
00064 eos << OUTPUT_MEDIAN_ON_EMPTY_SEQUENCE;
00065 }
00066 break;
00067 }
00068
00069 case EVAL_QUERY_SILENT:
00070 {
00071 bool empty_sequence = true;
00072 long double median_val =
00073 calculateValue(eos, env, modus, empty_sequence);
00074 if (!empty_sequence) {
00075 cur_val.setNumVal(median_val);
00076 } else {
00077 const char *median_empty_val =
00078 new char[strlen(OUTPUT_MEDIAN_ON_EMPTY_SEQUENCE) + 1];
00079 strcpy((char *) median_empty_val,
00080 OUTPUT_MEDIAN_ON_EMPTY_SEQUENCE);
00081 cur_val.setStrVal(median_empty_val);
00082 }
00083 break;
00084 }
00085
00086 case EVAL_SIGNOFF:
00087 forexp->eval(eos, env, EVAL_SIGNOFF);
00088 break;
00089
00090 default:
00091 throw
00092 RuntimeException
00093 ("AggregateFunctMedianExpression: Illegal Evaluation Mode",
00094 eid_runtime_illegalmode);
00095 break;
00096 }
00097 }
00098
00099 long double AggregateFunctMedianExpression::calculateValue(OutputStream & eos,
00100 Environment * env,
00101 unsigned modus,
00102 bool &
00103 empty_sequence) {
00104
00105 var ? bit->init(env->getNodeBinding(var->getId())) :
00106 bit->init(env->getNodeBinding(varstep->getId()));
00107
00108 long double median_ret = 0;
00109 vector < long double >*pcds = new vector < long double >;
00110 const char *pcd = NULL;
00111
00112 while (BufferNode * cur =
00113 bit->getNext(READ_UP_TO_CLOSE_CONTEXT, LOCK_CONTEXT_ALWAYS_CLEAR)) {
00114
00115 empty_sequence = false;
00116
00117 pcd = cur->getPCDataRepresentation();
00118 long double tmp = MiscFunctions::getNumericFromString(pcd);
00119
00120 pcds->push_back(tmp);
00121
00122 free((char *) pcd);
00123
00124 forexp->evalSignOffForBinding(eos, env, cur);
00125 }
00126 bit->clear();
00127
00128 if (!empty_sequence) {
00129 sort(pcds->begin(), pcds->end());
00130 if (pcds->size() % 2 == 0) {
00131 long double tmp =
00132 MiscFunctions::getSummationFrom((*pcds)[(pcds->size() / 2) - 1],
00133 (*pcds)[(pcds->size() / 2)]);
00134
00135 median_ret =
00136 MiscFunctions::getRoundFrom(MiscFunctions::
00137 getDivisionFrom(tmp, 2));
00138 } else {
00139 median_ret =
00140 MiscFunctions::getRoundFrom((*pcds)[(int) (pcds->size() / 2)]);
00141 }
00142 }
00143 delete pcds;
00144
00145 return median_ret;
00146 }