1 //------------------------------------------------------------------------------ 2 // <copyright file="UInt32Storage.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 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 //------------------------------------------------------------------------------ 9 10 namespace System.Data.Common { 11 using System; 12 using System.Xml; 13 using System.Data.SqlTypes; 14 using System.Collections; 15 16 internal sealed class UInt32Storage : DataStorage { 17 18 private const UInt32 defaultValue = UInt32.MinValue; 19 20 private UInt32[] values; 21 UInt32Storage(DataColumn column)22 public UInt32Storage(DataColumn column) 23 : base(column, typeof(UInt32), defaultValue, StorageType.UInt32) { 24 } 25 Aggregate(int[] records, AggregateType kind)26 override public Object Aggregate(int[] records, AggregateType kind) { 27 bool hasData = false; 28 try { 29 switch (kind) { 30 case AggregateType.Sum: 31 UInt64 sum = defaultValue; 32 foreach (int record in records) { 33 if (HasValue(record)) { 34 checked { sum += (UInt64) values[record];} 35 hasData = true; 36 } 37 } 38 if (hasData) { 39 return sum; 40 } 41 return NullValue; 42 43 case AggregateType.Mean: 44 Int64 meanSum = (Int64)defaultValue; 45 int meanCount = 0; 46 foreach (int record in records) { 47 if (HasValue(record)) { 48 checked { meanSum += (Int64)values[record];} 49 meanCount++; 50 hasData = true; 51 } 52 } 53 if (hasData) { 54 UInt32 mean; 55 checked {mean = (UInt32)(meanSum / meanCount);} 56 return mean; 57 } 58 return NullValue; 59 60 case AggregateType.Var: 61 case AggregateType.StDev: 62 int count = 0; 63 double var = 0.0f; 64 double prec = 0.0f; 65 double dsum = 0.0f; 66 double sqrsum = 0.0f; 67 68 foreach (int record in records) { 69 if (HasValue(record)) { 70 dsum += (double)values[record]; 71 sqrsum += (double)values[record]*(double)values[record]; 72 count++; 73 } 74 } 75 76 if (count > 1) { 77 var = ((double)count * sqrsum - (dsum * dsum)); 78 prec = var / (dsum * dsum); 79 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 83 84 if ((prec < 1e-15) || (var <0)) 85 var = 0; 86 else 87 var = var / (count * (count -1)); 88 89 if (kind == AggregateType.StDev) { 90 return Math.Sqrt(var); 91 } 92 return var; 93 } 94 return NullValue; 95 96 case AggregateType.Min: 97 UInt32 min = UInt32.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); 102 hasData = true; 103 } 104 } 105 if (hasData) { 106 return min; 107 } 108 return NullValue; 109 110 case AggregateType.Max: 111 UInt32 max = UInt32.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); 116 hasData = true; 117 } 118 } 119 if (hasData) { 120 return max; 121 } 122 return NullValue; 123 124 case AggregateType.First: 125 if (records.Length > 0) { 126 return values[records[0]]; 127 } 128 return null; 129 130 case AggregateType.Count: 131 count = 0; 132 for (int i = 0; i < records.Length; i++) { 133 if (HasValue(records[i])) 134 count++; 135 } 136 return count; 137 } 138 } 139 catch (OverflowException) { 140 throw ExprException.Overflow(typeof(UInt32)); 141 } 142 throw ExceptionBuilder.AggregateException(kind, DataType); 143 } 144 145 Compare(int recordNo1, int recordNo2)146 override public int Compare(int recordNo1, int recordNo2) { 147 UInt32 valueNo1 = values[recordNo1]; 148 UInt32 valueNo2 = values[recordNo2]; 149 150 if (valueNo1 == defaultValue || valueNo2 == defaultValue) { 151 int bitCheck = CompareBits(recordNo1, recordNo2); 152 if (0 != bitCheck) { 153 return bitCheck; 154 } 155 } 156 //return valueNo1.CompareTo(valueNo2); 157 return(valueNo1 < valueNo2 ? -1 : (valueNo1 > valueNo2 ? 1 : 0)); // similar to UInt32.CompareTo(UInt32) 158 } 159 CompareValueTo(int recordNo, object value)160 public override int CompareValueTo(int recordNo, object value) { 161 System.Diagnostics.Debug.Assert(0 <= recordNo, "Invalid record"); 162 System.Diagnostics.Debug.Assert(null != value, "null value"); 163 164 if (NullValue == value) { 165 return (HasValue(recordNo) ? 1 : 0); 166 } 167 168 UInt32 valueNo1 = values[recordNo]; 169 if ((defaultValue == valueNo1) && !HasValue(recordNo)) { 170 return -1; 171 } 172 return valueNo1.CompareTo((UInt32)value); 173 //return(valueNo1 < valueNo2 ? -1 : (valueNo1 > valueNo2 ? 1 : 0)); // similar to UInt32.CompareTo(UInt32) 174 } 175 ConvertValue(object value)176 public override object ConvertValue(object value) { 177 if (NullValue != value) { 178 if (null != value) { 179 value = ((IConvertible)value).ToUInt32(FormatProvider); 180 } 181 else { 182 value = NullValue; 183 } 184 } 185 return value; 186 } 187 Copy(int recordNo1, int recordNo2)188 override public void Copy(int recordNo1, int recordNo2) { 189 CopyBits(recordNo1, recordNo2); 190 values[recordNo2] = values[recordNo1]; 191 } 192 Get(int record)193 override public Object Get(int record) { 194 UInt32 value = values[record]; 195 if (!value.Equals(defaultValue)) { 196 return value; 197 } 198 return GetBits(record); 199 } 200 Set(int record, Object value)201 override public void Set(int record, Object value) { 202 System.Diagnostics.Debug.Assert(null != value, "null value"); 203 if (NullValue == value) { 204 values[record] = defaultValue; 205 SetNullBit(record, true); 206 } 207 else { 208 values[record] = ((IConvertible)value).ToUInt32(FormatProvider); 209 SetNullBit(record, false); 210 } 211 } 212 SetCapacity(int capacity)213 override public void SetCapacity(int capacity) { 214 UInt32[] newValues = new UInt32[capacity]; 215 if (null != values) { 216 Array.Copy(values, 0, newValues, 0, Math.Min(capacity, values.Length)); 217 } 218 values = newValues; 219 base.SetCapacity(capacity); 220 } 221 ConvertXmlToObject(string s)222 override public object ConvertXmlToObject(string s) { 223 return XmlConvert.ToUInt32(s); 224 } 225 ConvertObjectToXml(object value)226 override public string ConvertObjectToXml(object value) { 227 return XmlConvert.ToString((UInt32)value); 228 } 229 GetEmptyStorage(int recordCount)230 override protected object GetEmptyStorage(int recordCount) { 231 return new UInt32[recordCount]; 232 } 233 CopyValue(int record, object store, BitArray nullbits, int storeIndex)234 override protected void CopyValue(int record, object store, BitArray nullbits, int storeIndex) { 235 UInt32[] typedStore = (UInt32[]) store; 236 typedStore[storeIndex] = values[record]; 237 nullbits.Set(storeIndex, !HasValue(record)); 238 } 239 SetStorage(object store, BitArray nullbits)240 override protected void SetStorage(object store, BitArray nullbits) { 241 values = (UInt32[]) store; 242 SetNullStorage(nullbits); 243 } 244 } 245 } 246