History

GSF.TimeSeries: Reverted hashcode computing for MeasurementKey to be Guid.GetHashCode() instead of SHA1. The cost outweighed the benefit.

StevenChisholm committed 12 years ago

Commit 0b39f011 parent 7451e263 files · +1 −206Browse files

Unified · Split

3 files
  1. Source/Libraries/GSF.Core/GSF.Core.csproj +0 −1
  2. Source/Libraries/GSF.Core/IO/Checksums/GuidSHA1Helper.cs +0 −203
  3. Source/Libraries/GSF.TimeSeries/MeasurementKey.cs +1 −2
Source/Libraries/GSF.Core/GSF.Core.csproj+0−1
@@ -251,7 +251,6 @@ · 250 unmodified lines
251 <Compile Include="IO\Checksums\Crc16.cs" />251 <Compile Include="IO\Checksums\Crc16.cs" />
252 <Compile Include="IO\Checksums\Crc32.cs" />252 <Compile Include="IO\Checksums\Crc32.cs" />
253 <Compile Include="IO\Checksums\CrcCCITT.cs" />253 <Compile Include="IO\Checksums\CrcCCITT.cs" />
254 <Compile Include="IO\Checksums\GuidSHA1Helper.cs" />
255 <Compile Include="IO\Checksums\NamespaceDoc.cs" />254 <Compile Include="IO\Checksums\NamespaceDoc.cs" />
256 <Compile Include="IO\Checksums\Xor16.cs" />255 <Compile Include="IO\Checksums\Xor16.cs" />
257 <Compile Include="IO\Checksums\Xor32.cs" />256 <Compile Include="IO\Checksums\Xor32.cs" />
Source/Libraries/GSF.Core/IO/Checksums/GuidSHA1Helper.cs+0−203
@@ -1,203 +0,0 @@
1//******************************************************************************************************
2// GuidSHA1Helper.cs - Gbtc
3//
4// Copyright © 2014, Grid Protection Alliance. All Rights Reserved.
5//
6// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
7// the NOTICE file distributed with this work for additional information regarding copyright ownership.
8// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
9// not use this file except in compliance with the License. You may obtain a copy of the License at:
10//
11// http://www.opensource.org/licenses/eclipse-1.0.php
12//
13// Unless agreed to in writing, the subject software distributed under the License is distributed on an
14// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
15// License for the specific language governing permissions and limitations.
16//
17// Code Modification History:
18// ----------------------------------------------------------------------------------------------------
19// 04/27/2014 - Steven E. Chisholm
20// Generated original version of source code.
21//
22//******************************************************************************************************
23
24using System;
25
26namespace GSF.IO.Checksums
27{
28 /// <summary>
29 /// This class is a helper class to quickly generate a strong hash code for a GUID type.
30 /// </summary>
31 /// <remarks>
32 /// A strong hash function is important in Dictionary Lookups. If the hash is sufficently strong,
33 /// a mod operation over the largest prime can be avoided, thus allowing for faster customized dictionary lookups.
34 ///
35 /// Method is the same as taking the first 4 bytes of a SHA1 hashsum, except zero is reserved and converted to 1.
36 ///
37 /// Customized implementation is about twice as fast as .NET's and requires no class allocation.
38 /// All memory is allocated on the stack (approximately 400 bytes)
39 /// </remarks>
40 public unsafe class GuidSHA1Helper
41 {
42 private const uint Y1 = 0x5a827999;
43 private const uint Y2 = 0x6ed9eba1;
44 private const uint Y3 = 0x8f1bbcdc;
45 private const uint Y4 = 0xca62c1d6;
46
47 /// <summary>
48 /// Computes the non-zero hashcode of the <see cref="input"/>.
49 /// </summary>
50 /// <param name="input"></param>
51 /// <returns>
52 /// A Non-zero hash of the <see cref="input"/>. If the hash would have been 0, the value 1 is substituded.
53 /// </returns>
54 public static int ComputeHashCode(Guid input)
55 {
56 uint* hash = stackalloc uint[5];
57 byte* hashBlock = stackalloc byte[80 * 4];
58
59 //Initialize
60 hash[0] = 0x67452301;
61 hash[1] = 0xefcdab89;
62 hash[2] = 0x98badcfe;
63 hash[3] = 0x10325476;
64 hash[4] = 0xc3d2e1f0;
65
66 //Write GUID to buffer
67 *(Guid*)(hashBlock) = input;
68
69 const long bitLength = (16 << 3);
70 hashBlock[16] = 128;
71
72 //Clear hash
73 for (int x = 17; x < 56; x++)
74 hashBlock[x] = 0;
75
76 hashBlock[56] = (byte)(bitLength >> 56);
77 hashBlock[57] = (byte)(bitLength >> 48);
78 hashBlock[58] = (byte)(bitLength >> 40);
79 hashBlock[59] = (byte)(bitLength >> 32);
80 hashBlock[60] = (byte)(bitLength >> 24);
81 hashBlock[61] = (byte)(bitLength >> 16);
82 hashBlock[62] = (byte)(bitLength >> 8);
83 hashBlock[63] = (byte)(bitLength);
84
85 if (BitConverter.IsLittleEndian)
86 SwapEndianSha((ulong*)hashBlock, (ulong*)hashBlock);
87 InternalHashBlock(hash, (uint*)hashBlock);
88
89 //Checksum is bigEndian, read as an interger.
90 //Read big endian
91 int sum = *((byte*)hash + 0) << 24 |
92 *((byte*)hash + 1) << 16 |
93 *((byte*)hash + 2) << 8 |
94 *((byte*)hash + 3);
95
96 if (sum == 0)
97 return 1;
98 return sum;
99 }
100
101 /// <summary>
102 /// Computes the hash of the blocks. Words must already be in big endian format.
103 /// </summary>
104 /// <param name="hash">the current values of the hash</param>
105 /// <param name="words">16 words that are already in big endian format.</param>
106 static void InternalHashBlock(uint* hash, uint* words)
107 {
108 uint a = hash[0];
109 uint b = hash[1];
110 uint c = hash[2];
111 uint d = hash[3];
112 uint e = hash[4];
113 uint* x = words;
114 int i;
115 //
116 // expand 16 word block into 80 word block.
117 //
118 for (i = 0; i < 64; i++)
119 {
120 uint t = x[13] ^ x[8] ^ x[2] ^ x[0];
121 x[16] = t << 1 | t >> 31;
122 x++;
123 }
124
125 //
126 // round 1
127 //
128 x = words;
129
130 for (i = 0; i < 4; i++)
131 {
132 // E = rotateLeft(A, 5) + F(B, C, D) + E + X[idx++] + Y1
133 // B = rotateLeft(B, 30)
134 e += (a << 5 | (a >> 27)) + ((b & c) | (~b & d)) + x[0] + Y1; b = b << 30 | (b >> 2);
135 d += (e << 5 | (e >> 27)) + ((a & b) | (~a & c)) + x[1] + Y1; a = a << 30 | (a >> 2);
136 c += (d << 5 | (d >> 27)) + ((e & a) | (~e & b)) + x[2] + Y1; e = e << 30 | (e >> 2);
137 b += (c << 5 | (c >> 27)) + ((d & e) | (~d & a)) + x[3] + Y1; d = d << 30 | (d >> 2);
138 a += (b << 5 | (b >> 27)) + ((c & d) | (~c & e)) + x[4] + Y1; c = c << 30 | (c >> 2); x += 5;
139 }
140
141 //
142 // round 2
143 //
144 for (i = 0; i < 4; i++)
145 {
146 // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y2
147 // B = rotateLeft(B, 30)
148 e += (a << 5 | (a >> 27)) + (b ^ c ^ d) + x[0] + Y2; b = b << 30 | (b >> 2);
149 d += (e << 5 | (e >> 27)) + (a ^ b ^ c) + x[1] + Y2; a = a << 30 | (a >> 2);
150 c += (d << 5 | (d >> 27)) + (e ^ a ^ b) + x[2] + Y2; e = e << 30 | (e >> 2);
151 b += (c << 5 | (c >> 27)) + (d ^ e ^ a) + x[3] + Y2; d = d << 30 | (d >> 2);
152 a += (b << 5 | (b >> 27)) + (c ^ d ^ e) + x[4] + Y2; c = c << 30 | (c >> 2); x += 5;
153 }
154
155 //
156 // round 3
157 //
158 for (i = 0; i < 4; i++)
159 {
160 // E = rotateLeft(A, 5) + G(B, C, D) + E + X[idx++] + Y3
161 // B = rotateLeft(B, 30)
162 e += (a << 5 | (a >> 27)) + ((b & c) | (b & d) | (c & d)) + x[0] + Y3; b = b << 30 | (b >> 2);
163 d += (e << 5 | (e >> 27)) + ((a & b) | (a & c) | (b & c)) + x[1] + Y3; a = a << 30 | (a >> 2);
164 c += (d << 5 | (d >> 27)) + ((e & a) | (e & b) | (a & b)) + x[2] + Y3; e = e << 30 | (e >> 2);
165 b += (c << 5 | (c >> 27)) + ((d & e) | (d & a) | (e & a)) + x[3] + Y3; d = d << 30 | (d >> 2);
166 a += (b << 5 | (b >> 27)) + ((c & d) | (c & e) | (d & e)) + x[4] + Y3; c = c << 30 | (c >> 2); x += 5;
167 }
168
169 //
170 // round 4
171 //
172 for (i = 0; i < 4; i++)
173 {
174 // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y4
175 // B = rotateLeft(B, 30)
176 e += (a << 5 | (a >> 27)) + (b ^ c ^ d) + x[0] + Y4; b = b << 30 | (b >> 2);
177 d += (e << 5 | (e >> 27)) + (a ^ b ^ c) + x[1] + Y4; a = a << 30 | (a >> 2);
178 c += (d << 5 | (d >> 27)) + (e ^ a ^ b) + x[2] + Y4; e = e << 30 | (e >> 2);
179 b += (c << 5 | (c >> 27)) + (d ^ e ^ a) + x[3] + Y4; d = d << 30 | (d >> 2);
180 a += (b << 5 | (b >> 27)) + (c ^ d ^ e) + x[4] + Y4; c = c << 30 | (c >> 2); x += 5;
181 }
182
183 hash[0] += a;
184 hash[1] += b;
185 hash[2] += c;
186 hash[3] += d;
187 hash[4] += e;
188 }
189
190 static unsafe void SwapEndianSha(ulong* src, ulong* dst)
191 {
192 ulong value;
193 value = src[0]; dst[0] = ((0xFF000000FF000000 & value) >> 24) | ((0x00FF000000FF0000 & value) >> 8) | ((0x0000FF000000FF00 & value) << 8) | ((0x000000FF000000FF & value) << 24);
194 value = src[1]; dst[1] = ((0xFF000000FF000000 & value) >> 24) | ((0x00FF000000FF0000 & value) >> 8) | ((0x0000FF000000FF00 & value) << 8) | ((0x000000FF000000FF & value) << 24);
195 value = src[2]; dst[2] = ((0xFF000000FF000000 & value) >> 24) | ((0x00FF000000FF0000 & value) >> 8) | ((0x0000FF000000FF00 & value) << 8) | ((0x000000FF000000FF & value) << 24);
196 value = src[3]; dst[3] = ((0xFF000000FF000000 & value) >> 24) | ((0x00FF000000FF0000 & value) >> 8) | ((0x0000FF000000FF00 & value) << 8) | ((0x000000FF000000FF & value) << 24);
197 value = src[4]; dst[4] = ((0xFF000000FF000000 & value) >> 24) | ((0x00FF000000FF0000 & value) >> 8) | ((0x0000FF000000FF00 & value) << 8) | ((0x000000FF000000FF & value) << 24);
198 value = src[5]; dst[5] = ((0xFF000000FF000000 & value) >> 24) | ((0x00FF000000FF0000 & value) >> 8) | ((0x0000FF000000FF00 & value) << 8) | ((0x000000FF000000FF & value) << 24);
199 value = src[6]; dst[6] = ((0xFF000000FF000000 & value) >> 24) | ((0x00FF000000FF0000 & value) >> 8) | ((0x0000FF000000FF00 & value) << 8) | ((0x000000FF000000FF & value) << 24);
200 value = src[7]; dst[7] = ((0xFF000000FF000000 & value) >> 24) | ((0x00FF000000FF0000 & value) >> 8) | ((0x0000FF000000FF00 & value) << 8) | ((0x000000FF000000FF & value) << 24);
201 }
202 }
203}
Source/Libraries/GSF.TimeSeries/MeasurementKey.cs+1−2
@@ -28,7 +28,6 @@ using System.Collections.Concurrent; · 27 unmodified lines
28using System.Collections.Generic;28using System.Collections.Generic;
29using System.Data;29using System.Data;
30using GSF.Data;30using GSF.Data;
31using GSF.IO.Checksums;
32 31
33namespace GSF.TimeSeries32namespace GSF.TimeSeries
34{33{
@@ -55,7 +54,7 @@ namespace GSF.TimeSeries · 20 unmodified lines
55 m_signalID = signalID;54 m_signalID = signalID;
56 m_id = id;55 m_id = id;
57 m_source = source;56 m_source = source;
58 m_hashCode = GuidSHA1Helper.ComputeHashCode(signalID);57 m_hashCode = signalID.GetHashCode();
59 }58 }
60 59
61 #endregion60 #endregion

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t