1 //------------------------------------------------------------------------------
2 // <copyright file="UInt64Storage.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 // <owner current="false" primary="false">Microsoft</owner>
8 //------------------------------------------------------------------------------
10 namespace System.Data.Common {
13 using System.Data.SqlTypes;
14 using System.Collections;
16 internal sealed class UInt64Storage : DataStorage {
18 private static readonly UInt64 defaultValue = UInt64.MinValue;
20 private UInt64[] values;
22 public UInt64Storage(DataColumn column)
23 : base(column, typeof(UInt64), defaultValue, StorageType.UInt64) {
26 override public Object Aggregate(int[] records, AggregateType kind) {
30 case AggregateType.Sum:
31 UInt64 sum = defaultValue;
32 foreach (int record in records) {
33 if (HasValue(record)) {
34 checked { sum += values[record];}
43 case AggregateType.Mean:
44 Decimal meanSum = (Decimal)defaultValue;
46 foreach (int record in records) {
47 if (HasValue(record)) {
48 checked { meanSum += (Decimal)values[record];}
55 checked {mean = (UInt64)(Decimal)(meanSum / (Decimal)meanCount);}
60 case AggregateType.Var:
61 case AggregateType.StDev:
68 foreach (int record in records) {
69 if (HasValue(record)) {
70 dsum += (double)values[record];
71 sqrsum += (double)values[record]*(double)values[record];
77 var = ((double)count * sqrsum - (dsum * dsum));
78 prec = var / (dsum * dsum);
80 // we are dealing with the risk of a cancellation error
81 // double is guaranteed only for 15 digits so a difference
82 // with a result less than 1e-15 should be considered as zero
84 if ((prec < 1e-15) || (var <0))
87 var = var / (count * (count -1));
89 if (kind == AggregateType.StDev) {
90 return Math.Sqrt(var);
96 case AggregateType.Min:
97 UInt64 min = UInt64.MaxValue;
98 for (int i = 0; i < records.Length; i++) {
99 int record = records[i];
100 if (HasValue(record)) {
101 min=Math.Min(values[record], min);
110 case AggregateType.Max:
111 UInt64 max = UInt64.MinValue;
112 for (int i = 0; i < records.Length; i++) {
113 int record = records[i];
114 if (HasValue(record)) {
115 max=Math.Max(values[record], max);
124 case AggregateType.First:
125 if (records.Length > 0) {
126 return values[records[0]];
130 case AggregateType.Count:
131 return base.Aggregate(records, kind);
135 catch (OverflowException) {
136 throw ExprException.Overflow(typeof(UInt64));
138 throw ExceptionBuilder.AggregateException(kind, DataType);
141 override public int Compare(int recordNo1, int recordNo2) {
142 UInt64 valueNo1 = values[recordNo1];
143 UInt64 valueNo2 = values[recordNo2];
145 if (valueNo1.Equals(defaultValue) || valueNo2.Equals(defaultValue)) {
146 int bitCheck = CompareBits(recordNo1, recordNo2);
150 //return valueNo1.CompareTo(valueNo2);
151 return(valueNo1 < valueNo2 ? -1 : (valueNo1 > valueNo2 ? 1 : 0)); // similar to UInt64.CompareTo(UInt64)
154 public override int CompareValueTo(int recordNo, object value) {
155 System.Diagnostics.Debug.Assert(0 <= recordNo, "Invalid record");
156 System.Diagnostics.Debug.Assert(null != value, "null value");
158 if (NullValue == value) {
159 return (HasValue(recordNo) ? 1 : 0);
162 UInt64 valueNo1 = values[recordNo];
163 if ((defaultValue == valueNo1) && !HasValue(recordNo)) {
166 return valueNo1.CompareTo((UInt64)value);
167 //return(valueNo1 < valueNo2 ? -1 : (valueNo1 > valueNo2 ? 1 : 0)); // similar to UInt64.CompareTo(UInt64)
170 public override object ConvertValue(object value) {
171 if (NullValue != value) {
173 value = ((IConvertible)value).ToUInt64(FormatProvider);
182 override public void Copy(int recordNo1, int recordNo2) {
183 CopyBits(recordNo1, recordNo2);
184 values[recordNo2] = values[recordNo1];
187 override public Object Get(int record) {
188 UInt64 value = values[record];
189 if (!value.Equals(defaultValue)) {
192 return GetBits(record);
195 override public void Set(int record, Object value) {
196 System.Diagnostics.Debug.Assert(null != value, "null value");
197 if (NullValue == value) {
198 values[record] = defaultValue;
199 SetNullBit(record, true);
202 values[record] = ((IConvertible)value).ToUInt64(FormatProvider);
203 SetNullBit(record, false);
207 override public void SetCapacity(int capacity) {
208 UInt64[] newValues = new UInt64[capacity];
209 if (null != values) {
210 Array.Copy(values, 0, newValues, 0, Math.Min(capacity, values.Length));
213 base.SetCapacity(capacity);
216 override public object ConvertXmlToObject(string s) {
217 return XmlConvert.ToUInt64(s);
220 override public string ConvertObjectToXml(object value) {
221 return XmlConvert.ToString((UInt64)value);
224 override protected object GetEmptyStorage(int recordCount) {
225 return new UInt64[recordCount];
228 override protected void CopyValue(int record, object store, BitArray nullbits, int storeIndex) {
229 UInt64[] typedStore = (UInt64[]) store;
230 typedStore[storeIndex] = values[record];
231 nullbits.Set(storeIndex, !HasValue(record));
234 override protected void SetStorage(object store, BitArray nullbits) {
235 values = (UInt64[]) store;
236 SetNullStorage(nullbits);