Created
May 5, 2011 10:42
-
-
Save max-mulawa/956849 to your computer and use it in GitHub Desktop.
Median
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Data.SqlTypes; | |
using System.IO; | |
using Microsoft.SqlServer.Server; | |
[Serializable] | |
[SqlUserDefinedAggregate(Format.UserDefined, //Type implements IBinarySerialize | |
IsInvariantToDuplicates = false, //passing the same row will affect the result | |
IsInvariantToNulls = false, // passing NULL value will affect the result | |
IsInvariantToOrder = true, //order of the rows doesn't affect the results | |
IsNullIfEmpty = true, //if no rows are passed the return value is NULL | |
Name="Median", | |
MaxByteSize = 8000 //this is no longer t he case in 2008 R2, it shoud be MaxByteSize=-1 to don't face 2 GB limit | |
)] | |
public class Median : IBinarySerialize | |
{ | |
private SqlDouble medianValue; | |
private List<SqlDouble> list; | |
public List<SqlDouble> Items | |
{ | |
get { return list; } | |
} | |
public void Init() | |
{ | |
medianValue = 0; | |
list = new List<SqlDouble>(); | |
} | |
public void Accumulate(SqlDouble Value) | |
{ | |
if(!Value.IsNull) | |
{ | |
list.Add(Value); | |
} | |
} | |
public void Merge(Median Group) | |
{ | |
list.AddRange(Group.Items); | |
} | |
public SqlDouble Terminate() | |
{ | |
medianValue = CalculateMedian(); | |
return medianValue; | |
} | |
private SqlDouble CalculateMedian() | |
{ | |
SqlDouble median = SqlDouble.Null; | |
list.Sort(); | |
if (list.Count % 2 == 1) | |
{ | |
median = list[(list.Count + 1) / 2 - 1]; | |
} | |
else | |
{ | |
median = (list[list.Count / 2] + list[list.Count / 2 - 1]) / 2.0; | |
} | |
return median; | |
} | |
/// <summary> | |
/// Format | |
/// Bytes 1 - 4: list items count | |
/// Byter 5 - 5+8xlist.Count : 8 byte floating point numbers | |
/// </summary> | |
/// <param name="r"></param> | |
public void Read(BinaryReader r) | |
{ | |
list = new List<SqlDouble>(); | |
int itemsCount = r.ReadInt32(); | |
for (int i = 0; i < itemsCount; i++) | |
{ | |
list.Add(new SqlDouble(r.ReadDouble())); | |
} | |
} | |
public void Write(BinaryWriter w) | |
{ | |
w.Write(list.Count); | |
foreach (var value in list) | |
{ | |
w.Write(value.Value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment