![]() |
Statistics for MySQL
0.9
|
00001 /* median.cc (median) */ 00002 00003 /*********************************************************************** 00004 * This code is part of Statistics for MySQL. 00005 * 00006 * Copyright (C) 2011 Heinrich Schuchardt (xypron.glpk@gmx.de) 00007 * 00008 * Licensed under the Apache License, Version 2.0 (the "License"); 00009 * you may not use this file except in compliance with the License. 00010 * You may obtain a copy of the License at 00011 * 00012 * http://www.apache.org/licenses/LICENSE-2.0 00013 * 00014 * Unless required by applicable law or agreed to in writing, software 00015 * distributed under the License is distributed on an "AS IS" BASIS, 00016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00017 * See the License for the specific language governing permissions and 00018 * limitations under the License. 00019 ***********************************************************************/ 00020 00021 00031 #include "sqlstat.h" 00032 #include <set> 00033 00034 using namespace std; 00035 00039 typedef multiset<double, less<double> > DoubleSet; 00040 00053 my_bool median_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { 00054 DoubleSet *data; 00055 00056 if (args->arg_count != 1) { 00057 strcpy(message,"median() requires one argument"); 00058 return 1; 00059 } 00060 args->arg_type[0] = REAL_RESULT; 00061 00062 data = new DoubleSet(); 00063 if (data == NULL) { 00064 strcpy(message,"Couldn't allocate memory"); 00065 return 1; 00066 } 00067 00068 initid->maybe_null = 1; 00069 initid->decimals = NOT_FIXED_DEC; 00070 initid->max_length = 13 + initid->decimals; 00071 initid->ptr = (char *) data; 00072 initid->const_item = 0; 00073 00074 return 0; 00075 } 00076 00088 void median_reset(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { 00089 median_clear(initid, is_null, error); 00090 median_add(initid, args, is_null, error); 00091 } 00092 00102 void median_clear(UDF_INIT *initid, char *is_null, char *error) { 00103 DoubleSet *data; 00104 00105 data = (DoubleSet *) initid->ptr; 00106 data->clear(); 00107 } 00108 00119 void median_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { 00120 DoubleSet *data; 00121 double x; 00122 00123 if (!args->args[0]) { 00124 return; 00125 } 00126 data = (DoubleSet *) initid->ptr; 00127 x = *((double*) args->args[0]); 00128 00129 data->insert(x); 00130 } 00131 00141 double median(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { 00142 DoubleSet *data; 00143 DoubleSet::iterator pos; 00144 double ret; 00145 size_t n; 00146 size_t n2; 00147 00148 data = (DoubleSet *) initid->ptr; 00149 00150 00151 n = data->size(); 00152 if (n <= 0 ) { 00153 *is_null = 1; 00154 return 0; 00155 } 00156 00157 n2 = ++n / 2; 00158 00159 pos = data->begin(); 00160 for (int i = 0; i < n2; i++) { 00161 ret = *pos++; 00162 } 00163 00164 if (1 & n) { 00165 ret += *pos; 00166 ret /= 2; 00167 } 00168 00169 return ret; 00170 } 00171 00179 void median_deinit(UDF_INIT *initid) { 00180 DoubleSet *data; 00181 if (initid->ptr) { 00182 data = (DoubleSet *) initid->ptr; 00183 data->~multiset(); 00184 } 00185 }