~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/NGit/NGit.Storage.Pack/DeltaIndex.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
This code is derived from jgit (http://eclipse.org/jgit).
 
3
Copyright owners are documented in jgit's IP log.
 
4
 
 
5
This program and the accompanying materials are made available
 
6
under the terms of the Eclipse Distribution License v1.0 which
 
7
accompanies this distribution, is reproduced below, and is
 
8
available at http://www.eclipse.org/org/documents/edl-v10.php
 
9
 
 
10
All rights reserved.
 
11
 
 
12
Redistribution and use in source and binary forms, with or
 
13
without modification, are permitted provided that the following
 
14
conditions are met:
 
15
 
 
16
- Redistributions of source code must retain the above copyright
 
17
  notice, this list of conditions and the following disclaimer.
 
18
 
 
19
- Redistributions in binary form must reproduce the above
 
20
  copyright notice, this list of conditions and the following
 
21
  disclaimer in the documentation and/or other materials provided
 
22
  with the distribution.
 
23
 
 
24
- Neither the name of the Eclipse Foundation, Inc. nor the
 
25
  names of its contributors may be used to endorse or promote
 
26
  products derived from this software without specific prior
 
27
  written permission.
 
28
 
 
29
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 
30
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 
31
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
32
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
33
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 
34
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
35
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
36
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
37
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
38
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
39
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
40
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
41
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
42
*/
 
43
 
 
44
using NGit.Storage.Pack;
 
45
using Sharpen;
 
46
 
 
47
namespace NGit.Storage.Pack
 
48
{
 
49
        /// <summary>Index of blocks in a source file.</summary>
 
50
        /// <remarks>
 
51
        /// Index of blocks in a source file.
 
52
        /// <p>
 
53
        /// The index can be passed a result buffer, and output an instruction sequence
 
54
        /// that transforms the source buffer used by the index into the result buffer.
 
55
        /// The instruction sequence can be executed by
 
56
        /// <see cref="BinaryDelta">BinaryDelta</see>
 
57
        /// or
 
58
        /// <see cref="DeltaStream">DeltaStream</see>
 
59
        /// to recreate the result buffer.
 
60
        /// <p>
 
61
        /// An index stores the entire contents of the source buffer, but also a table of
 
62
        /// block identities mapped to locations where the block appears in the source
 
63
        /// buffer. The mapping table uses 12 bytes for every 16 bytes of source buffer,
 
64
        /// and is therefore ~75% of the source buffer size. The overall index is ~1.75x
 
65
        /// the size of the source buffer. This relationship holds for any JVM, as only a
 
66
        /// constant number of objects are allocated per index. Callers can use the
 
67
        /// method
 
68
        /// <see cref="GetIndexSize()">GetIndexSize()</see>
 
69
        /// to obtain a reasonably accurate estimate of
 
70
        /// the complete heap space used by this index.
 
71
        /// <p>
 
72
        /// A
 
73
        /// <code>DeltaIndex</code>
 
74
        /// is thread-safe. Concurrent threads can use the same
 
75
        /// index to encode delta instructions for different result buffers.
 
76
        /// </remarks>
 
77
        public class DeltaIndex
 
78
        {
 
79
                /// <summary>Number of bytes in a block.</summary>
 
80
                /// <remarks>Number of bytes in a block.</remarks>
 
81
                internal const int BLKSZ = 16;
 
82
 
 
83
                // must be 16, see unrolled loop in hashBlock
 
84
                /// <summary>Estimate the size of an index for a given source.</summary>
 
85
                /// <remarks>
 
86
                /// Estimate the size of an index for a given source.
 
87
                /// <p>
 
88
                /// This is roughly a worst-case estimate. The actual index may be smaller.
 
89
                /// </remarks>
 
90
                /// <param name="sourceLength">length of the source, in bytes.</param>
 
91
                /// <returns>
 
92
                /// estimated size. Approximately
 
93
                /// <code>1.75 * sourceLength</code>
 
94
                /// .
 
95
                /// </returns>
 
96
                public static long EstimateIndexSize(int sourceLength)
 
97
                {
 
98
                        return sourceLength + (sourceLength * 3 / 4);
 
99
                }
 
100
 
 
101
                /// <summary>Maximum number of positions to consider for a given content hash.</summary>
 
102
                /// <remarks>
 
103
                /// Maximum number of positions to consider for a given content hash.
 
104
                /// <p>
 
105
                /// All positions with the same content hash are stored into a single chain.
 
106
                /// The chain size is capped to ensure delta encoding stays linear time at
 
107
                /// O(len_src + len_dst) rather than quadratic at O(len_src * len_dst).
 
108
                /// </remarks>
 
109
                private const int MAX_CHAIN_LENGTH = 64;
 
110
 
 
111
                /// <summary>Original source file that we indexed.</summary>
 
112
                /// <remarks>Original source file that we indexed.</remarks>
 
113
                private readonly byte[] src;
 
114
 
 
115
                /// <summary>
 
116
                /// Pointers into the
 
117
                /// <see cref="entries">entries</see>
 
118
                /// table, indexed by block hash.
 
119
                /// <p>
 
120
                /// A block hash is masked with
 
121
                /// <see cref="tableMask">tableMask</see>
 
122
                /// to become the array index
 
123
                /// of this table. The value stored here is the first index within
 
124
                /// <see cref="entries">entries</see>
 
125
                /// that starts the consecutive list of blocks with that
 
126
                /// same masked hash. If there are no matching blocks, 0 is stored instead.
 
127
                /// <p>
 
128
                /// Note that this table is always a power of 2 in size, to support fast
 
129
                /// normalization of a block hash into an array index.
 
130
                /// </summary>
 
131
                private readonly int[] table;
 
132
 
 
133
                /// <summary>
 
134
                /// Pairs of block hash value and
 
135
                /// <see cref="src">src</see>
 
136
                /// offsets.
 
137
                /// <p>
 
138
                /// The very first entry in this table at index 0 is always empty, this is to
 
139
                /// allow fast evaluation when
 
140
                /// <see cref="table">table</see>
 
141
                /// has no values under any given
 
142
                /// slot. Remaining entries are pairs of integers, with the upper 32 bits
 
143
                /// holding the block hash and the lower 32 bits holding the source offset.
 
144
                /// </summary>
 
145
                private readonly long[] entries;
 
146
 
 
147
                /// <summary>
 
148
                /// Mask to make block hashes into an array index for
 
149
                /// <see cref="table">table</see>
 
150
                /// .
 
151
                /// </summary>
 
152
                private readonly int tableMask;
 
153
 
 
154
                /// <summary>Construct an index from the source file.</summary>
 
155
                /// <remarks>Construct an index from the source file.</remarks>
 
156
                /// <param name="sourceBuffer">
 
157
                /// the source file's raw contents. The buffer will be held by the
 
158
                /// index instance to facilitate matching, and therefore must not
 
159
                /// be modified by the caller.
 
160
                /// </param>
 
161
                public DeltaIndex(byte[] sourceBuffer)
 
162
                {
 
163
                        src = sourceBuffer;
 
164
                        DeltaIndexScanner scan = new DeltaIndexScanner(src, src.Length);
 
165
                        // Reuse the same table the scanner made. We will replace the
 
166
                        // values at each position, but we want the same-length array.
 
167
                        //
 
168
                        table = scan.table;
 
169
                        tableMask = scan.tableMask;
 
170
                        // Because entry index 0 means there are no entries for the
 
171
                        // slot in the table, we have to allocate one extra position.
 
172
                        //
 
173
                        entries = new long[1 + CountEntries(scan)];
 
174
                        CopyEntries(scan);
 
175
                }
 
176
 
 
177
                private int CountEntries(DeltaIndexScanner scan)
 
178
                {
 
179
                        // Figure out exactly how many entries we need. As we do the
 
180
                        // enumeration truncate any delta chains longer than what we
 
181
                        // are willing to scan during encode. This keeps the encode
 
182
                        // logic linear in the size of the input rather than quadratic.
 
183
                        //
 
184
                        int cnt = 0;
 
185
                        for (int i = 0; i < table.Length; i++)
 
186
                        {
 
187
                                int h = table[i];
 
188
                                if (h == 0)
 
189
                                {
 
190
                                        continue;
 
191
                                }
 
192
                                int len = 0;
 
193
                                do
 
194
                                {
 
195
                                        if (++len == MAX_CHAIN_LENGTH)
 
196
                                        {
 
197
                                                scan.next[h] = 0;
 
198
                                                break;
 
199
                                        }
 
200
                                        h = scan.next[h];
 
201
                                }
 
202
                                while (h != 0);
 
203
                                cnt += len;
 
204
                        }
 
205
                        return cnt;
 
206
                }
 
207
 
 
208
                private void CopyEntries(DeltaIndexScanner scan)
 
209
                {
 
210
                        // Rebuild the entries list from the scanner, positioning all
 
211
                        // blocks in the same hash chain next to each other. We can
 
212
                        // then later discard the next list, along with the scanner.
 
213
                        //
 
214
                        int next = 1;
 
215
                        for (int i = 0; i < table.Length; i++)
 
216
                        {
 
217
                                int h = table[i];
 
218
                                if (h == 0)
 
219
                                {
 
220
                                        continue;
 
221
                                }
 
222
                                table[i] = next;
 
223
                                do
 
224
                                {
 
225
                                        entries[next++] = scan.entries[h];
 
226
                                        h = scan.next[h];
 
227
                                }
 
228
                                while (h != 0);
 
229
                        }
 
230
                }
 
231
 
 
232
                /// <returns>size of the source buffer this index has scanned.</returns>
 
233
                public virtual long GetSourceSize()
 
234
                {
 
235
                        return src.Length;
 
236
                }
 
237
 
 
238
                /// <summary>Get an estimate of the memory required by this index.</summary>
 
239
                /// <remarks>Get an estimate of the memory required by this index.</remarks>
 
240
                /// <returns>
 
241
                /// an approximation of the number of bytes used by this index in
 
242
                /// memory. The size includes the cached source buffer size from
 
243
                /// <see cref="GetSourceSize()">GetSourceSize()</see>
 
244
                /// , as well as a rough approximation of JVM
 
245
                /// object overheads.
 
246
                /// </returns>
 
247
                public virtual long GetIndexSize()
 
248
                {
 
249
                        long sz = 8;
 
250
                        sz += 4 * 4;
 
251
                        sz += SizeOf(src);
 
252
                        sz += SizeOf(table);
 
253
                        sz += SizeOf(entries);
 
254
                        return sz;
 
255
                }
 
256
 
 
257
                private static long SizeOf(byte[] b)
 
258
                {
 
259
                        return SizeOfArray(1, b.Length);
 
260
                }
 
261
 
 
262
                private static long SizeOf(int[] b)
 
263
                {
 
264
                        return SizeOfArray(4, b.Length);
 
265
                }
 
266
 
 
267
                private static long SizeOf(long[] b)
 
268
                {
 
269
                        return SizeOfArray(8, b.Length);
 
270
                }
 
271
 
 
272
                private static int SizeOfArray(int entSize, int len)
 
273
                {
 
274
                        return 12 + (len * entSize);
 
275
                }
 
276
 
 
277
                /// <summary>Generate a delta sequence to recreate the result buffer.</summary>
 
278
                /// <remarks>
 
279
                /// Generate a delta sequence to recreate the result buffer.
 
280
                /// <p>
 
281
                /// There is no limit on the size of the delta sequence created. This is the
 
282
                /// same as
 
283
                /// <code>encode(out, res, 0)</code>
 
284
                /// .
 
285
                /// </remarks>
 
286
                /// <param name="out">
 
287
                /// stream to receive the delta instructions that can transform
 
288
                /// this index's source buffer into
 
289
                /// <code>res</code>
 
290
                /// . This stream
 
291
                /// should be buffered, as instructions are written directly to it
 
292
                /// in small bursts.
 
293
                /// </param>
 
294
                /// <param name="res">
 
295
                /// the desired result buffer. The generated instructions will
 
296
                /// recreate this buffer when applied to the source buffer stored
 
297
                /// within this index.
 
298
                /// </param>
 
299
                /// <exception cref="System.IO.IOException">the output stream refused to write the instructions.
 
300
                ///     </exception>
 
301
                public virtual void Encode(OutputStream @out, byte[] res)
 
302
                {
 
303
                        Encode(@out, res, 0);
 
304
                }
 
305
 
 
306
                /// <summary>Generate a delta sequence to recreate the result buffer.</summary>
 
307
                /// <remarks>Generate a delta sequence to recreate the result buffer.</remarks>
 
308
                /// <param name="out">
 
309
                /// stream to receive the delta instructions that can transform
 
310
                /// this index's source buffer into
 
311
                /// <code>res</code>
 
312
                /// . This stream
 
313
                /// should be buffered, as instructions are written directly to it
 
314
                /// in small bursts. If the caller might need to discard the
 
315
                /// instructions (such as when deltaSizeLimit would be exceeded)
 
316
                /// the caller is responsible for discarding or rewinding the
 
317
                /// stream when this method returns false.
 
318
                /// </param>
 
319
                /// <param name="res">
 
320
                /// the desired result buffer. The generated instructions will
 
321
                /// recreate this buffer when applied to the source buffer stored
 
322
                /// within this index.
 
323
                /// </param>
 
324
                /// <param name="deltaSizeLimit">
 
325
                /// maximum number of bytes that the delta instructions can
 
326
                /// occupy. If the generated instructions would be longer than
 
327
                /// this amount, this method returns false. If 0, there is no
 
328
                /// limit on the length of delta created.
 
329
                /// </param>
 
330
                /// <returns>
 
331
                /// true if the delta is smaller than deltaSizeLimit; false if the
 
332
                /// encoder aborted because the encoded delta instructions would be
 
333
                /// longer than deltaSizeLimit bytes.
 
334
                /// </returns>
 
335
                /// <exception cref="System.IO.IOException">the output stream refused to write the instructions.
 
336
                ///     </exception>
 
337
                public virtual bool Encode(OutputStream @out, byte[] res, int deltaSizeLimit)
 
338
                {
 
339
                        int end = res.Length;
 
340
                        DeltaEncoder enc = NewEncoder(@out, end, deltaSizeLimit);
 
341
                        // If either input is smaller than one full block, we simply punt
 
342
                        // and construct a delta as a literal. This implies that any file
 
343
                        // smaller than our block size is never delta encoded as the delta
 
344
                        // will always be larger than the file itself would be.
 
345
                        //
 
346
                        if (end < BLKSZ || table.Length == 0)
 
347
                        {
 
348
                                return enc.Insert(res);
 
349
                        }
 
350
                        // Bootstrap the scan by constructing a hash for the first block
 
351
                        // in the input.
 
352
                        //
 
353
                        int blkPtr = 0;
 
354
                        int blkEnd = BLKSZ;
 
355
                        int hash = HashBlock(res, 0);
 
356
                        int resPtr = 0;
 
357
                        while (blkEnd < end)
 
358
                        {
 
359
                                int tableIdx = hash & tableMask;
 
360
                                int entryIdx = table[tableIdx];
 
361
                                if (entryIdx == 0)
 
362
                                {
 
363
                                        // No matching blocks, slide forward one byte.
 
364
                                        //
 
365
                                        hash = Step(hash, res[blkPtr++], res[blkEnd++]);
 
366
                                        continue;
 
367
                                }
 
368
                                // For every possible location of the current block, try to
 
369
                                // extend the match out to the longest common substring.
 
370
                                //
 
371
                                int bestLen = -1;
 
372
                                int bestPtr = -1;
 
373
                                int bestNeg = 0;
 
374
                                do
 
375
                                {
 
376
                                        long ent = entries[entryIdx++];
 
377
                                        if (KeyOf(ent) == hash)
 
378
                                        {
 
379
                                                int neg = 0;
 
380
                                                if (resPtr < blkPtr)
 
381
                                                {
 
382
                                                        // If we need to do an insertion, check to see if
 
383
                                                        // moving the starting point of the copy backwards
 
384
                                                        // will allow us to shorten the insert. Our hash
 
385
                                                        // may not have allowed us to identify this area.
 
386
                                                        // Since it is quite fast to perform a negative
 
387
                                                        // scan, try to stretch backwards too.
 
388
                                                        //
 
389
                                                        neg = blkPtr - resPtr;
 
390
                                                        neg = Negmatch(res, blkPtr, src, ValOf(ent), neg);
 
391
                                                }
 
392
                                                int len = neg + Fwdmatch(res, blkPtr, src, ValOf(ent));
 
393
                                                if (bestLen < len)
 
394
                                                {
 
395
                                                        bestLen = len;
 
396
                                                        bestPtr = ValOf(ent);
 
397
                                                        bestNeg = neg;
 
398
                                                }
 
399
                                        }
 
400
                                        else
 
401
                                        {
 
402
                                                if ((KeyOf(ent) & tableMask) != tableIdx)
 
403
                                                {
 
404
                                                        break;
 
405
                                                }
 
406
                                        }
 
407
                                }
 
408
                                while (bestLen < 4096 && entryIdx < entries.Length);
 
409
                                if (bestLen < BLKSZ)
 
410
                                {
 
411
                                        // All of the locations were false positives, or the copy
 
412
                                        // is shorter than a block. In the latter case this won't
 
413
                                        // give us a very great copy instruction, so delay and try
 
414
                                        // at the next byte.
 
415
                                        //
 
416
                                        hash = Step(hash, res[blkPtr++], res[blkEnd++]);
 
417
                                        continue;
 
418
                                }
 
419
                                blkPtr -= bestNeg;
 
420
                                if (resPtr < blkPtr)
 
421
                                {
 
422
                                        // There are bytes between the last instruction we made
 
423
                                        // and the current block pointer. None of these matched
 
424
                                        // during the earlier iteration so insert them directly
 
425
                                        // into the instruction stream.
 
426
                                        //
 
427
                                        int cnt = blkPtr - resPtr;
 
428
                                        if (!enc.Insert(res, resPtr, cnt))
 
429
                                        {
 
430
                                                return false;
 
431
                                        }
 
432
                                }
 
433
                                if (!enc.Copy(bestPtr - bestNeg, bestLen))
 
434
                                {
 
435
                                        return false;
 
436
                                }
 
437
                                blkPtr += bestLen;
 
438
                                resPtr = blkPtr;
 
439
                                blkEnd = blkPtr + BLKSZ;
 
440
                                // If we don't have a full block available to us, abort now.
 
441
                                //
 
442
                                if (end <= blkEnd)
 
443
                                {
 
444
                                        break;
 
445
                                }
 
446
                                // Start a new hash of the block after the copy region.
 
447
                                //
 
448
                                hash = HashBlock(res, blkPtr);
 
449
                        }
 
450
                        if (resPtr < end)
 
451
                        {
 
452
                                // There were bytes at the end which didn't match, or maybe
 
453
                                // didn't make a full block. Insert whatever is left over.
 
454
                                //
 
455
                                int cnt = end - resPtr;
 
456
                                return enc.Insert(res, resPtr, cnt);
 
457
                        }
 
458
                        return true;
 
459
                }
 
460
 
 
461
                /// <exception cref="System.IO.IOException"></exception>
 
462
                private DeltaEncoder NewEncoder(OutputStream @out, long resSize, int limit)
 
463
                {
 
464
                        return new DeltaEncoder(@out, GetSourceSize(), resSize, limit);
 
465
                }
 
466
 
 
467
                private static int Fwdmatch(byte[] res, int resPtr, byte[] src, int srcPtr)
 
468
                {
 
469
                        int start = resPtr;
 
470
                        for (; resPtr < res.Length && srcPtr < src.Length; resPtr++, srcPtr++)
 
471
                        {
 
472
                                if (res[resPtr] != src[srcPtr])
 
473
                                {
 
474
                                        break;
 
475
                                }
 
476
                        }
 
477
                        return resPtr - start;
 
478
                }
 
479
 
 
480
                private static int Negmatch(byte[] res, int resPtr, byte[] src, int srcPtr, int limit
 
481
                        )
 
482
                {
 
483
                        if (srcPtr == 0)
 
484
                        {
 
485
                                return 0;
 
486
                        }
 
487
                        resPtr--;
 
488
                        srcPtr--;
 
489
                        int start = resPtr;
 
490
                        do
 
491
                        {
 
492
                                if (res[resPtr] != src[srcPtr])
 
493
                                {
 
494
                                        break;
 
495
                                }
 
496
                                resPtr--;
 
497
                                srcPtr--;
 
498
                        }
 
499
                        while (0 <= srcPtr && 0 < --limit);
 
500
                        return start - resPtr;
 
501
                }
 
502
 
 
503
                public override string ToString()
 
504
                {
 
505
                        string[] units = new string[] { "bytes", "KiB", "MiB", "GiB" };
 
506
                        long sz = GetIndexSize();
 
507
                        int u = 0;
 
508
                        while (1024 <= sz && u < units.Length - 1)
 
509
                        {
 
510
                                int rem = (int)(sz % 1024);
 
511
                                sz /= 1024;
 
512
                                if (rem != 0)
 
513
                                {
 
514
                                        sz++;
 
515
                                }
 
516
                                u++;
 
517
                        }
 
518
                        return "DeltaIndex[" + sz + " " + units[u] + "]";
 
519
                }
 
520
 
 
521
                internal static int HashBlock(byte[] raw, int ptr)
 
522
                {
 
523
                        int hash;
 
524
                        // The first 4 steps collapse out into a 4 byte big-endian decode,
 
525
                        // with a larger right shift as we combined shift lefts together.
 
526
                        //
 
527
                        hash = ((raw[ptr] & unchecked((int)(0xff))) << 24) | ((raw[ptr + 1] & unchecked((
 
528
                                int)(0xff))) << 16) | ((raw[ptr + 2] & unchecked((int)(0xff))) << 8) | (raw[ptr 
 
529
                                + 3] & unchecked((int)(0xff)));
 
530
                        //
 
531
                        //
 
532
                        //
 
533
                        hash ^= T[(int)(((uint)hash) >> 31)];
 
534
                        hash = ((hash << 8) | (raw[ptr + 4] & unchecked((int)(0xff)))) ^ T[(int)(((uint)hash
 
535
                                ) >> 23)];
 
536
                        hash = ((hash << 8) | (raw[ptr + 5] & unchecked((int)(0xff)))) ^ T[(int)(((uint)hash
 
537
                                ) >> 23)];
 
538
                        hash = ((hash << 8) | (raw[ptr + 6] & unchecked((int)(0xff)))) ^ T[(int)(((uint)hash
 
539
                                ) >> 23)];
 
540
                        hash = ((hash << 8) | (raw[ptr + 7] & unchecked((int)(0xff)))) ^ T[(int)(((uint)hash
 
541
                                ) >> 23)];
 
542
                        hash = ((hash << 8) | (raw[ptr + 8] & unchecked((int)(0xff)))) ^ T[(int)(((uint)hash
 
543
                                ) >> 23)];
 
544
                        hash = ((hash << 8) | (raw[ptr + 9] & unchecked((int)(0xff)))) ^ T[(int)(((uint)hash
 
545
                                ) >> 23)];
 
546
                        hash = ((hash << 8) | (raw[ptr + 10] & unchecked((int)(0xff)))) ^ T[(int)(((uint)
 
547
                                hash) >> 23)];
 
548
                        hash = ((hash << 8) | (raw[ptr + 11] & unchecked((int)(0xff)))) ^ T[(int)(((uint)
 
549
                                hash) >> 23)];
 
550
                        hash = ((hash << 8) | (raw[ptr + 12] & unchecked((int)(0xff)))) ^ T[(int)(((uint)
 
551
                                hash) >> 23)];
 
552
                        hash = ((hash << 8) | (raw[ptr + 13] & unchecked((int)(0xff)))) ^ T[(int)(((uint)
 
553
                                hash) >> 23)];
 
554
                        hash = ((hash << 8) | (raw[ptr + 14] & unchecked((int)(0xff)))) ^ T[(int)(((uint)
 
555
                                hash) >> 23)];
 
556
                        hash = ((hash << 8) | (raw[ptr + 15] & unchecked((int)(0xff)))) ^ T[(int)(((uint)
 
557
                                hash) >> 23)];
 
558
                        return hash;
 
559
                }
 
560
 
 
561
                private static int Step(int hash, byte toRemove, byte toAdd)
 
562
                {
 
563
                        hash ^= U[toRemove & unchecked((int)(0xff))];
 
564
                        return ((hash << 8) | (toAdd & unchecked((int)(0xff)))) ^ T[(int)(((uint)hash) >>
 
565
                                 23)];
 
566
                }
 
567
 
 
568
                private static int KeyOf(long ent)
 
569
                {
 
570
                        return (int)((long)(((ulong)ent) >> 32));
 
571
                }
 
572
 
 
573
                private static int ValOf(long ent)
 
574
                {
 
575
                        return (int)ent;
 
576
                }
 
577
 
 
578
                private static readonly int[] T = new int[] { unchecked((int)(0x00000000)), unchecked(
 
579
                        (int)(0xd4c6b32d)), unchecked((int)(0x7d4bd577)), unchecked((int)(0xa98d665a)), 
 
580
                        unchecked((int)(0x2e5119c3)), unchecked((int)(0xfa97aaee)), unchecked((int)(0x531accb4
 
581
                        )), unchecked((int)(0x87dc7f99)), unchecked((int)(0x5ca23386)), unchecked((int)(
 
582
                        0x886480ab)), unchecked((int)(0x21e9e6f1)), unchecked((int)(0xf52f55dc)), unchecked(
 
583
                        (int)(0x72f32a45)), unchecked((int)(0xa6359968)), unchecked((int)(0x0fb8ff32)), 
 
584
                        unchecked((int)(0xdb7e4c1f)), unchecked((int)(0x6d82d421)), unchecked((int)(0xb944670c
 
585
                        )), unchecked((int)(0x10c90156)), unchecked((int)(0xc40fb27b)), unchecked((int)(
 
586
                        0x43d3cde2)), unchecked((int)(0x97157ecf)), unchecked((int)(0x3e981895)), unchecked(
 
587
                        (int)(0xea5eabb8)), unchecked((int)(0x3120e7a7)), unchecked((int)(0xe5e6548a)), 
 
588
                        unchecked((int)(0x4c6b32d0)), unchecked((int)(0x98ad81fd)), unchecked((int)(0x1f71fe64
 
589
                        )), unchecked((int)(0xcbb74d49)), unchecked((int)(0x623a2b13)), unchecked((int)(
 
590
                        0xb6fc983e)), unchecked((int)(0x0fc31b6f)), unchecked((int)(0xdb05a842)), unchecked(
 
591
                        (int)(0x7288ce18)), unchecked((int)(0xa64e7d35)), unchecked((int)(0x219202ac)), 
 
592
                        unchecked((int)(0xf554b181)), unchecked((int)(0x5cd9d7db)), unchecked((int)(0x881f64f6
 
593
                        )), unchecked((int)(0x536128e9)), unchecked((int)(0x87a79bc4)), unchecked((int)(
 
594
                        0x2e2afd9e)), unchecked((int)(0xfaec4eb3)), unchecked((int)(0x7d30312a)), unchecked(
 
595
                        (int)(0xa9f68207)), unchecked((int)(0x007be45d)), unchecked((int)(0xd4bd5770)), 
 
596
                        unchecked((int)(0x6241cf4e)), unchecked((int)(0xb6877c63)), unchecked((int)(0x1f0a1a39
 
597
                        )), unchecked((int)(0xcbcca914)), unchecked((int)(0x4c10d68d)), unchecked((int)(
 
598
                        0x98d665a0)), unchecked((int)(0x315b03fa)), unchecked((int)(0xe59db0d7)), unchecked(
 
599
                        (int)(0x3ee3fcc8)), unchecked((int)(0xea254fe5)), unchecked((int)(0x43a829bf)), 
 
600
                        unchecked((int)(0x976e9a92)), unchecked((int)(0x10b2e50b)), unchecked((int)(0xc4745626
 
601
                        )), unchecked((int)(0x6df9307c)), unchecked((int)(0xb93f8351)), unchecked((int)(
 
602
                        0x1f8636de)), unchecked((int)(0xcb4085f3)), unchecked((int)(0x62cde3a9)), unchecked(
 
603
                        (int)(0xb60b5084)), unchecked((int)(0x31d72f1d)), unchecked((int)(0xe5119c30)), 
 
604
                        unchecked((int)(0x4c9cfa6a)), unchecked((int)(0x985a4947)), unchecked((int)(0x43240558
 
605
                        )), unchecked((int)(0x97e2b675)), unchecked((int)(0x3e6fd02f)), unchecked((int)(
 
606
                        0xeaa96302)), unchecked((int)(0x6d751c9b)), unchecked((int)(0xb9b3afb6)), unchecked(
 
607
                        (int)(0x103ec9ec)), unchecked((int)(0xc4f87ac1)), unchecked((int)(0x7204e2ff)), 
 
608
                        unchecked((int)(0xa6c251d2)), unchecked((int)(0x0f4f3788)), unchecked((int)(0xdb8984a5
 
609
                        )), unchecked((int)(0x5c55fb3c)), unchecked((int)(0x88934811)), unchecked((int)(
 
610
                        0x211e2e4b)), unchecked((int)(0xf5d89d66)), unchecked((int)(0x2ea6d179)), unchecked(
 
611
                        (int)(0xfa606254)), unchecked((int)(0x53ed040e)), unchecked((int)(0x872bb723)), 
 
612
                        unchecked((int)(0x00f7c8ba)), unchecked((int)(0xd4317b97)), unchecked((int)(0x7dbc1dcd
 
613
                        )), unchecked((int)(0xa97aaee0)), unchecked((int)(0x10452db1)), unchecked((int)(
 
614
                        0xc4839e9c)), unchecked((int)(0x6d0ef8c6)), unchecked((int)(0xb9c84beb)), unchecked(
 
615
                        (int)(0x3e143472)), unchecked((int)(0xead2875f)), unchecked((int)(0x435fe105)), 
 
616
                        unchecked((int)(0x97995228)), unchecked((int)(0x4ce71e37)), unchecked((int)(0x9821ad1a
 
617
                        )), unchecked((int)(0x31accb40)), unchecked((int)(0xe56a786d)), unchecked((int)(
 
618
                        0x62b607f4)), unchecked((int)(0xb670b4d9)), unchecked((int)(0x1ffdd283)), unchecked(
 
619
                        (int)(0xcb3b61ae)), unchecked((int)(0x7dc7f990)), unchecked((int)(0xa9014abd)), 
 
620
                        unchecked((int)(0x008c2ce7)), unchecked((int)(0xd44a9fca)), unchecked((int)(0x5396e053
 
621
                        )), unchecked((int)(0x8750537e)), unchecked((int)(0x2edd3524)), unchecked((int)(
 
622
                        0xfa1b8609)), unchecked((int)(0x2165ca16)), unchecked((int)(0xf5a3793b)), unchecked(
 
623
                        (int)(0x5c2e1f61)), unchecked((int)(0x88e8ac4c)), unchecked((int)(0x0f34d3d5)), 
 
624
                        unchecked((int)(0xdbf260f8)), unchecked((int)(0x727f06a2)), unchecked((int)(0xa6b9b58f
 
625
                        )), unchecked((int)(0x3f0c6dbc)), unchecked((int)(0xebcade91)), unchecked((int)(
 
626
                        0x4247b8cb)), unchecked((int)(0x96810be6)), unchecked((int)(0x115d747f)), unchecked(
 
627
                        (int)(0xc59bc752)), unchecked((int)(0x6c16a108)), unchecked((int)(0xb8d01225)), 
 
628
                        unchecked((int)(0x63ae5e3a)), unchecked((int)(0xb768ed17)), unchecked((int)(0x1ee58b4d
 
629
                        )), unchecked((int)(0xca233860)), unchecked((int)(0x4dff47f9)), unchecked((int)(
 
630
                        0x9939f4d4)), unchecked((int)(0x30b4928e)), unchecked((int)(0xe47221a3)), unchecked(
 
631
                        (int)(0x528eb99d)), unchecked((int)(0x86480ab0)), unchecked((int)(0x2fc56cea)), 
 
632
                        unchecked((int)(0xfb03dfc7)), unchecked((int)(0x7cdfa05e)), unchecked((int)(0xa8191373
 
633
                        )), unchecked((int)(0x01947529)), unchecked((int)(0xd552c604)), unchecked((int)(
 
634
                        0x0e2c8a1b)), unchecked((int)(0xdaea3936)), unchecked((int)(0x73675f6c)), unchecked(
 
635
                        (int)(0xa7a1ec41)), unchecked((int)(0x207d93d8)), unchecked((int)(0xf4bb20f5)), 
 
636
                        unchecked((int)(0x5d3646af)), unchecked((int)(0x89f0f582)), unchecked((int)(0x30cf76d3
 
637
                        )), unchecked((int)(0xe409c5fe)), unchecked((int)(0x4d84a3a4)), unchecked((int)(
 
638
                        0x99421089)), unchecked((int)(0x1e9e6f10)), unchecked((int)(0xca58dc3d)), unchecked(
 
639
                        (int)(0x63d5ba67)), unchecked((int)(0xb713094a)), unchecked((int)(0x6c6d4555)), 
 
640
                        unchecked((int)(0xb8abf678)), unchecked((int)(0x11269022)), unchecked((int)(0xc5e0230f
 
641
                        )), unchecked((int)(0x423c5c96)), unchecked((int)(0x96faefbb)), unchecked((int)(
 
642
                        0x3f7789e1)), unchecked((int)(0xebb13acc)), unchecked((int)(0x5d4da2f2)), unchecked(
 
643
                        (int)(0x898b11df)), unchecked((int)(0x20067785)), unchecked((int)(0xf4c0c4a8)), 
 
644
                        unchecked((int)(0x731cbb31)), unchecked((int)(0xa7da081c)), unchecked((int)(0x0e576e46
 
645
                        )), unchecked((int)(0xda91dd6b)), unchecked((int)(0x01ef9174)), unchecked((int)(
 
646
                        0xd5292259)), unchecked((int)(0x7ca44403)), unchecked((int)(0xa862f72e)), unchecked(
 
647
                        (int)(0x2fbe88b7)), unchecked((int)(0xfb783b9a)), unchecked((int)(0x52f55dc0)), 
 
648
                        unchecked((int)(0x8633eeed)), unchecked((int)(0x208a5b62)), unchecked((int)(0xf44ce84f
 
649
                        )), unchecked((int)(0x5dc18e15)), unchecked((int)(0x89073d38)), unchecked((int)(
 
650
                        0x0edb42a1)), unchecked((int)(0xda1df18c)), unchecked((int)(0x739097d6)), unchecked(
 
651
                        (int)(0xa75624fb)), unchecked((int)(0x7c2868e4)), unchecked((int)(0xa8eedbc9)), 
 
652
                        unchecked((int)(0x0163bd93)), unchecked((int)(0xd5a50ebe)), unchecked((int)(0x52797127
 
653
                        )), unchecked((int)(0x86bfc20a)), unchecked((int)(0x2f32a450)), unchecked((int)(
 
654
                        0xfbf4177d)), unchecked((int)(0x4d088f43)), unchecked((int)(0x99ce3c6e)), unchecked(
 
655
                        (int)(0x30435a34)), unchecked((int)(0xe485e919)), unchecked((int)(0x63599680)), 
 
656
                        unchecked((int)(0xb79f25ad)), unchecked((int)(0x1e1243f7)), unchecked((int)(0xcad4f0da
 
657
                        )), unchecked((int)(0x11aabcc5)), unchecked((int)(0xc56c0fe8)), unchecked((int)(
 
658
                        0x6ce169b2)), unchecked((int)(0xb827da9f)), unchecked((int)(0x3ffba506)), unchecked(
 
659
                        (int)(0xeb3d162b)), unchecked((int)(0x42b07071)), unchecked((int)(0x9676c35c)), 
 
660
                        unchecked((int)(0x2f49400d)), unchecked((int)(0xfb8ff320)), unchecked((int)(0x5202957a
 
661
                        )), unchecked((int)(0x86c42657)), unchecked((int)(0x011859ce)), unchecked((int)(
 
662
                        0xd5deeae3)), unchecked((int)(0x7c538cb9)), unchecked((int)(0xa8953f94)), unchecked(
 
663
                        (int)(0x73eb738b)), unchecked((int)(0xa72dc0a6)), unchecked((int)(0x0ea0a6fc)), 
 
664
                        unchecked((int)(0xda6615d1)), unchecked((int)(0x5dba6a48)), unchecked((int)(0x897cd965
 
665
                        )), unchecked((int)(0x20f1bf3f)), unchecked((int)(0xf4370c12)), unchecked((int)(
 
666
                        0x42cb942c)), unchecked((int)(0x960d2701)), unchecked((int)(0x3f80415b)), unchecked(
 
667
                        (int)(0xeb46f276)), unchecked((int)(0x6c9a8def)), unchecked((int)(0xb85c3ec2)), 
 
668
                        unchecked((int)(0x11d15898)), unchecked((int)(0xc517ebb5)), unchecked((int)(0x1e69a7aa
 
669
                        )), unchecked((int)(0xcaaf1487)), unchecked((int)(0x632272dd)), unchecked((int)(
 
670
                        0xb7e4c1f0)), unchecked((int)(0x3038be69)), unchecked((int)(0xe4fe0d44)), unchecked(
 
671
                        (int)(0x4d736b1e)), unchecked((int)(0x99b5d833)) };
 
672
 
 
673
                private static readonly int[] U = new int[] { unchecked((int)(0x00000000)), unchecked(
 
674
                        (int)(0x12c6e90f)), unchecked((int)(0x258dd21e)), unchecked((int)(0x374b3b11)), 
 
675
                        unchecked((int)(0x4b1ba43c)), unchecked((int)(0x59dd4d33)), unchecked((int)(0x6e967622
 
676
                        )), unchecked((int)(0x7c509f2d)), unchecked((int)(0x42f1fb55)), unchecked((int)(
 
677
                        0x5037125a)), unchecked((int)(0x677c294b)), unchecked((int)(0x75bac044)), unchecked(
 
678
                        (int)(0x09ea5f69)), unchecked((int)(0x1b2cb666)), unchecked((int)(0x2c678d77)), 
 
679
                        unchecked((int)(0x3ea16478)), unchecked((int)(0x51254587)), unchecked((int)(0x43e3ac88
 
680
                        )), unchecked((int)(0x74a89799)), unchecked((int)(0x666e7e96)), unchecked((int)(
 
681
                        0x1a3ee1bb)), unchecked((int)(0x08f808b4)), unchecked((int)(0x3fb333a5)), unchecked(
 
682
                        (int)(0x2d75daaa)), unchecked((int)(0x13d4bed2)), unchecked((int)(0x011257dd)), 
 
683
                        unchecked((int)(0x36596ccc)), unchecked((int)(0x249f85c3)), unchecked((int)(0x58cf1aee
 
684
                        )), unchecked((int)(0x4a09f3e1)), unchecked((int)(0x7d42c8f0)), unchecked((int)(
 
685
                        0x6f8421ff)), unchecked((int)(0x768c3823)), unchecked((int)(0x644ad12c)), unchecked(
 
686
                        (int)(0x5301ea3d)), unchecked((int)(0x41c70332)), unchecked((int)(0x3d979c1f)), 
 
687
                        unchecked((int)(0x2f517510)), unchecked((int)(0x181a4e01)), unchecked((int)(0x0adca70e
 
688
                        )), unchecked((int)(0x347dc376)), unchecked((int)(0x26bb2a79)), unchecked((int)(
 
689
                        0x11f01168)), unchecked((int)(0x0336f867)), unchecked((int)(0x7f66674a)), unchecked(
 
690
                        (int)(0x6da08e45)), unchecked((int)(0x5aebb554)), unchecked((int)(0x482d5c5b)), 
 
691
                        unchecked((int)(0x27a97da4)), unchecked((int)(0x356f94ab)), unchecked((int)(0x0224afba
 
692
                        )), unchecked((int)(0x10e246b5)), unchecked((int)(0x6cb2d998)), unchecked((int)(
 
693
                        0x7e743097)), unchecked((int)(0x493f0b86)), unchecked((int)(0x5bf9e289)), unchecked(
 
694
                        (int)(0x655886f1)), unchecked((int)(0x779e6ffe)), unchecked((int)(0x40d554ef)), 
 
695
                        unchecked((int)(0x5213bde0)), unchecked((int)(0x2e4322cd)), unchecked((int)(0x3c85cbc2
 
696
                        )), unchecked((int)(0x0bcef0d3)), unchecked((int)(0x190819dc)), unchecked((int)(
 
697
                        0x39dec36b)), unchecked((int)(0x2b182a64)), unchecked((int)(0x1c531175)), unchecked(
 
698
                        (int)(0x0e95f87a)), unchecked((int)(0x72c56757)), unchecked((int)(0x60038e58)), 
 
699
                        unchecked((int)(0x5748b549)), unchecked((int)(0x458e5c46)), unchecked((int)(0x7b2f383e
 
700
                        )), unchecked((int)(0x69e9d131)), unchecked((int)(0x5ea2ea20)), unchecked((int)(
 
701
                        0x4c64032f)), unchecked((int)(0x30349c02)), unchecked((int)(0x22f2750d)), unchecked(
 
702
                        (int)(0x15b94e1c)), unchecked((int)(0x077fa713)), unchecked((int)(0x68fb86ec)), 
 
703
                        unchecked((int)(0x7a3d6fe3)), unchecked((int)(0x4d7654f2)), unchecked((int)(0x5fb0bdfd
 
704
                        )), unchecked((int)(0x23e022d0)), unchecked((int)(0x3126cbdf)), unchecked((int)(
 
705
                        0x066df0ce)), unchecked((int)(0x14ab19c1)), unchecked((int)(0x2a0a7db9)), unchecked(
 
706
                        (int)(0x38cc94b6)), unchecked((int)(0x0f87afa7)), unchecked((int)(0x1d4146a8)), 
 
707
                        unchecked((int)(0x6111d985)), unchecked((int)(0x73d7308a)), unchecked((int)(0x449c0b9b
 
708
                        )), unchecked((int)(0x565ae294)), unchecked((int)(0x4f52fb48)), unchecked((int)(
 
709
                        0x5d941247)), unchecked((int)(0x6adf2956)), unchecked((int)(0x7819c059)), unchecked(
 
710
                        (int)(0x04495f74)), unchecked((int)(0x168fb67b)), unchecked((int)(0x21c48d6a)), 
 
711
                        unchecked((int)(0x33026465)), unchecked((int)(0x0da3001d)), unchecked((int)(0x1f65e912
 
712
                        )), unchecked((int)(0x282ed203)), unchecked((int)(0x3ae83b0c)), unchecked((int)(
 
713
                        0x46b8a421)), unchecked((int)(0x547e4d2e)), unchecked((int)(0x6335763f)), unchecked(
 
714
                        (int)(0x71f39f30)), unchecked((int)(0x1e77becf)), unchecked((int)(0x0cb157c0)), 
 
715
                        unchecked((int)(0x3bfa6cd1)), unchecked((int)(0x293c85de)), unchecked((int)(0x556c1af3
 
716
                        )), unchecked((int)(0x47aaf3fc)), unchecked((int)(0x70e1c8ed)), unchecked((int)(
 
717
                        0x622721e2)), unchecked((int)(0x5c86459a)), unchecked((int)(0x4e40ac95)), unchecked(
 
718
                        (int)(0x790b9784)), unchecked((int)(0x6bcd7e8b)), unchecked((int)(0x179de1a6)), 
 
719
                        unchecked((int)(0x055b08a9)), unchecked((int)(0x321033b8)), unchecked((int)(0x20d6dab7
 
720
                        )), unchecked((int)(0x73bd86d6)), unchecked((int)(0x617b6fd9)), unchecked((int)(
 
721
                        0x563054c8)), unchecked((int)(0x44f6bdc7)), unchecked((int)(0x38a622ea)), unchecked(
 
722
                        (int)(0x2a60cbe5)), unchecked((int)(0x1d2bf0f4)), unchecked((int)(0x0fed19fb)), 
 
723
                        unchecked((int)(0x314c7d83)), unchecked((int)(0x238a948c)), unchecked((int)(0x14c1af9d
 
724
                        )), unchecked((int)(0x06074692)), unchecked((int)(0x7a57d9bf)), unchecked((int)(
 
725
                        0x689130b0)), unchecked((int)(0x5fda0ba1)), unchecked((int)(0x4d1ce2ae)), unchecked(
 
726
                        (int)(0x2298c351)), unchecked((int)(0x305e2a5e)), unchecked((int)(0x0715114f)), 
 
727
                        unchecked((int)(0x15d3f840)), unchecked((int)(0x6983676d)), unchecked((int)(0x7b458e62
 
728
                        )), unchecked((int)(0x4c0eb573)), unchecked((int)(0x5ec85c7c)), unchecked((int)(
 
729
                        0x60693804)), unchecked((int)(0x72afd10b)), unchecked((int)(0x45e4ea1a)), unchecked(
 
730
                        (int)(0x57220315)), unchecked((int)(0x2b729c38)), unchecked((int)(0x39b47537)), 
 
731
                        unchecked((int)(0x0eff4e26)), unchecked((int)(0x1c39a729)), unchecked((int)(0x0531bef5
 
732
                        )), unchecked((int)(0x17f757fa)), unchecked((int)(0x20bc6ceb)), unchecked((int)(
 
733
                        0x327a85e4)), unchecked((int)(0x4e2a1ac9)), unchecked((int)(0x5cecf3c6)), unchecked(
 
734
                        (int)(0x6ba7c8d7)), unchecked((int)(0x796121d8)), unchecked((int)(0x47c045a0)), 
 
735
                        unchecked((int)(0x5506acaf)), unchecked((int)(0x624d97be)), unchecked((int)(0x708b7eb1
 
736
                        )), unchecked((int)(0x0cdbe19c)), unchecked((int)(0x1e1d0893)), unchecked((int)(
 
737
                        0x29563382)), unchecked((int)(0x3b90da8d)), unchecked((int)(0x5414fb72)), unchecked(
 
738
                        (int)(0x46d2127d)), unchecked((int)(0x7199296c)), unchecked((int)(0x635fc063)), 
 
739
                        unchecked((int)(0x1f0f5f4e)), unchecked((int)(0x0dc9b641)), unchecked((int)(0x3a828d50
 
740
                        )), unchecked((int)(0x2844645f)), unchecked((int)(0x16e50027)), unchecked((int)(
 
741
                        0x0423e928)), unchecked((int)(0x3368d239)), unchecked((int)(0x21ae3b36)), unchecked(
 
742
                        (int)(0x5dfea41b)), unchecked((int)(0x4f384d14)), unchecked((int)(0x78737605)), 
 
743
                        unchecked((int)(0x6ab59f0a)), unchecked((int)(0x4a6345bd)), unchecked((int)(0x58a5acb2
 
744
                        )), unchecked((int)(0x6fee97a3)), unchecked((int)(0x7d287eac)), unchecked((int)(
 
745
                        0x0178e181)), unchecked((int)(0x13be088e)), unchecked((int)(0x24f5339f)), unchecked(
 
746
                        (int)(0x3633da90)), unchecked((int)(0x0892bee8)), unchecked((int)(0x1a5457e7)), 
 
747
                        unchecked((int)(0x2d1f6cf6)), unchecked((int)(0x3fd985f9)), unchecked((int)(0x43891ad4
 
748
                        )), unchecked((int)(0x514ff3db)), unchecked((int)(0x6604c8ca)), unchecked((int)(
 
749
                        0x74c221c5)), unchecked((int)(0x1b46003a)), unchecked((int)(0x0980e935)), unchecked(
 
750
                        (int)(0x3ecbd224)), unchecked((int)(0x2c0d3b2b)), unchecked((int)(0x505da406)), 
 
751
                        unchecked((int)(0x429b4d09)), unchecked((int)(0x75d07618)), unchecked((int)(0x67169f17
 
752
                        )), unchecked((int)(0x59b7fb6f)), unchecked((int)(0x4b711260)), unchecked((int)(
 
753
                        0x7c3a2971)), unchecked((int)(0x6efcc07e)), unchecked((int)(0x12ac5f53)), unchecked(
 
754
                        (int)(0x006ab65c)), unchecked((int)(0x37218d4d)), unchecked((int)(0x25e76442)), 
 
755
                        unchecked((int)(0x3cef7d9e)), unchecked((int)(0x2e299491)), unchecked((int)(0x1962af80
 
756
                        )), unchecked((int)(0x0ba4468f)), unchecked((int)(0x77f4d9a2)), unchecked((int)(
 
757
                        0x653230ad)), unchecked((int)(0x52790bbc)), unchecked((int)(0x40bfe2b3)), unchecked(
 
758
                        (int)(0x7e1e86cb)), unchecked((int)(0x6cd86fc4)), unchecked((int)(0x5b9354d5)), 
 
759
                        unchecked((int)(0x4955bdda)), unchecked((int)(0x350522f7)), unchecked((int)(0x27c3cbf8
 
760
                        )), unchecked((int)(0x1088f0e9)), unchecked((int)(0x024e19e6)), unchecked((int)(
 
761
                        0x6dca3819)), unchecked((int)(0x7f0cd116)), unchecked((int)(0x4847ea07)), unchecked(
 
762
                        (int)(0x5a810308)), unchecked((int)(0x26d19c25)), unchecked((int)(0x3417752a)), 
 
763
                        unchecked((int)(0x035c4e3b)), unchecked((int)(0x119aa734)), unchecked((int)(0x2f3bc34c
 
764
                        )), unchecked((int)(0x3dfd2a43)), unchecked((int)(0x0ab61152)), unchecked((int)(
 
765
                        0x1870f85d)), unchecked((int)(0x64206770)), unchecked((int)(0x76e68e7f)), unchecked(
 
766
                        (int)(0x41adb56e)), unchecked((int)(0x536b5c61)) };
 
767
        }
 
768
}