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
251251 <Compile Include="IO\Checksums\Crc16.cs" />
252252 <Compile Include="IO\Checksums\Crc32.cs" />
253253 <Compile Include="IO\Checksums\CrcCCITT.cs" />
254− <Compile Include="IO\Checksums\GuidSHA1Helper.cs" />
255254 <Compile Include="IO\Checksums\NamespaceDoc.cs" />
256255 <Compile Include="IO\Checksums\Xor16.cs" />
257256 <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−
24−using System;
25−
26−namespace 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
2828 using System.Collections.Generic;
2929 using System.Data;
3030 using GSF.Data;
31−using GSF.IO.Checksums;
3231
3332 namespace GSF.TimeSeries
3433 {
@@ -55,7 +54,7 @@ namespace GSF.TimeSeries · 20 unmodified lines
5554 m_signalID = signalID;
5655 m_id = id;
5756 m_source = source;
58− m_hashCode = GuidSHA1Helper.ComputeHashCode(signalID);
57+ m_hashCode = signalID.GetHashCode();
5958 }
6059
6160 #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