001package squidpony.squidmath; 002 003import java.io.Serializable; 004import java.util.Arrays; 005import java.util.Iterator; 006import java.util.List; 007import java.util.Objects; 008 009import static squidpony.squidmath.CrossHash.Water.*; 010import static squidpony.squidmath.NumberTools.doubleToMixedIntBits; 011import static squidpony.squidmath.NumberTools.floatToIntBits; 012 013/** 014 * 64-bit and 32-bit hashing functions that we can rely on staying the same cross-platform. 015 * Several algorithms are present here, each with some tradeoffs for performance, quality, 016 * and extra features. Each algorithm was designed for speed and general-purpose usability, 017 * but not cryptographic security. 018 * <br> 019 * The hashes this returns are always 0 when given null to hash. Arrays with 020 * identical elements of identical types will hash identically. Arrays with identical 021 * numerical values but different types will sometimes hash differently. This class 022 * always provides 64-bit hashes via hash64() and 32-bit hashes via hash(), and Wisp 023 * provides a hash32() method that matches older behavior and uses only 32-bit math. 024 * The hash64() and hash() methods, except in Hive, use 64-bit math even when producing 025 * 32-bit hashes, for GWT reasons. GWT doesn't have the same behavior as desktop and 026 * Android applications when using ints because it treats doubles mostly like ints, 027 * sometimes, due to it using JavaScript. If we use mainly longs, though, GWT emulates 028 * the longs with a more complex technique behind-the-scenes, that behaves the same on 029 * the web as it does on desktop or on a phone. Since CrossHash is supposed to be stable 030 * cross-platform, this is the way we need to go, despite it being slightly slower. 031 * <br> 032 * The static methods in CrossHash, like {@link #hash64(int[])}, delegate to the {@link Water} 033 * algorithm. This is a fairly fast and heavily-tested hash that developed from something like 034 * Wang Yi's wyhash algorithm, though only the constants and the general concept of a mum() 035 * function are shared with wyhash. There are several static inner classes in CrossHash 036 * {@link Water} (already mentioned), {@link Yolk} (which is very close to Water but allows a 037 * 64-bit salt or seed), {@link Curlup} (which is the fastest hash here for larger inputs, and 038 * also allows a 64-bit seed), {@link Mist} (which allows a 128-bit salt, but has mediocre 039 * quality), {@link Hive} (which is mostly here for compatibility, but has OK quality and good 040 * collision rates), and {@link Wisp} (which is fast for small inputs but has bad collision 041 * rates). There's also the inner IHasher interface, and the classes that implement it. 042 * Water, Yolk, and Curlup all pass the rigorous SMHasher test battery. The others don't pass 043 * it in full, or sometimes at all. 044 * <br> 045 * IHasher values are provided as static fields, and use Water to hash a specific type or fall 046 * back to Object.hashCode if given an object with the wrong type. IHasher values are optional 047 * parts of OrderedMap, OrderedSet, Arrangement, and the various classes that use Arrangement 048 * like K2 and K2V1, and allow arrays to be used as keys in those collections while keeping 049 * hashing by value instead of the normal hashing by reference for arrays. You probably won't 050 * ever need to make a class that implements IHasher yourself; for some cases you may want to 051 * look at the {@link Hashers} class for additional functions. 052 * <br> 053 * Note: This class was formerly called StableHash, but since that refers to a specific 054 * category of hashing algorithm that this is not, and since the goal is to be cross- 055 * platform, the name was changed to CrossHash. 056 * Note 2: FNV-1a was removed from SquidLib on July 25, 2017, and replaced as default with Wisp; Wisp 057 * was later replaced as default by Hive, and in June 2019 Hive was replaced by Water. Wisp was used 058 * because at the time SquidLib preferred 64-bit math when math needed to be the same across platforms; 059 * math on longs behaves the same on GWT as on desktop, despite being slower. Hive passed an older version 060 * of SMHasher, a testing suite for hashes, where Wisp does not (it fails just like Arrays.hashCode() 061 * does). Hive uses a cross-platform subset of the possible 32-bit math operations when producing 32-bit 062 * hashes of data that doesn't involve longs or doubles, and this should speed up the CrossHash.Hive.hash() 063 * methods a lot on GWT, but it slows down 32-bit output on desktop-class JVMs. Water became the default 064 * when newer versions of SMHasher showed that Hive wasn't as high-quality as it had appeared, and the 065 * recently-debuted wyhash by Wang Yi, a variation on a hash called MUM, opened some possibilities for 066 * structures that are simple but also very fast. Water is modeled after wyhash and uses the same constants 067 * in its hash64() methods, but avoids the 128-bit multiplication that wyhash uses. Because both wyhash and 068 * Water operate on 4 items at a time, they tend to be very fast on desktop platforms, but Water probably 069 * won't be amazing at GWT performance. Similarly, the recently-added Curlup performs very well due to SIMD 070 * optimizations that HotSpot performs, and probably won't do as well on GWT or Android. 071 * <br> 072 * Created by Tommy Ettinger on 1/16/2016. 073 * @author Tommy Ettinger 074 */ 075public class CrossHash { 076 public static long hash64(final CharSequence data) { 077 return Water.hash64(data); 078 } 079 080 public static long hash64(final boolean[] data) { 081 return Water.hash64(data); 082 } 083 084 public static long hash64(final byte[] data) { 085 return Water.hash64(data); 086 } 087 088 public static long hash64(final short[] data) { 089 return Water.hash64(data); 090 } 091 092 public static long hash64(final int[] data) { 093 return Water.hash64(data); 094 } 095 096 public static long hash64(final long[] data) { 097 return Water.hash64(data); 098 } 099 100 public static long hash64(final char[] data) { 101 return Water.hash64(data); 102 } 103 104 public static long hash64(final float[] data) { 105 return Water.hash64(data); 106 } 107 108 public static long hash64(final double[] data) { 109 return Water.hash64(data); 110 } 111 112 /** 113 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 114 * 115 * @param data the char array to hash 116 * @param start the start of the section to hash (inclusive) 117 * @param end the end of the section to hash (exclusive) 118 * @return a 64-bit hash code for the requested section of data 119 */ 120 public static long hash64(final char[] data, final int start, final int end) { 121 return Water.hash64(data, start, end); 122 } 123 124 /** 125 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 126 * 127 * @param data the String or other CharSequence to hash 128 * @param start the start of the section to hash (inclusive) 129 * @param end the end of the section to hash (exclusive) 130 * @return a 64-bit hash code for the requested section of data 131 */ 132 public static long hash64(final CharSequence data, final int start, final int end) { 133 return Water.hash64(data, start, end); 134 } 135 136 public static long hash64(final char[][] data) { 137 return Water.hash64(data); 138 } 139 140 public static long hash64(final int[][] data) { 141 return Water.hash64(data); 142 } 143 144 public static long hash64(final long[][] data) { 145 return Water.hash64(data); 146 } 147 148 public static long hash64(final CharSequence[] data) { 149 return Water.hash64(data); 150 } 151 152 public static long hash64(final CharSequence[]... data) { 153 return Water.hash64(data); 154 } 155 156 public static long hash64(final Iterable<? extends CharSequence> data) { 157 return Water.hash64(data); 158 } 159 160 public static long hash64(final List<? extends CharSequence> data) { 161 return Water.hash64(data); 162 } 163 164 public static long hash64(final Object[] data) { 165 return Water.hash64(data); 166 } 167 168 public static long hash64(final Object data) { 169 return Water.hash64(data); 170 } 171 172 173 public static int hash(final CharSequence data) { 174 return Water.hash(data); 175 } 176 177 public static int hash(final boolean[] data) { 178 return Water.hash(data); 179 } 180 181 public static int hash(final byte[] data) { 182 return Water.hash(data); 183 } 184 185 public static int hash(final short[] data) { 186 return Water.hash(data); 187 } 188 189 public static int hash(final int[] data) { 190 return Water.hash(data); 191 } 192 193 public static int hash(final long[] data) { 194 return Water.hash(data); 195 } 196 197 public static int hash(final char[] data) { 198 return Water.hash(data); 199 } 200 201 public static int hash(final float[] data) { 202 return Water.hash(data); 203 } 204 205 public static int hash(final double[] data) { 206 return Water.hash(data); 207 } 208 209 /** 210 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 211 * 212 * @param data the char array to hash 213 * @param start the start of the section to hash (inclusive) 214 * @param end the end of the section to hash (exclusive) 215 * @return a 32-bit hash code for the requested section of data 216 */ 217 public static int hash(final char[] data, final int start, final int end) { 218 return Water.hash(data, start, end); 219 } 220 221 /** 222 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 223 * 224 * @param data the String or other CharSequence to hash 225 * @param start the start of the section to hash (inclusive) 226 * @param end the end of the section to hash (exclusive) 227 * @return a 32-bit hash code for the requested section of data 228 */ 229 public static int hash(final CharSequence data, final int start, final int end) { 230 return Water.hash(data, start, end); 231 } 232 233 234 public static int hash(final char[][] data) { 235 return Water.hash(data); 236 } 237 238 public static int hash(final int[][] data) { 239 return Water.hash(data); 240 } 241 242 public static int hash(final long[][] data) { 243 return Water.hash(data); 244 } 245 246 public static int hash(final CharSequence[] data) { 247 return Water.hash(data); 248 } 249 250 public static int hash(final CharSequence[]... data) { 251 return Water.hash(data); 252 } 253 254 public static int hash(final Iterable<? extends CharSequence> data) { 255 return Water.hash(data); 256 } 257 258 public static int hash(final List<? extends CharSequence> data) { 259 return Water.hash(data); 260 } 261 262 public static int hash(final Object[] data) { 263 return Water.hash(data); 264 } 265 266 public static int hash(final Object data) { 267 return Water.hash(data); 268 } 269 270 /** 271 * An interface that can be used to move the logic for the hashCode() and equals() methods from a class' methods to 272 * an implementation of IHasher that certain collections in SquidLib can use. Primarily useful when the key type is 273 * an array, which normally doesn't work as expected in Java hash-based collections, but can if the right collection 274 * and IHasher are used. See also {@link Hashers} for additional implementations, some of which need dependencies on 275 * things the rest of CrossHash doesn't, like a case-insensitive String hasher/equator that uses RegExodus to handle 276 * CharSequence comparison on GWT. 277 */ 278 public interface IHasher extends Serializable { 279 /** 280 * If data is a type that this IHasher can specifically hash, this method should use that specific hash; in 281 * other situations, it should simply delegate to calling {@link Object#hashCode()} on data. The body of an 282 * implementation of this method can be very small; for an IHasher that is meant for byte arrays, the body could 283 * be: {@code return (data instanceof byte[]) ? CrossHash.Lightning.hash((byte[]) data) : data.hashCode();} 284 * 285 * @param data the Object to hash; this method should take any type but often has special behavior for one type 286 * @return a 32-bit int hash code of data 287 */ 288 int hash(final Object data); 289 290 /** 291 * Not all types you might want to use an IHasher on meaningfully implement .equals(), such as array types; in 292 * these situations the areEqual method helps quickly check for equality by potentially having special logic for 293 * the type this is meant to check. The body of implementations for this method can be fairly small; for byte 294 * arrays, it looks like: {@code return left == right 295 * || ((left instanceof byte[] && right instanceof byte[]) 296 * ? Arrays.equals((byte[]) left, (byte[]) right) 297 * : Objects.equals(left, right));} , but for multidimensional arrays you should use the 298 * {@link #equalityHelper(Object[], Object[], IHasher)} method with an IHasher for the inner arrays that are 1D 299 * or otherwise already-hash-able, as can be seen in the body of the implementation for 2D char arrays, where 300 * charHasher is an existing IHasher that handles 1D arrays: 301 * {@code return left == right 302 * || ((left instanceof char[][] && right instanceof char[][]) 303 * ? equalityHelper((char[][]) left, (char[][]) right, charHasher) 304 * : Objects.equals(left, right));} 305 * 306 * @param left allowed to be null; most implementations will have special behavior for one type 307 * @param right allowed to be null; most implementations will have special behavior for one type 308 * @return true if left is equal to right (preferably by value, but reference equality may sometimes be needed) 309 */ 310 boolean areEqual(final Object left, final Object right); 311 } 312 313 /** 314 * Not a general-purpose method; meant to ease implementation of {@link IHasher#areEqual(Object, Object)} 315 * methods when the type being compared is a multi-dimensional array (which normally requires the heavyweight method 316 * {@link Arrays#deepEquals(Object[], Object[])} or doing more work yourself; this reduces the work needed to 317 * implement fixed-depth equality). As mentioned in the docs for {@link IHasher#areEqual(Object, Object)}, example 318 * code that hashes 2D char arrays can be done using an IHasher for 1D char arrays called charHasher: 319 * {@code return left == right 320 * || ((left instanceof char[][] && right instanceof char[][]) 321 * ? equalityHelper((char[][]) left, (char[][]) right, charHasher) 322 * : Objects.equals(left, right));} 323 * 324 * @param left an array of some kind of Object, usually an array, that the given IHasher can compare 325 * @param right an array of some kind of Object, usually an array, that the given IHasher can compare 326 * @param inner an IHasher to compare items in left with items in right 327 * @return true if the contents of left and right are equal by the given IHasher, otherwise false 328 */ 329 public static boolean equalityHelper(Object[] left, Object[] right, IHasher inner) { 330 if (left == right) 331 return true; 332 if (left == null || right == null || left.length != right.length) 333 return false; 334 for (int i = 0; i < left.length; i++) { 335 if (!inner.areEqual(left[i], right[i])) 336 return false; 337 } 338 return true; 339 } 340 341 private static class BooleanHasher implements IHasher, Serializable { 342 private static final long serialVersionUID = 3L; 343 344 BooleanHasher() { 345 } 346 347 @Override 348 public int hash(final Object data) { 349 return (data instanceof boolean[]) ? CrossHash.hash((boolean[]) data) : data.hashCode(); 350 } 351 352 @Override 353 public boolean areEqual(Object left, Object right) { 354 return left == right || ((left instanceof boolean[] && right instanceof boolean[]) ? Arrays.equals((boolean[]) left, (boolean[]) right) : Objects.equals(left, right)); 355 } 356 } 357 358 public static final IHasher booleanHasher = new BooleanHasher(); 359 360 private static class ByteHasher implements IHasher, Serializable { 361 private static final long serialVersionUID = 3L; 362 363 ByteHasher() { 364 } 365 366 @Override 367 public int hash(final Object data) { 368 return (data instanceof byte[]) ? CrossHash.hash((byte[]) data) : data.hashCode(); 369 } 370 371 @Override 372 public boolean areEqual(Object left, Object right) { 373 return left == right 374 || ((left instanceof byte[] && right instanceof byte[]) 375 ? Arrays.equals((byte[]) left, (byte[]) right) 376 : Objects.equals(left, right)); 377 } 378 } 379 380 public static final IHasher byteHasher = new ByteHasher(); 381 382 private static class ShortHasher implements IHasher, Serializable { 383 private static final long serialVersionUID = 3L; 384 385 ShortHasher() { 386 } 387 388 @Override 389 public int hash(final Object data) { 390 return (data instanceof short[]) ? CrossHash.hash((short[]) data) : data.hashCode(); 391 } 392 393 @Override 394 public boolean areEqual(Object left, Object right) { 395 return left == right || ((left instanceof short[] && right instanceof short[]) ? Arrays.equals((short[]) left, (short[]) right) : Objects.equals(left, right)); 396 } 397 } 398 399 public static final IHasher shortHasher = new ShortHasher(); 400 401 private static class CharHasher implements IHasher, Serializable { 402 private static final long serialVersionUID = 3L; 403 404 CharHasher() { 405 } 406 407 @Override 408 public int hash(final Object data) { 409 return (data instanceof char[]) ? CrossHash.hash((char[]) data) : data.hashCode(); 410 } 411 412 @Override 413 public boolean areEqual(Object left, Object right) { 414 return left == right || ((left instanceof char[] && right instanceof char[]) ? Arrays.equals((char[]) left, (char[]) right) : Objects.equals(left, right)); 415 } 416 } 417 418 public static final IHasher charHasher = new CharHasher(); 419 420 private static class IntHasher implements IHasher, Serializable { 421 private static final long serialVersionUID = 3L; 422 423 IntHasher() { 424 } 425 426 @Override 427 public int hash(final Object data) { 428 return (data instanceof int[]) ? CrossHash.hash((int[]) data) : data.hashCode(); 429 } 430 431 @Override 432 public boolean areEqual(Object left, Object right) { 433 return (left instanceof int[] && right instanceof int[]) ? Arrays.equals((int[]) left, (int[]) right) : Objects.equals(left, right); 434 } 435 } 436 437 public static final IHasher intHasher = new IntHasher(); 438 439 private static class LongHasher implements IHasher, Serializable { 440 private static final long serialVersionUID = 3L; 441 442 LongHasher() { 443 } 444 445 @Override 446 public int hash(final Object data) { 447 return (data instanceof long[]) ? CrossHash.hash((long[]) data) : data.hashCode(); 448 } 449 450 @Override 451 public boolean areEqual(Object left, Object right) { 452 return (left instanceof long[] && right instanceof long[]) ? Arrays.equals((long[]) left, (long[]) right) : Objects.equals(left, right); 453 } 454 } 455 456 public static final IHasher longHasher = new LongHasher(); 457 458 private static class FloatHasher implements IHasher, Serializable { 459 private static final long serialVersionUID = 3L; 460 461 FloatHasher() { 462 } 463 464 @Override 465 public int hash(final Object data) { 466 return (data instanceof float[]) ? CrossHash.hash((float[]) data) : data.hashCode(); 467 } 468 469 @Override 470 public boolean areEqual(Object left, Object right) { 471 return left == right || ((left instanceof float[] && right instanceof float[]) ? Arrays.equals((float[]) left, (float[]) right) : Objects.equals(left, right)); 472 } 473 } 474 475 public static final IHasher floatHasher = new FloatHasher(); 476 477 private static class DoubleHasher implements IHasher, Serializable { 478 private static final long serialVersionUID = 3L; 479 480 DoubleHasher() { 481 } 482 483 @Override 484 public int hash(final Object data) { 485 return (data instanceof double[]) ? CrossHash.hash((double[]) data) : data.hashCode(); 486 } 487 488 @Override 489 public boolean areEqual(Object left, Object right) { 490 return left == right || ((left instanceof double[] && right instanceof double[]) ? Arrays.equals((double[]) left, (double[]) right) : Objects.equals(left, right)); 491 } 492 } 493 494 public static final IHasher doubleHasher = new DoubleHasher(); 495 496 private static class Char2DHasher implements IHasher, Serializable { 497 private static final long serialVersionUID = 3L; 498 499 Char2DHasher() { 500 } 501 502 @Override 503 public int hash(final Object data) { 504 return (data instanceof char[][]) ? CrossHash.hash((char[][]) data) : data.hashCode(); 505 } 506 507 @Override 508 public boolean areEqual(Object left, Object right) { 509 return left == right 510 || ((left instanceof char[][] && right instanceof char[][]) 511 ? equalityHelper((char[][]) left, (char[][]) right, charHasher) 512 : Objects.equals(left, right)); 513 } 514 } 515 516 public static final IHasher char2DHasher = new Char2DHasher(); 517 518 private static class Int2DHasher implements IHasher, Serializable { 519 private static final long serialVersionUID = 3L; 520 521 Int2DHasher() { 522 } 523 524 @Override 525 public int hash(final Object data) { 526 return (data instanceof int[][]) ? CrossHash.hash((int[][]) data) : data.hashCode(); 527 } 528 529 @Override 530 public boolean areEqual(Object left, Object right) { 531 return left == right 532 || ((left instanceof int[][] && right instanceof int[][]) 533 ? equalityHelper((int[][]) left, (int[][]) right, intHasher) 534 : Objects.equals(left, right)); 535 } 536 } 537 538 public static final IHasher int2DHasher = new Int2DHasher(); 539 540 private static class Long2DHasher implements IHasher, Serializable { 541 private static final long serialVersionUID = 3L; 542 543 Long2DHasher() { 544 } 545 546 @Override 547 public int hash(final Object data) { 548 return (data instanceof long[][]) ? CrossHash.hash((long[][]) data) : data.hashCode(); 549 } 550 551 @Override 552 public boolean areEqual(Object left, Object right) { 553 return left == right 554 || ((left instanceof long[][] && right instanceof long[][]) 555 ? equalityHelper((long[][]) left, (long[][]) right, longHasher) 556 : Objects.equals(left, right)); 557 } 558 } 559 560 public static final IHasher long2DHasher = new Long2DHasher(); 561 562 private static class StringHasher implements IHasher, Serializable { 563 private static final long serialVersionUID = 3L; 564 565 StringHasher() { 566 } 567 568 @Override 569 public int hash(final Object data) { 570 return (data instanceof CharSequence) ? CrossHash.hash((CharSequence) data) : data.hashCode(); 571 } 572 573 @Override 574 public boolean areEqual(Object left, Object right) { 575 return Objects.equals(left, right); 576 } 577 } 578 579 public static final IHasher stringHasher = new StringHasher(); 580 581 private static class StringArrayHasher implements IHasher, Serializable { 582 private static final long serialVersionUID = 3L; 583 584 StringArrayHasher() { 585 } 586 587 @Override 588 public int hash(final Object data) { 589 return (data instanceof CharSequence[]) ? CrossHash.hash((CharSequence[]) data) : data.hashCode(); 590 } 591 592 @Override 593 public boolean areEqual(Object left, Object right) { 594 return left == right || ((left instanceof CharSequence[] && right instanceof CharSequence[]) ? equalityHelper((CharSequence[]) left, (CharSequence[]) right, stringHasher) : Objects.equals(left, right)); 595 } 596 } 597 598 /** 599 * Though the name suggests this only hashes String arrays, it can actually hash any CharSequence array as well. 600 */ 601 public static final IHasher stringArrayHasher = new StringArrayHasher(); 602 603 private static class ObjectArrayHasher implements IHasher, Serializable { 604 private static final long serialVersionUID = 3L; 605 606 ObjectArrayHasher() { 607 } 608 609 @Override 610 public int hash(final Object data) { 611 return (data instanceof Object[]) ? CrossHash.hash((Object[]) data) : data.hashCode(); 612 } 613 614 @Override 615 public boolean areEqual(Object left, Object right) { 616 return left == right || ((left instanceof Object[] && right instanceof Object[]) && Arrays.equals((Object[]) left, (Object[]) right) || Objects.equals(left, right)); 617 } 618 } 619 public static final IHasher objectArrayHasher = new ObjectArrayHasher(); 620 621 private static class DefaultHasher implements IHasher, Serializable { 622 private static final long serialVersionUID = 5L; 623 624 DefaultHasher() { 625 } 626 627 @Override 628 public int hash(final Object data) { 629 if(data == null) return 0; 630 final int x = data.hashCode() * 0x9E375; 631 return x ^ x >>> 16; 632 } 633 634 @Override 635 public boolean areEqual(final Object left, final Object right) { 636 return (left == right) || (left != null && left.equals(right)); 637 } 638 } 639 640 public static final IHasher defaultHasher = new DefaultHasher(); 641 642 private static class MildHasher implements IHasher, Serializable { 643 private static final long serialVersionUID = 4L; 644 645 MildHasher() { 646 } 647 648 @Override 649 public int hash(final Object data) { 650 return data != null ? data.hashCode() : 0; 651 } 652 653 @Override 654 public boolean areEqual(final Object left, final Object right) { 655 return (left == right) || (left != null && left.equals(right)); 656 } 657 } 658 659 /** 660 * The most basic IHasher type; effectively delegates to {@link Objects#hashCode(Object)} and 661 * {@link Objects#equals(Object, Object)}. Might not scramble the bits of a hash well enough to have good 662 * performance in a hash table lke {@link OrderedMap} or {@link UnorderedSet}, unless the objects being hashed have 663 * good hashCode() implementations already. 664 */ 665 public static final IHasher mildHasher = new MildHasher(); 666 667 private static class IdentityHasher implements IHasher, Serializable 668 { 669 private static final long serialVersionUID = 4L; 670 IdentityHasher() { } 671 672 @Override 673 public int hash(Object data) { 674 return System.identityHashCode(data); 675 } 676 677 @Override 678 public boolean areEqual(Object left, Object right) { 679 return left == right; 680 } 681 } 682 public static final IHasher identityHasher = new IdentityHasher(); 683 684 private static class GeneralHasher implements IHasher, Serializable { 685 private static final long serialVersionUID = 3L; 686 687 GeneralHasher() { 688 } 689 690 @Override 691 public int hash(final Object data) { 692 return CrossHash.hash(data); 693 } 694 695 @Override 696 public boolean areEqual(Object left, Object right) { 697 if(left == right) return true; 698 Class<?> l = left.getClass(), r = right.getClass(); 699 if(l == r) 700 { 701 if(l.isArray()) 702 { 703 if(left instanceof int[]) return Arrays.equals((int[]) left, (int[]) right); 704 else if(left instanceof long[]) return Arrays.equals((long[]) left, (long[]) right); 705 else if(left instanceof char[]) return Arrays.equals((char[]) left, (char[]) right); 706 else if(left instanceof double[]) return Arrays.equals((double[]) left, (double[]) right); 707 else if(left instanceof boolean[]) return Arrays.equals((boolean[]) left, (boolean[]) right); 708 else if(left instanceof byte[]) return Arrays.equals((byte[]) left, (byte[]) right); 709 else if(left instanceof float[]) return Arrays.equals((float[]) left, (float[]) right); 710 else if(left instanceof short[]) return Arrays.equals((short[]) left, (short[]) right); 711 else if(left instanceof char[][]) return equalityHelper((char[][]) left, (char[][]) right, charHasher); 712 else if(left instanceof int[][]) return equalityHelper((int[][]) left, (int[][]) right, intHasher); 713 else if(left instanceof long[][]) return equalityHelper((long[][]) left, (long[][]) right, longHasher); 714 else if(left instanceof CharSequence[]) return equalityHelper((CharSequence[]) left, (CharSequence[]) right, stringHasher); 715 else if(left instanceof Object[]) return Arrays.equals((Object[]) left, (Object[]) right); 716 } 717 return Objects.equals(left, right); 718 } 719 return false; 720 } 721 } 722 723 /** 724 * This IHasher is the one you should use if you aren't totally certain what types will go in an OrderedMap's keys 725 * or an OrderedSet's items, since it can handle mixes of elements. 726 */ 727 public static final IHasher generalHasher = new GeneralHasher(); 728 729 /** 730 * A quick, simple hashing function that seems to have good results. Like LightRNG, it stores a state that 731 * it updates independently of the output, and this starts at a large prime. At each step, it takes the 732 * current item in the array being hashed, adds a large non-prime used in LightRNG's generation function 733 * (it's 2 to the 64, times the golden ratio phi, and truncated to a signed long), multiplies by a prime 734 * called the "state multiplier", adds the result to the state and stores it, multiplies the value of the 735 * state by another prime called the "output multiplier", then XORs the current result with that value 736 * before moving onto the next item in the array. A finalization step XORs the result with a complex value 737 * made by adding the state (left over from the previous step) to what was the output multiplier, adding 738 * the last known value for result to the phi-related constant from LightRNG, multiplying that pair, adding 739 * the initial state (which turns out to be unusually good for this, despite no particularly special numeric 740 * qualities other than being a probable prime) and then bitwise-rotating it left by a seemingly-random 741 * number drawn from the highest 6 bits of the state. 742 * <br> 743 * This all can be done very quickly; a million hashes of a million different 16-element long arrays can be 744 * computed in under 18-20 ms (in the benchmark, some amount of that is overhead from generating a new 745 * array with LongPeriodRNG, since the benchmark uses that RNG's state for data, and the default 746 * Arrays.hashCode implementation is only somewhat faster at under 16 ms). After several tries and tweaks 747 * to the constants this uses, it also gets remarkably few hash collisions. On the same 0x100000, or 748 * 1048576, RNG states for data, Lightning gets 110 collisions, the JDK Arrays.hashCode method gets 129 749 * collisions, Sip (implementing SipHash) gets 145 collisions, and CrossHash (using the FNV-1a algorithm) 750 * gets 135 collisions. Dispersion is not perfect, but 751 * at many bit sizes Lightning continues to have less collisions (it disperses better than the other hashes 752 * with several quantities of bits, at least on this test data). Lightning also does relatively well, though 753 * it isn't clearly ahead of the rest all the time, when hashing Strings, especially ones that use a larger 754 * set of letters, it seems (FakeLanguageGen was used to make test data, and languages that used more 755 * characters in their alphabet seemed to hash better with this than competing hashes for some reason). 756 * <br> 757 * There is certainly room for improvement with the specific numbers chosen; earlier versions used the 758 * state multiplier "Neely's number", which is a probable prime made by taking the radix-29 number 759 * "HARGNALLINSCLOPIOPEEPIO" (a reference to a very unusual TV show), truncating to 64 bits, and rotating 760 * right by 42 bits. This version uses "Neely's number" for an initial state and during finalization, and 761 * uses a different probable prime as the state multiplier, made with a similar process; it starts with the 762 * radix-36 number "EDSGERWDIJKSTRA", then does the same process but rotates right by 37 bits to obtain a 763 * different prime. This tweak seems to help with hash collisions. Extensive trial and error was used to 764 * find the current output multiplier, which has no real relationship to anything else but has exactly 32 of 765 * 64 bits set to 1, has 1 in the least and most significant bit indices (meaning it is negative and odd), 766 * and other than that seems to have better results on most inputs for mystifying reasons. Earlier versions 767 * applied a Gray code step to alter the output instead of a multiplier that heavily overflows to obfuscate 768 * state, but that had a predictable pattern for most of the inputs tried, which seemed less-than-ideal for 769 * a hash. Vitally, Lightning avoids predictable collisions that Arrays.hashCode has, like 770 * {@code Arrays.hashCode(new long[]{0})==Arrays.hashCode(new long[]{-1})}. 771 * <br> 772 * The output multiplier is 0xC6BC279692B5CC83L, the state multiplier is 0xD0E89D2D311E289FL, the number 773 * added to the state (from LightRNG and code derived from FastUtil, but obtained from the golden ratio 774 * phi) is 0x9E3779B97F4A7C15L, and the starting state ("Neely's Number") is 0x632BE59BD9B4E019L. 775 * <br> 776 * To help find patterns in hash output in a visual way, you can hash an x,y point, take the bottom 24 bits, 777 * and use that as an RGB color for the pixel at that x,y point. On a 512x512 grid of points, the patterns 778 * in Arrays.hashCode and the default CrossHash algorithm (FNV-1a) are evident, and Sip (implementing 779 * SipHash) does approximately as well as Lightning, with no clear patterns visible (Sip has been removed 780 * from SquidLib because it needs a lot of code and is slower than Mist). The 781 * idea is from a technical report on visual uses for hashing, 782 * http://www.clockandflame.com/media/Goulburn06.pdf . 783 * <ul> 784 * <li>{@link java.util.Arrays#hashCode(int[])}: http://i.imgur.com/S4Gh1sX.png</li> 785 * <li>{@link CrossHash#hash(int[])}: http://i.imgur.com/x8SDqvL.png</li> 786 * <li>(Former) CrossHash.Sip.hash(int[]): http://i.imgur.com/keSpIwm.png</li> 787 * <li>{@link CrossHash.Lightning#hash(int[])}: http://i.imgur.com/afGJ9cA.png</li> 788 * </ul> 789 */ 790 // tested output multipliers 791 // 0x DA1A459BD9B4C619L 792 // 0x DC1A459879B5C619L 793 // 0x DC1A479829B5E639L 794 // 0x DC1A479C29B5C639L 795 // 0x EA1C479692B5C639L 796 // 0x CA1C479692B5C635L // this gets 105 collisions, low 797 // 0x CABC479692B5C635L 798 // 0x DC1A479C29B5C647L 799 // 0x DC1A479C29B5C725L 800 // 0x CABC279692B5CB21L 801 // 0x C6BC279692B5CC83L // this gets 100 collisions, lowest 802 // 0x C6BC279692B4D8A5L 803 // 0x C6BC279692B4D345L 804 // 0x C6EC273692B4A4B9L 805 // 0x C6A3256B52D5B463L 806 // 0x C6A3256B52D5B463L 807 // 0x C6A3256D52D5B4C9L 808 // 0x D8A3256D52D5B619L 809 // 0x D96E6AC724658947L 810 // 0x D96E6AC724658C2DL 811 // 0x CCABF9E32FD684F9L 812 // 0x C314163FAF912A01L 813 // 0x C3246007A332C12AL 814 // 0x CA1C479692B5C6ABL 815 // 0x C6B5275692B5CC83 // untested so far 816 public static final class Lightning { 817 818 public static long hash64(final boolean[] data) { 819 if (data == null) 820 return 0; 821 long z = 0x632BE59BD9B4E019L, result = 1L; 822 for (int i = 0; i < data.length; i++) { 823 result ^= (z += (data[i] ? 0x9E3779B97F4A7C94L : 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 824 } 825 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 826 } 827 828 public static long hash64(final byte[] data) { 829 if (data == null) 830 return 0; 831 long z = 0x632BE59BD9B4E019L, result = 1L; 832 for (int i = 0; i < data.length; i++) { 833 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 834 } 835 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 836 } 837 838 public static long hash64(final short[] data) { 839 if (data == null) 840 return 0; 841 long z = 0x632BE59BD9B4E019L, result = 1L; 842 for (int i = 0; i < data.length; i++) { 843 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 844 } 845 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 846 } 847 848 public static long hash64(final char[] data) { 849 if (data == null) 850 return 0; 851 long z = 0x632BE59BD9B4E019L, result = 1L; 852 for (int i = 0; i < data.length; i++) { 853 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 854 } 855 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 856 } 857 858 public static long hash64(final int[] data) { 859 if (data == null) 860 return 0; 861 long z = 0x632BE59BD9B4E019L, result = 1L; 862 for (int i = 0; i < data.length; i++) { 863 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 864 } 865 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 866 } 867 868 public static long hash64(final long[] data) { 869 if (data == null) 870 return 0; 871 long z = 0x632BE59BD9B4E019L, result = 1L; 872 for (int i = 0; i < data.length; i++) { 873 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 874 } 875 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 876 } 877 878 public static long hash64(final float[] data) { 879 if (data == null) 880 return 0; 881 long z = 0x632BE59BD9B4E019L, result = 1L; 882 for (int i = 0; i < data.length; i++) { 883 result ^= (z += (floatToIntBits(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 884 } 885 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 886 } 887 888 public static long hash64(final double[] data) { 889 if (data == null) 890 return 0; 891 long z = 0x632BE59BD9B4E019L, result = 1L; 892 for (int i = 0; i < data.length; i++) { 893 result ^= (z += (NumberTools.doubleToMixedIntBits(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 894 } 895 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 896 } 897 898 /** 899 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 900 * 901 * @param data the char array to hash 902 * @param start the start of the section to hash (inclusive) 903 * @param end the end of the section to hash (exclusive) 904 * @return a 64-bit hash code for the requested section of data 905 */ 906 public static long hash64(final char[] data, final int start, final int end) { 907 if (data == null || start >= end) 908 return 0; 909 long z = 0x632BE59BD9B4E019L, result = 1L; 910 for (int i = start; i < end && i < data.length; i++) { 911 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 912 } 913 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 914 } 915 /** 916 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 917 * moving between chars in increments of step (which is always greater than 0). 918 * 919 * @param data the char array to hash 920 * @param start the start of the section to hash (inclusive) 921 * @param end the end of the section to hash (exclusive) 922 * @param step how many elements to advance after using one element from data; must be greater than 0 923 * @return a 64-bit hash code for the requested section of data 924 */ 925 public static long hash64(final char[] data, final int start, final int end, final int step) { 926 if (data == null || start >= end || step <= 0) 927 return 0; 928 long z = 0x632BE59BD9B4E019L, result = 1L; 929 for (int i = start; i < end && i < data.length; i += step) { 930 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 931 } 932 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 933 } 934 935 public static long hash64(final CharSequence data) { 936 if (data == null) 937 return 0; 938 long z = 0x632BE59BD9B4E019L, result = 1L; 939 for (int i = 0; i < data.length(); i++) { 940 result ^= (z += (data.charAt(i) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 941 } 942 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 943 } 944 945 public static long hash64(final char[][] data) { 946 if (data == null) 947 return 0; 948 long z = 0x632BE59BD9B4E019L, result = 1L; 949 for (int i = 0; i < data.length; i++) { 950 result ^= (z += (hash64(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 951 } 952 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 953 } 954 955 public static long hash64(final long[][] data) { 956 if (data == null) 957 return 0; 958 long z = 0x632BE59BD9B4E019L, result = 1L; 959 for (int i = 0; i < data.length; i++) { 960 result ^= (z += (hash64(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 961 } 962 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 963 } 964 965 public static long hash64(final CharSequence[] data) { 966 if (data == null) 967 return 0; 968 long z = 0x632BE59BD9B4E019L, result = 1L; 969 for (int i = 0; i < data.length; i++) { 970 result ^= (z += (hash64(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 971 } 972 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 973 } 974 975 public static long hash64(final Iterable<? extends CharSequence> data) { 976 if (data == null) 977 return 0; 978 long z = 0x632BE59BD9B4E019L, result = 1L; 979 for (CharSequence datum : data) { 980 result ^= (z += (hash64(datum) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 981 } 982 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 983 } 984 985 public static long hash64(final CharSequence[]... data) { 986 if (data == null) 987 return 0; 988 long z = 0x632BE59BD9B4E019L, result = 1L; 989 for (int i = 0; i < data.length; i++) { 990 result ^= (z += (hash64(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 991 } 992 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 993 } 994 995 public static long hash64(final Object[] data) { 996 if (data == null) 997 return 0; 998 long z = 0x632BE59BD9B4E019L, result = 1L; 999 Object o; 1000 for (int i = 0; i < data.length; i++) { 1001 o = data[i]; 1002 result ^= (z += ((o == null ? 0 : o.hashCode()) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1003 } 1004 return result ^ Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58)); 1005 } 1006 1007 public static int hash(final boolean[] data) { 1008 if (data == null) 1009 return 0; 1010 long z = 0x632BE59BD9B4E019L, result = 1L; 1011 for (int i = 0; i < data.length; i++) { 1012 result ^= (z += (data[i] ? 0x9E3779B97F4A7C94L : 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1013 } 1014 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1015 } 1016 1017 public static int hash(final byte[] data) { 1018 if (data == null) 1019 return 0; 1020 long z = 0x632BE59BD9B4E019L, result = 1L; 1021 for (int i = 0; i < data.length; i++) { 1022 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1023 } 1024 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1025 } 1026 1027 public static int hash(final short[] data) { 1028 if (data == null) 1029 return 0; 1030 long z = 0x632BE59BD9B4E019L, result = 1L; 1031 for (int i = 0; i < data.length; i++) { 1032 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1033 } 1034 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1035 } 1036 1037 public static int hash(final char[] data) { 1038 if (data == null) 1039 return 0; 1040 long z = 0x632BE59BD9B4E019L, result = 1L; 1041 for (int i = 0; i < data.length; i++) { 1042 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1043 } 1044 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1045 } 1046 1047 public static int hash(final int[] data) { 1048 if (data == null) 1049 return 0; 1050 long z = 0x632BE59BD9B4E019L, result = 1L; 1051 for (int i = 0; i < data.length; i++) { 1052 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1053 1054 } 1055 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1056 } 1057 1058 public static int hash(final long[] data) { 1059 if (data == null) 1060 return 0; 1061 long z = 0x632BE59BD9B4E019L, result = 1L; 1062 for (int i = 0; i < data.length; i++) { 1063 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1064 } 1065 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1066 } 1067 1068 public static int hash(final float[] data) { 1069 if (data == null) 1070 return 0; 1071 long z = 0x632BE59BD9B4E019L, result = 1L; 1072 for (int i = 0; i < data.length; i++) { 1073 result ^= (z += (floatToIntBits(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1074 } 1075 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1076 } 1077 1078 public static int hash(final double[] data) { 1079 if (data == null) 1080 return 0; 1081 long z = 0x632BE59BD9B4E019L, result = 1L; 1082 for (int i = 0; i < data.length; i++) { 1083 result ^= (z += (NumberTools.doubleToMixedIntBits(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1084 } 1085 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1086 } 1087 1088 /** 1089 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 1090 * 1091 * @param data the char array to hash 1092 * @param start the start of the section to hash (inclusive) 1093 * @param end the end of the section to hash (exclusive) 1094 * @return a 32-bit hash code for the requested section of data 1095 */ 1096 public static int hash(final char[] data, final int start, final int end) { 1097 if (data == null || start >= end) 1098 return 0; 1099 1100 long z = 0x632BE59BD9B4E019L, result = 1L; 1101 for (int i = start; i < end && i < data.length; i++) { 1102 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1103 } 1104 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1105 } 1106 /** 1107 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 1108 * moving between chars in increments of step (which is always greater than 0). 1109 * 1110 * @param data the char array to hash 1111 * @param start the start of the section to hash (inclusive) 1112 * @param end the end of the section to hash (exclusive) 1113 * @param step how many elements to advance after using one element from data; must be greater than 0 1114 * @return a 32-bit hash code for the requested section of data 1115 */ 1116 public static int hash(final char[] data, final int start, final int end, final int step) { 1117 if (data == null || start >= end || step <= 0) 1118 return 0; 1119 1120 long z = 0x632BE59BD9B4E019L, result = 1L; 1121 for (int i = start; i < end && i < data.length; i += step) { 1122 result ^= (z += (data[i] + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1123 } 1124 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1125 } 1126 1127 public static int hash(final CharSequence data) { 1128 if (data == null) 1129 return 0; 1130 long z = 0x632BE59BD9B4E019L, result = 1L; 1131 for (int i = 0; i < data.length(); i++) { 1132 result ^= (z += (data.charAt(i) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1133 } 1134 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1135 } 1136 1137 public static int hash(final char[][] data) { 1138 if (data == null) 1139 return 0; 1140 long z = 0x632BE59BD9B4E019L, result = 1L; 1141 for (int i = 0; i < data.length; i++) { 1142 result ^= (z += (hash64(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1143 } 1144 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1145 } 1146 1147 public static int hash(final long[][] data) { 1148 if (data == null) 1149 return 0; 1150 long z = 0x632BE59BD9B4E019L, result = 1L; 1151 for (int i = 0; i < data.length; i++) { 1152 result ^= (z += (hash64(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1153 } 1154 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1155 } 1156 1157 public static int hash(final CharSequence[] data) { 1158 if (data == null) 1159 return 0; 1160 long z = 0x632BE59BD9B4E019L, result = 1L; 1161 for (int i = 0; i < data.length; i++) { 1162 result ^= (z += (hash64(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1163 } 1164 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1165 } 1166 1167 public static int hash(final Iterable<? extends CharSequence> data) { 1168 if (data == null) 1169 return 0; 1170 long z = 0x632BE59BD9B4E019L, result = 1L; 1171 for (CharSequence datum : data) { 1172 result ^= (z += (hash64(datum) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1173 } 1174 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1175 } 1176 1177 public static int hash(final CharSequence[]... data) { 1178 if (data == null) 1179 return 0; 1180 long z = 0x632BE59BD9B4E019L, result = 1L; 1181 for (int i = 0; i < data.length; i++) { 1182 result ^= (z += (hash64(data[i]) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1183 } 1184 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1185 } 1186 1187 public static int hash(final Object[] data) { 1188 if (data == null) 1189 return 0; 1190 long z = 0x632BE59BD9B4E019L, result = 1L; 1191 Object o; 1192 for (int i = 0; i < data.length; i++) { 1193 o = data[i]; 1194 result ^= (z += ((o == null ? 0 : o.hashCode()) + 0x9E3779B97F4A7C15L) * 0xD0E89D2D311E289FL) * 0xC6BC279692B5CC83L; 1195 } 1196 return (int) ((result ^= Long.rotateLeft((z * 0xC6BC279692B5CC83L ^ result * 0x9E3779B97F4A7C15L) + 0x632BE59BD9B4E019L, (int) (z >>> 58))) ^ (result >>> 32)); 1197 } 1198 } 1199 1200 // Nice ints, all probable primes except the last one, for 32-bit hashing 1201 // 0x62E2AC0D 0x632BE5AB 0x85157AF5 0x9E3779B9 1202 /** 1203 * The fastest hash in CrossHash, with middling quality. Uses a finely-tuned mix of very few operations for each 1204 * element, plus a minimal and simple finalization step, and as such obtains superior speed on the standard 1205 * benchmark SquidLib uses for hashes (hashing one million 16-element long arrays, remaining the best in both 32-bit 1206 * and 64-bit versions). Specifically, Wisp takes 9.478 ms to generate a million 64-bit hashes on a recent laptop 1207 * with an i7-6700HQ processor (removing the time the control takes to generate the million arrays). For comparison, 1208 * the JDK's Arrays.hashCode method takes 13.642 ms on the same workload, though it produces 32-bit hashes. Wisp 1209 * performs almost exactly as well producing 32-bit hashes as it does 64-bit hashes, where Hive slows down 1210 * significantly on some input types. This also passes visual tests where an earlier version of Wisp did not. 1211 * Collision rates are slightly worse than other CrossHash classes, but are better than the JDK's 1212 * Arrays.hashCode method, that is, acceptably low when given varied-enough inputs. On certain kinds of similar 1213 * inputs, Wisp will struggle with a higher collision rate. For example, when hashing Strings that contain only 1214 * several spaces, then some combination of digits 0-5, then more spaces, Wisp does very badly, worse than 1215 * {@link String#hashCode()} (which also does badly, though not as badly), while other hashes here do fine (such as 1216 * Water, which is the default for {@link CrossHash#hash(CharSequence)}). 1217 * <br> 1218 * This version replaces an older version of Wisp that had serious quality issues and wasn't quite as fast. Since 1219 * the only reason one would use the older version was speed without regard for quality, and it was marked as Beta, 1220 * a faster version makes sense to replace the slower one, rather than add yet another nested class in CrossHash. 1221 * <br> 1222 * Wisp is no longer considered Beta-quality, but even though it is rather fast, it has some cases where categories 1223 * of input cause frequent collisions. {@link Water} is about 20% slower but doesn't have such categories of 1224 * pathologically bad inputs, and passes tests that Wisp fails badly on. Because the hash-based collections in 1225 * SquidLib need a pretty good hash function to work at their best (they use linear-probing with open addressing, 1226 * which struggles when hashes are bad), 20% loss of speed during hashing to avoid slower 1227 * lookups/insertions/deletions from {@link OrderedMap}, {@link OrderedSet}, {@link UnorderedMap}, 1228 * {@link UnorderedSet}, {@link Arrangement}, and others is probably worth it; if you really need speed then you 1229 * should first consider {@link Curlup}, which is faster than Wisp on moderately-long input arrays (with 20 or more 1230 * items, usually), and only if you need a fast hash for small inputs, where collisions aren't a problem, should you 1231 * turn to Wisp. 1232 */ 1233 public static final class Wisp { 1234 public static long hash64(final boolean[] data) { 1235 if (data == null) 1236 return 0; 1237 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1238 final int len = data.length; 1239 for (int i = 0; i < len; i++) { 1240 result += (a ^= 0x8329C6EB9E6AD3E3L * (data[i] ? 0xC6BC279692B5CC83L : 0xAEF17502108EF2D9L)); 1241 } 1242 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1243 } 1244 1245 public static long hash64(final byte[] data) { 1246 if (data == null) 1247 return 0; 1248 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1249 final int len = data.length; 1250 for (int i = 0; i < len; i++) { 1251 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1252 } 1253 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1254 } 1255 1256 public static long hash64(final short[] data) { 1257 if (data == null) 1258 return 0; 1259 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1260 final int len = data.length; 1261 for (int i = 0; i < len; i++) { 1262 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1263 } 1264 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1265 } 1266 1267 public static long hash64(final char[] data) { 1268 if (data == null) 1269 return 0; 1270 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1271 final int len = data.length; 1272 for (int i = 0; i < len; i++) { 1273 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1274 } 1275 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1276 } 1277 1278 public static long hash64(final int[] data) { 1279 if (data == null) 1280 return 0; 1281 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1282 final int len = data.length; 1283 for (int i = 0; i < len; i++) { 1284 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1285 } 1286 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1287 } 1288 1289 public static long hash64(final long[] data) { 1290 if (data == null) 1291 return 0; 1292 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1293 final int len = data.length; 1294 for (int i = 0; i < len; i++) { 1295 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1296 } 1297 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1298 } 1299 1300 public static long hash64(final float[] data) { 1301 if (data == null) 1302 return 0; 1303 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1304 final int len = data.length; 1305 for (int i = 0; i < len; i++) { 1306 result += (a ^= 0x8329C6EB9E6AD3E3L * floatToIntBits(data[i])); 1307 } 1308 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1309 } 1310 1311 public static long hash64(final double[] data) { 1312 if (data == null) 1313 return 0; 1314 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1315 final int len = data.length; 1316 for (int i = 0; i < len; i++) { 1317 result += (a ^= 0x8329C6EB9E6AD3E3L * NumberTools.doubleToMixedIntBits(data[i])); 1318 } 1319 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1320 } 1321 1322 public static long hash64(final CharSequence data) { 1323 if (data == null) 1324 return 0; 1325 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1326 final int len = data.length(); 1327 for (int i = 0; i < len; i++) { 1328 result += (a ^= 0x8329C6EB9E6AD3E3L * data.charAt(i)); 1329 } 1330 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1331 } 1332 1333 /** 1334 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 1335 * 1336 * @param data the char array to hash 1337 * @param start the start of the section to hash (inclusive) 1338 * @param end the end of the section to hash (exclusive) 1339 * @return a 64-bit hash code for the requested section of data 1340 */ 1341 public static long hash64(final char[] data, final int start, final int end) { 1342 if (data == null || start >= end) 1343 return 0; 1344 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1345 final int len = Math.min(end, data.length); 1346 for (int i = start; i < len; i++) { 1347 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1348 } 1349 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1350 } 1351 1352 /** 1353 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 1354 * moving between chars in increments of step (which is always greater than 0). 1355 * 1356 * @param data the char array to hash 1357 * @param start the start of the section to hash (inclusive) 1358 * @param end the end of the section to hash (exclusive) 1359 * @param step how many elements to advance after using one element from data; must be greater than 0 1360 * @return a 64-bit hash code for the requested section of data 1361 */ 1362 public static long hash64(final char[] data, final int start, final int end, final int step) { 1363 if (data == null || start >= end || step <= 0) 1364 return 0; 1365 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1366 final int len = Math.min(end, data.length); 1367 for (int i = start; i < len; i += step) { 1368 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1369 } 1370 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1371 } 1372 1373 public static long hash64(final char[][] data) { 1374 if (data == null) 1375 return 0; 1376 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1377 final int len = data.length; 1378 for (int i = 0; i < len; i++) { 1379 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1380 } 1381 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1382 } 1383 1384 public static long hash64(final int[][] data) { 1385 if (data == null) 1386 return 0; 1387 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1388 final int len = data.length; 1389 for (int i = 0; i < len; i++) { 1390 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1391 } 1392 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1393 } 1394 1395 public static long hash64(final long[][] data) { 1396 if (data == null) 1397 return 0; 1398 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1399 final int len = data.length; 1400 for (int i = 0; i < len; i++) { 1401 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1402 } 1403 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1404 } 1405 1406 public static long hash64(final CharSequence[] data) { 1407 if (data == null) 1408 return 0; 1409 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1410 final int len = data.length; 1411 for (int i = 0; i < len; i++) { 1412 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1413 } 1414 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1415 } 1416 1417 public static long hash64(final CharSequence[]... data) { 1418 if (data == null) 1419 return 0; 1420 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1421 final int len = data.length; 1422 for (int i = 0; i < len; i++) { 1423 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1424 } 1425 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1426 } 1427 1428 public static long hash64(final Iterable<? extends CharSequence> data) { 1429 if (data == null) 1430 return 0; 1431 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1432 for (CharSequence datum : data) { 1433 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(datum)); 1434 } 1435 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1436 } 1437 1438 public static long hash64(final List<? extends CharSequence> data) { 1439 if (data == null) 1440 return 0; 1441 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1442 final int len = data.size(); 1443 for (int i = 0; i < len; i++) { 1444 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data.get(i))); 1445 } 1446 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1447 } 1448 1449 public static long hash64(final Object[] data) { 1450 if (data == null) 1451 return 0; 1452 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1453 final int len = data.length; 1454 Object o; 1455 for (int i = 0; i < len; i++) { 1456 result += (a ^= 0x8329C6EB9E6AD3E3L * ((o = data[i]) == null ? -1L : o.hashCode())); 1457 } 1458 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1459 } 1460 1461 public static long hash64(final Object data) { 1462 if (data == null) 1463 return 0L; 1464 long a = 0x632BE59BD9B4E019L ^ 0x8329C6EB9E6AD3E3L * data.hashCode(), result = 0x9E3779B97F4A7C94L + a; 1465 return result * (a | 1L) ^ (result << 37 | result >>> 27); 1466 } 1467 1468 public static int hash32(final boolean[] data) { 1469 if (data == null) 1470 return 0; 1471 int result = 0x9E3779B9, a = 0x632BE5AB; 1472 final int len = data.length; 1473 for (int i = 0; i < len; i++) { 1474 result += (a ^= 0x85157AF5 * (data[i] ? 0x789ABCDE : 0x62E2AC0D)); 1475 } 1476 return result * (a | 1) ^ (result >>> 11 | result << 21); 1477 } 1478 1479 1480 public static int hash32(final byte[] data) { 1481 if (data == null) 1482 return 0; 1483 int result = 0x9E3779B9, a = 0x632BE5AB; 1484 final int len = data.length; 1485 for (int i = 0; i < len; i++) { 1486 result += (a ^= 0x85157AF5 * data[i]); 1487 } 1488 return result * (a | 1) ^ (result >>> 11 | result << 21); 1489 } 1490 1491 public static int hash32(final short[] data) { 1492 if (data == null) 1493 return 0; 1494 int result = 0x9E3779B9, a = 0x632BE5AB; 1495 final int len = data.length; 1496 for (int i = 0; i < len; i++) { 1497 result += (a ^= 0x85157AF5 * data[i]); 1498 } 1499 return result * (a | 1) ^ (result >>> 11 | result << 21); 1500 } 1501 1502 public static int hash32(final char[] data) { 1503 if (data == null) 1504 return 0; 1505 int result = 0x9E3779B9, a = 0x632BE5AB; 1506 final int len = data.length; 1507 for (int i = 0; i < len; i++) { 1508 result += (a ^= 0x85157AF5 * data[i]); 1509 } 1510 return result * (a | 1) ^ (result >>> 11 | result << 21); 1511 } 1512 public static int hash32(final int[] data) { 1513 if (data == null) 1514 return 0; 1515 int result = 0x9E3779B9, a = 0x632BE5AB; 1516 final int len = data.length; 1517 for (int i = 0; i < len; i++) { 1518 result += (a ^= 0x85157AF5 * data[i]); 1519 } 1520 return result * (a | 1) ^ (result >>> 11 | result << 21); 1521 } 1522 1523 public static int hash32(final long[] data) { 1524 if (data == null) 1525 return 0; 1526 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1527 final int len = data.length; 1528 for (int i = 0; i < len; i++) { 1529 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1530 } 1531 return (int)((a += (result << 37 | result >>> 27)) ^ (a >>> 32)); 1532 } 1533 1534 public static int hash32(final float[] data) { 1535 if (data == null) 1536 return 0; 1537 int result = 0x9E3779B9, a = 0x632BE5AB; 1538 final int len = data.length; 1539 for (int i = 0; i < len; i++) { 1540 result += (a ^= 0x85157AF5 * floatToIntBits(data[i])); 1541 } 1542 return result * (a | 1) ^ (result >>> 11 | result << 21); 1543 } 1544 1545 public static int hash32(final double[] data) { 1546 if (data == null) 1547 return 0; 1548 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1549 final int len = data.length; 1550 double t; 1551 for (int i = 0; i < len; i++) { 1552 result += (a ^= 0x8329C6EB9E6AD3E3L * ((long) (-0xD0E8.9D2D311E289Fp-25 * (t = data[i]) + t * -0x1.39b4dce80194cp9))); 1553 } 1554 return (int)((result = (result * (a | 1L) ^ (result << 37 | result >>> 27))) ^ (result >>> 32)); 1555 } 1556 1557 public static int hash32(final CharSequence data) { 1558 if (data == null) 1559 return 0; 1560 int result = 0x9E3779B9, a = 0x632BE5AB; 1561 final int len = data.length(); 1562 for (int i = 0; i < len; i++) { 1563 result += (a ^= 0x85157AF5 * data.charAt(i)); 1564 } 1565 return result * (a | 1) ^ (result >>> 11 | result << 21); 1566 } 1567 1568 /** 1569 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 1570 * Uses 32-bit math on most platforms, but will give different results on GWT due to it using double values that 1571 * only somewhat act like int values. 1572 * @param data the char array to hash 1573 * @param start the start of the section to hash (inclusive) 1574 * @param end the end of the section to hash (exclusive) 1575 * @return a 32-bit hash code for the requested section of data 1576 */ 1577 public static int hash32(final char[] data, final int start, final int end) { 1578 if (data == null || start >= end) 1579 return 0; 1580 int result = 0x9E3779B9, a = 0x632BE5AB; 1581 final int len = Math.min(end, data.length); 1582 for (int i = start; i < len; i++) { 1583 result += (a ^= 0x85157AF5 * data[i]); 1584 } 1585 return result * (a | 1) ^ (result >>> 11 | result << 21); 1586 } 1587 1588 public static int hash32(final char[][] data) { 1589 if (data == null) 1590 return 0; 1591 int result = 0x9E3779B9, a = 0x632BE5AB; 1592 final int len = data.length; 1593 for (int i = 0; i < len; i++) { 1594 result += (a ^= 0x85157AF5 * hash32(data[i])); 1595 } 1596 return result * (a | 1) ^ (result >>> 11 | result << 21); 1597 } 1598 1599 public static int hash32(final int[][] data) { 1600 if (data == null) 1601 return 0; 1602 int result = 0x9E3779B9, a = 0x632BE5AB; 1603 final int len = data.length; 1604 for (int i = 0; i < len; i++) { 1605 result += (a ^= 0x85157AF5 * hash32(data[i])); 1606 } 1607 return result * (a | 1) ^ (result >>> 11 | result << 21); 1608 } 1609 1610 public static int hash32(final long[][] data) { 1611 if (data == null) 1612 return 0; 1613 int result = 0x9E3779B9, a = 0x632BE5AB; 1614 final int len = data.length; 1615 for (int i = 0; i < len; i++) { 1616 result += (a ^= 0x85157AF5 * hash32(data[i])); 1617 } 1618 return result * (a | 1) ^ (result >>> 11 | result << 21); 1619 } 1620 1621 public static int hash32(final CharSequence[] data) { 1622 if (data == null) 1623 return 0; 1624 int result = 0x9E3779B9, a = 0x632BE5AB; 1625 final int len = data.length; 1626 for (int i = 0; i < len; i++) { 1627 result += (a ^= 0x85157AF5 * hash32(data[i])); 1628 } 1629 return result * (a | 1) ^ (result >>> 11 | result << 21); 1630 } 1631 1632 public static int hash32(final CharSequence[]... data) { 1633 if (data == null) 1634 return 0; 1635 int result = 0x9E3779B9, a = 0x632BE5AB; 1636 final int len = data.length; 1637 for (int i = 0; i < len; i++) { 1638 result += (a ^= 0x85157AF5 * hash32(data[i])); 1639 } 1640 return result * (a | 1) ^ (result >>> 11 | result << 21); 1641 } 1642 1643 public static int hash32(final Iterable<? extends CharSequence> data) { 1644 if (data == null) 1645 return 0; 1646 int result = 0x9E3779B9, a = 0x632BE5AB; 1647 for (CharSequence datum : data) { 1648 result += (a ^= 0x85157AF5 * hash32(datum)); 1649 } 1650 return result * (a | 1) ^ (result >>> 11 | result << 21); 1651 } 1652 1653 public static int hash32(final List<? extends CharSequence> data) { 1654 if (data == null) 1655 return 0; 1656 int result = 0x9E3779B9, a = 0x632BE5AB; 1657 final int len = data.size(); 1658 for (int i = 0; i < len; i++) { 1659 result += (a ^= 0x85157AF5 * hash32(data.get(i))); 1660 } 1661 return result * (a | 1) ^ (result >>> 11 | result << 21); 1662 } 1663 1664 public static int hash32(final Object[] data) { 1665 if (data == null) 1666 return 0; 1667 int result = 0x9E3779B9, a = 0x632BE5AB; 1668 final int len = data.length; 1669 Object o; 1670 for (int i = 0; i < len; i++) { 1671 result += (a ^= 0x85157AF5 * ((o = data[i]) == null ? -1 : o.hashCode())); 1672 } 1673 return result * (a | 1) ^ (result >>> 11 | result << 21); 1674 } 1675 1676 public static int hash32(final Object data) { 1677 if (data == null) 1678 return 0; 1679 int a = 0x632BE5AB ^ 0x85157AF5 * data.hashCode(), result = 0x9E3779B9 + a; 1680 return result * (a | 1) ^ (result >>> 11 | result << 21); 1681 } 1682 public static int hash(final boolean[] data) { 1683 if (data == null) 1684 return 0; 1685 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1686 final int len = data.length; 1687 for (int i = 0; i < len; i++) { 1688 result += (a ^= 0x8329C6EB9E6AD3E3L * (data[i] ? 0xC6BC279692B5CC83L : 0xAEF17502108EF2D9L)); 1689 } 1690 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1691 } 1692 1693 public static int hash(final byte[] data) { 1694 if (data == null) 1695 return 0; 1696 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1697 final int len = data.length; 1698 for (int i = 0; i < len; i++) { 1699 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1700 } 1701 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1702 } 1703 1704 public static int hash(final short[] data) { 1705 if (data == null) 1706 return 0; 1707 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1708 final int len = data.length; 1709 for (int i = 0; i < len; i++) { 1710 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1711 } 1712 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1713 } 1714 1715 public static int hash(final char[] data) { 1716 if (data == null) 1717 return 0; 1718 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1719 final int len = data.length; 1720 for (int i = 0; i < len; i++) { 1721 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1722 } 1723 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1724 } 1725 1726 public static int hash(final int[] data) { 1727 if (data == null) 1728 return 0; 1729 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1730 final int len = data.length; 1731 for (int i = 0; i < len; i++) { 1732 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1733 } 1734 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1735 } 1736 1737 public static int hash(final long[] data) { 1738 if (data == null) 1739 return 0; 1740 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1741 final int len = data.length; 1742 for (int i = 0; i < len; i++) { 1743 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1744 } 1745 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1746 } 1747 1748 public static int hash(final float[] data) { 1749 if (data == null) 1750 return 0; 1751 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1752 final int len = data.length; 1753 for (int i = 0; i < len; i++) { 1754 result += (a ^= 0x8329C6EB9E6AD3E3L * floatToIntBits(data[i])); 1755 } 1756 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1757 } 1758 1759 public static int hash(final double[] data) { 1760 if (data == null) 1761 return 0; 1762 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1763 final int len = data.length; 1764 for (int i = 0; i < len; i++) { 1765 result += (a ^= 0x8329C6EB9E6AD3E3L * NumberTools.doubleToMixedIntBits(data[i])); 1766 } 1767 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1768 } 1769 1770 public static int hash(final CharSequence data) { 1771 if (data == null) 1772 return 0; 1773 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1774 final int len = data.length(); 1775 for (int i = 0; i < len; i++) { 1776 result += (a ^= 0x8329C6EB9E6AD3E3L * data.charAt(i)); 1777 } 1778 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1779 } 1780 /** 1781 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 1782 * 1783 * @param data the char array to hash 1784 * @param start the start of the section to hash (inclusive) 1785 * @param end the end of the section to hash (exclusive) 1786 * @return a 32-bit hash code for the requested section of data 1787 */ 1788 public static int hash(final char[] data, final int start, final int end) { 1789 if (data == null || start >= end) 1790 return 0; 1791 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1792 final int len = Math.min(end, data.length); 1793 for (int i = start; i < len; i++) { 1794 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1795 } 1796 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1797 } 1798 1799 /** 1800 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 1801 * moving between chars in increments of step (which is always greater than 0). 1802 * 1803 * @param data the char array to hash 1804 * @param start the start of the section to hash (inclusive) 1805 * @param end the end of the section to hash (exclusive) 1806 * @param step how many elements to advance after using one element from data; must be greater than 0 1807 * @return a 32-bit hash code for the requested section of data 1808 */ 1809 public static int hash(final char[] data, final int start, final int end, final int step) { 1810 if (data == null || start >= end || step <= 0) 1811 return 0; 1812 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1813 final int len = Math.min(end, data.length); 1814 for (int i = start; i < len; i+= step) { 1815 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]); 1816 } 1817 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1818 } 1819 1820 public static int hash(final char[][] data) { 1821 if (data == null) 1822 return 0; 1823 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1824 final int len = data.length; 1825 for (int i = 0; i < len; i++) { 1826 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1827 } 1828 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1829 } 1830 1831 public static int hash(final int[][] data) { 1832 if (data == null) 1833 return 0; 1834 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1835 final int len = data.length; 1836 for (int i = 0; i < len; i++) { 1837 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1838 } 1839 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1840 } 1841 1842 public static int hash(final long[][] data) { 1843 if (data == null) 1844 return 0; 1845 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1846 final int len = data.length; 1847 for (int i = 0; i < len; i++) { 1848 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1849 } 1850 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1851 } 1852 1853 public static int hash(final CharSequence[] data) { 1854 if (data == null) 1855 return 0; 1856 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1857 final int len = data.length; 1858 for (int i = 0; i < len; i++) { 1859 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1860 } 1861 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1862 } 1863 1864 public static int hash(final CharSequence[]... data) { 1865 if (data == null) 1866 return 0; 1867 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1868 final int len = data.length; 1869 for (int i = 0; i < len; i++) { 1870 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])); 1871 } 1872 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1873 } 1874 1875 public static int hash(final Iterable<? extends CharSequence> data) { 1876 if (data == null) 1877 return 0; 1878 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1879 for (CharSequence datum : data) { 1880 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(datum)); 1881 } 1882 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1883 } 1884 1885 public static int hash(final List<? extends CharSequence> data) { 1886 if (data == null) 1887 return 0; 1888 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1889 final int len = data.size(); 1890 for (int i = 0; i < len; i++) { 1891 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data.get(i))); 1892 } 1893 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1894 } 1895 1896 public static int hash(final Object[] data) { 1897 if (data == null) 1898 return 0; 1899 long result = 0x9E3779B97F4A7C94L, a = 0x632BE59BD9B4E019L; 1900 final int len = data.length; 1901 Object o; 1902 for (int i = 0; i < len; i++) { 1903 result += (a ^= 0x8329C6EB9E6AD3E3L * ((o = data[i]) == null ? -1 : o.hashCode())); 1904 } 1905 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1906 } 1907 1908 public static int hash(final Object data) { 1909 if (data == null) 1910 return 0; 1911 long a = 0x632BE59BD9B4E019L ^ 0x8329C6EB9E6AD3E3L * data.hashCode(), result = 0x9E3779B97F4A7C94L + a; 1912 return (int)(result * (a | 1L) ^ (result << 37 | result >>> 27)); 1913 } 1914 1915 } 1916 1917 /** 1918 * A whole cluster of Wisp-like hash functions that sacrifice a small degree of speed, but can be built with up 1919 * to 128 bits of salt values that help to obscure what hashing function is actually being used. This class is 1920 * similar to the older Storm variety, but is somewhat faster and has many more possible salt "states" when using 1921 * the constructors that take two longs or a CharSequence. There isn't really any reason to use Storm, so Mist has 1922 * now replaced Storm entirely. Code that used Storm should be able to just change any usage of "Storm" to "Mist", 1923 * or can instead use {@link Yolk} or {@link Curlup} for higher quality and speed but smaller salt size. 1924 * <br> 1925 * The salt fields are not serialized, so it is important that the same salt will be given by the 1926 * program when the same hash results are wanted for some inputs. 1927 * <br> 1928 * A group of 48 static, final, pre-initialized Mist members are present in this class, 24 with the 1929 * name of a letter in the Greek alphabet (this uses the convention on Wikipedia, 1930 * https://en.wikipedia.org/wiki/Greek_alphabet#Letters , where lambda is spelled with a 'b') and 24 with the same 1931 * name followed by an underscore, such as {@link #alpha_}. The whole group of 48 pre-initialized members are also 1932 * present in a static array called {@code predefined}. These can be useful when, for example, you want to get 1933 * multiple hashes of a single array or String as part of cuckoo hashing or similar techniques that need multiple 1934 * hashes for the same inputs. 1935 */ 1936 public static final class Mist implements Serializable { 1937 private static final long serialVersionUID = -1275284837479983271L; 1938 1939 private transient final long l1, l2; 1940 1941 public Mist() { 1942 this(0x1234567876543210L, 0xEDCBA98789ABCDEFL); 1943 } 1944 1945 public Mist(final CharSequence alteration) { 1946 this(CrossHash.hash64(alteration), Lightning.hash64(alteration)); 1947 } 1948 private static int permute(final long state) 1949 { 1950 int s = (int)state ^ 0xD0E89D2D; 1951 s = (s >>> 19 | s << 13); 1952 s ^= state >>> (5 + (state >>> 59)); 1953 return ((s *= 277803737) >>> 22) ^ s; 1954 } 1955 1956 @SuppressWarnings("NumericOverflow") 1957 public Mist(final long alteration) { 1958 long l1, l2; 1959 l1 = alteration + permute(alteration); 1960 l1 = (l1 ^ (l1 >>> 30)) * 0xBF58476D1CE4E5B9L; 1961 l1 = (l1 ^ (l1 >>> 27)) * 0x94D049BB133111EBL; 1962 this.l1 = l1 ^ l1 >>> 31; 1963 1964 l2 = alteration + 6 * 0x9E3779B97F4A7C15L; 1965 l2 = (l2 ^ (l2 >>> 30)) * 0xBF58476D1CE4E5B9L; 1966 l2 = (l2 ^ (l2 >>> 27)) * 0x94D049BB133111EBL; 1967 this.l2 = l2 ^ l2 >>> 31; 1968 } 1969 1970 public Mist(final long alteration1, long alteration2) { 1971 final int i1 = permute(alteration1); 1972 l1 = alteration1 + i1; 1973 l2 = alteration2 + permute(alteration2 + i1); 1974 } 1975 1976 /** 1977 * Makes a new Mist with all of the salt values altered based on the previous salt values. 1978 * This will make a different, incompatible Mist object that will give different results than the original. 1979 * Meant for use in Cuckoo Hashing, which can need the hash function to be updated or changed. 1980 * An alternative is to select a different Mist object from {@link #predefined}, or to simply 1981 * construct a new Mist with a different parameter or set of parameters. 1982 */ 1983 @SuppressWarnings("NumericOverflow") 1984 public Mist randomize() 1985 { 1986 long l1, l2; 1987 l1 = this.l2 + permute(this.l2 + 3 * 0x9E3779B97F4A7C15L); 1988 l1 = (l1 ^ (l1 >>> 30)) * 0xBF58476D1CE4E5B9L; 1989 l1 = (l1 ^ (l1 >>> 27)) * 0x94D049BB133111EBL; 1990 l1 ^= l1 >>> 31; 1991 1992 l2 = permute(l1 + 5 * 0x9E3779B97F4A7C15L) + 6 * 0x9E3779B97F4A7C15L; 1993 l2 = (l2 ^ (l2 >>> 30)) * 0xBF58476D1CE4E5B9L; 1994 l2 = (l2 ^ (l2 >>> 27)) * 0x94D049BB133111EBL; 1995 l2 ^= l2 >>> 31; 1996 1997 return new Mist(l1, l2); 1998 } 1999 2000 public static final Mist alpha = new Mist("alpha"), beta = new Mist("beta"), gamma = new Mist("gamma"), 2001 delta = new Mist("delta"), epsilon = new Mist("epsilon"), zeta = new Mist("zeta"), 2002 eta = new Mist("eta"), theta = new Mist("theta"), iota = new Mist("iota"), 2003 kappa = new Mist("kappa"), lambda = new Mist("lambda"), mu = new Mist("mu"), 2004 nu = new Mist("nu"), xi = new Mist("xi"), omicron = new Mist("omicron"), pi = new Mist("pi"), 2005 rho = new Mist("rho"), sigma = new Mist("sigma"), tau = new Mist("tau"), 2006 upsilon = new Mist("upsilon"), phi = new Mist("phi"), chi = new Mist("chi"), psi = new Mist("psi"), 2007 omega = new Mist("omega"), 2008 alpha_ = new Mist("ALPHA"), beta_ = new Mist("BETA"), gamma_ = new Mist("GAMMA"), 2009 delta_ = new Mist("DELTA"), epsilon_ = new Mist("EPSILON"), zeta_ = new Mist("ZETA"), 2010 eta_ = new Mist("ETA"), theta_ = new Mist("THETA"), iota_ = new Mist("IOTA"), 2011 kappa_ = new Mist("KAPPA"), lambda_ = new Mist("LAMBDA"), mu_ = new Mist("MU"), 2012 nu_ = new Mist("NU"), xi_ = new Mist("XI"), omicron_ = new Mist("OMICRON"), pi_ = new Mist("PI"), 2013 rho_ = new Mist("RHO"), sigma_ = new Mist("SIGMA"), tau_ = new Mist("TAU"), 2014 upsilon_ = new Mist("UPSILON"), phi_ = new Mist("PHI"), chi_ = new Mist("CHI"), psi_ = new Mist("PSI"), 2015 omega_ = new Mist("OMEGA"); 2016 /** 2017 * Has a length of 48, which may be relevant if automatically choosing a predefined hash functor. 2018 */ 2019 public static final Mist[] predefined = new Mist[]{alpha, beta, gamma, delta, epsilon, zeta, eta, theta, iota, 2020 kappa, lambda, mu, nu, xi, omicron, pi, rho, sigma, tau, upsilon, phi, chi, psi, omega, 2021 alpha_, beta_, gamma_, delta_, epsilon_, zeta_, eta_, theta_, iota_, 2022 kappa_, lambda_, mu_, nu_, xi_, omicron_, pi_, rho_, sigma_, tau_, upsilon_, phi_, chi_, psi_, omega_}; 2023 2024 public long hash64(final boolean[] data) { 2025 if (data == null) 2026 return 0; 2027 final int len = data.length; 2028 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2029 for (int i = 0; i < len; i++) { 2030 result += (a ^= 0x8329C6EB9E6AD3E3L * (data[i] ? 0x9E3779B97F4A7C15L : 0x789ABCDEFEDCBA98L)) ^ l2 * a + l1; 2031 } 2032 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2033 } 2034 2035 2036 public long hash64(final byte[] data) { 2037 if (data == null) 2038 return 0; 2039 final int len = data.length; 2040 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2041 for (int i = 0; i < len; i++) { 2042 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2043 } 2044 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2045 } 2046 2047 public long hash64(final short[] data) { 2048 if (data == null) 2049 return 0; 2050 final int len = data.length; 2051 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2052 for (int i = 0; i < len; i++) { 2053 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2054 } 2055 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2056 } 2057 2058 public long hash64(final char[] data) { 2059 if (data == null) 2060 return 0; 2061 final int len = data.length; 2062 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2063 for (int i = 0; i < len; i++) { 2064 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2065 } 2066 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2067 } 2068 2069 public long hash64(final int[] data) { 2070 if (data == null) 2071 return 0; 2072 final int len = data.length; 2073 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2074 for (int i = 0; i < len; i++) { 2075 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2076 } 2077 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2078 } 2079 2080 public long hash64(final long[] data) { 2081 if (data == null) 2082 return 0; 2083 final int len = data.length; 2084 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2085 for (int i = 0; i < len; i++) { 2086 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2087 } 2088 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2089 } 2090 2091 2092 public long hash64(final float[] data) { 2093 if (data == null) 2094 return 0; 2095 final int len = data.length; 2096 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2097 for (int i = 0; i < len; i++) { 2098 result += (a ^= 0x8329C6EB9E6AD3E3L * floatToIntBits(data[i])) ^ l2 * a + l1; 2099 } 2100 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2101 } 2102 2103 public long hash64(final double[] data) { 2104 if (data == null) 2105 return 0; 2106 final int len = data.length; 2107 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2108 for (int i = 0; i < len; i++) { 2109 result += (a ^= 0x8329C6EB9E6AD3E3L * NumberTools.doubleToMixedIntBits(data[i])) ^ l2 * a + l1; 2110 } 2111 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2112 } 2113 2114 /** 2115 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 2116 * 2117 * @param data the char array to hash 2118 * @param start the start of the section to hash (inclusive) 2119 * @param end the end of the section to hash (exclusive) 2120 * @return a 64-bit hash code for the requested section of data 2121 */ 2122 public long hash64(final char[] data, final int start, final int end) { 2123 if (data == null || start >= end) 2124 return 0; 2125 final int len = data.length; 2126 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2127 for (int i = start; i < end && i < len; i++) { 2128 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2129 } 2130 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2131 } 2132 2133 /** 2134 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 2135 * moving between chars in increments of step (which is always greater than 0). 2136 * 2137 * @param data the char array to hash 2138 * @param start the start of the section to hash (inclusive) 2139 * @param end the end of the section to hash (exclusive) 2140 * @param step how many elements to advance after using one element from data; must be greater than 0 2141 * @return a 64-bit hash code for the requested section of data 2142 */ 2143 public long hash64(final char[] data, final int start, final int end, final int step) { 2144 if (data == null || start >= end || step <= 0) 2145 return 0; 2146 final int len = data.length; 2147 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2148 for (int i = start; i < end && i < len; i += step) { 2149 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2150 } 2151 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2152 } 2153 2154 public long hash64(final CharSequence data) { 2155 if (data == null) 2156 return 0; 2157 final int len = data.length(); 2158 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2159 for (int i = 0; i < len; i++) { 2160 result += (a ^= 0x8329C6EB9E6AD3E3L * data.charAt(i)) ^ l2 * a + l1; 2161 } 2162 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2163 } 2164 2165 public long hash64(final char[][] data) { 2166 if (data == null) 2167 return 0; 2168 final int len = data.length; 2169 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2170 for (int i = 0; i < len; i++) { 2171 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])) ^ l2 * a + l1; 2172 } 2173 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2174 } 2175 2176 public long hash64(final long[][] data) { 2177 if (data == null) 2178 return 0; 2179 final int len = data.length; 2180 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2181 for (int i = 0; i < len; i++) { 2182 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])) ^ l2 * a + l1; 2183 } 2184 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2185 } 2186 2187 public long hash64(final CharSequence[] data) { 2188 if (data == null) 2189 return 0; 2190 final int len = data.length; 2191 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2192 for (int i = 0; i < len; i++) { 2193 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])) ^ l2 * a + l1; 2194 } 2195 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2196 } 2197 2198 public long hash64(final Iterable<? extends CharSequence> data) { 2199 if (data == null) 2200 return 0; 2201 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2202 for (CharSequence datum : data) { 2203 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(datum)) ^ l2 * a + l1; 2204 } 2205 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2206 } 2207 2208 public long hash64(final CharSequence[]... data) { 2209 if (data == null) 2210 return 0; 2211 final int len = data.length; 2212 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2213 for (int i = 0; i < len; i++) { 2214 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])) ^ l2 * a + l1; 2215 } 2216 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2217 } 2218 2219 public long hash64(final Object[] data) { 2220 if (data == null) 2221 return 0; 2222 final int len = data.length; 2223 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2224 Object o; 2225 for (int i = 0; i < len; i++) { 2226 result += (a ^= 0x8329C6EB9E6AD3E3L * ((o = data[i]) == null ? -1 : o.hashCode())) ^ l2 * a + l1; 2227 } 2228 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2229 } 2230 2231 public long hash64(final Object data) { 2232 if (data == null) 2233 return 0; 2234 final long a = 0x632BE59BD9B4E019L ^ 0x8329C6EB9E6AD3E3L * data.hashCode(), 2235 result = 0x9E3779B97F4A7C94L + l2 + (a ^ l2 * a + l1); 2236 return result * (a * l1 | 1L) ^ (result << 37 | result >>> 27); 2237 } 2238 public int hash(final boolean[] data) { 2239 if (data == null) 2240 return 0; 2241 final int len = data.length; 2242 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2243 for (int i = 0; i < len; i++) { 2244 result += (a ^= 0x8329C6EB9E6AD3E3L * (data[i] ? 0x9E3779B97F4A7C15L : 0x789ABCDEFEDCBA98L)) ^ l2 * a + l1; 2245 } 2246 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2247 } 2248 2249 2250 public int hash(final byte[] data) { 2251 if (data == null) 2252 return 0; 2253 final int len = data.length; 2254 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2255 for (int i = 0; i < len; i++) { 2256 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2257 } 2258 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2259 } 2260 2261 public int hash(final short[] data) { 2262 if (data == null) 2263 return 0; 2264 final int len = data.length; 2265 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2266 for (int i = 0; i < len; i++) { 2267 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2268 } 2269 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2270 } 2271 2272 public int hash(final char[] data) { 2273 if (data == null) 2274 return 0; 2275 final int len = data.length; 2276 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2277 for (int i = 0; i < len; i++) { 2278 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2279 } 2280 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2281 } 2282 2283 public int hash(final int[] data) { 2284 if (data == null) 2285 return 0; 2286 final int len = data.length; 2287 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2288 for (int i = 0; i < len; i++) { 2289 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2290 } 2291 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2292 } 2293 2294 public int hash(final long[] data) { 2295 if (data == null) 2296 return 0; 2297 final int len = data.length; 2298 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2299 for (int i = 0; i < len; i++) { 2300 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2301 } 2302 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2303 } 2304 2305 2306 public int hash(final float[] data) { 2307 if (data == null) 2308 return 0; 2309 final int len = data.length; 2310 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2311 for (int i = 0; i < len; i++) { 2312 result += (a ^= 0x8329C6EB9E6AD3E3L * floatToIntBits(data[i])) ^ l2 * a + l1; 2313 } 2314 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2315 } 2316 2317 public int hash(final double[] data) { 2318 if (data == null) 2319 return 0; 2320 final int len = data.length; 2321 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2322 for (int i = 0; i < len; i++) { 2323 result += (a ^= 0x8329C6EB9E6AD3E3L * NumberTools.doubleToMixedIntBits(data[i])) ^ l2 * a + l1; 2324 } 2325 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2326 } 2327 2328 /** 2329 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 2330 * 2331 * @param data the char array to hash 2332 * @param start the start of the section to hash (inclusive) 2333 * @param end the end of the section to hash (exclusive) 2334 * @return a 32-bit hash code for the requested section of data 2335 */ 2336 public int hash(final char[] data, final int start, final int end) { 2337 if (data == null || start >= end) 2338 return 0; 2339 final int len = data.length; 2340 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2341 for (int i = start; i < end && i < len; i++) { 2342 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2343 } 2344 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2345 } 2346 /** 2347 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 2348 * moving between chars in increments of step (which is always greater than 0). 2349 * 2350 * @param data the char array to hash 2351 * @param start the start of the section to hash (inclusive) 2352 * @param end the end of the section to hash (exclusive) 2353 * @param step how many elements to advance after using one element from data; must be greater than 0 2354 * @return a 32-bit hash code for the requested section of data 2355 */ 2356 public int hash(final char[] data, final int start, final int end, final int step) { 2357 if (data == null || start >= end || step <= 0) 2358 return 0; 2359 final int len = data.length; 2360 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2361 for (int i = start; i < end && i < len; i += step) { 2362 result += (a ^= 0x8329C6EB9E6AD3E3L * data[i]) ^ l2 * a + l1; 2363 } 2364 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2365 } 2366 2367 public int hash(final CharSequence data) { 2368 if (data == null) 2369 return 0; 2370 final int len = data.length(); 2371 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2372 for (int i = 0; i < len; i++) { 2373 result += (a ^= 0x8329C6EB9E6AD3E3L * data.charAt(i)) ^ l2 * a + l1; 2374 } 2375 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2376 } 2377 2378 public int hash(final char[][] data) { 2379 if (data == null) 2380 return 0; 2381 final int len = data.length; 2382 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2383 for (int i = 0; i < len; i++) { 2384 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])) ^ l2 * a + l1; 2385 } 2386 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2387 } 2388 2389 public int hash(final long[][] data) { 2390 if (data == null) 2391 return 0; 2392 final int len = data.length; 2393 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2394 for (int i = 0; i < len; i++) { 2395 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])) ^ l2 * a + l1; 2396 } 2397 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2398 } 2399 2400 public int hash(final CharSequence[] data) { 2401 if (data == null) 2402 return 0; 2403 final int len = data.length; 2404 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2405 for (int i = 0; i < len; i++) { 2406 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])) ^ l2 * a + l1; 2407 } 2408 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2409 } 2410 2411 public int hash(final Iterable<? extends CharSequence> data) { 2412 if (data == null) 2413 return 0; 2414 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2415 for (CharSequence datum : data) { 2416 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(datum)) ^ l2 * a + l1; 2417 } 2418 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2419 } 2420 2421 public int hash(final CharSequence[]... data) { 2422 if (data == null) 2423 return 0; 2424 final int len = data.length; 2425 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2426 for (int i = 0; i < len; i++) { 2427 result += (a ^= 0x8329C6EB9E6AD3E3L * hash64(data[i])) ^ l2 * a + l1; 2428 } 2429 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2430 } 2431 2432 public int hash(final Object[] data) { 2433 if (data == null) 2434 return 0; 2435 final int len = data.length; 2436 long result = 0x9E3779B97F4A7C94L + l2, a = 0x632BE59BD9B4E019L; 2437 Object o; 2438 for (int i = 0; i < len; i++) { 2439 result += (a ^= 0x8329C6EB9E6AD3E3L * ((o = data[i]) == null ? -1 : o.hashCode())) ^ l2 * a + l1; 2440 } 2441 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2442 } 2443 2444 public int hash(final Object data) { 2445 if (data == null) 2446 return 0; 2447 final long a = 0x632BE59BD9B4E019L ^ 0x8329C6EB9E6AD3E3L * data.hashCode(), 2448 result = 0x9E3779B97F4A7C94L + l2 + (a ^ l2 * a + l1); 2449 return (int)(result * (a * l1 | 1L) ^ (result << 37 | result >>> 27)); 2450 } 2451 } 2452 2453 /** 2454 * A reasonably-fast hashing function that passes some of SMHasher's quality tests, but neither critically fails nor 2455 * overwhelmingly succeeds the full SMHasher test battery. This was the default used by methods in the 2456 * outer class like {@link CrossHash#hash(int[])}, but it has been replaced there by {@link Water}; you should 2457 * prefer using the outer class since this inner class is only here for reference. The one advantage Hive has over 2458 * Water is potentially better optimization for GWT, but since the main usage of CrossHash is for 64-bit hashes, GWT 2459 * will be slow regardless for that usage. 2460 * <br> 2461 * This mixes three different algorithms: the main one is used whenever inputs or outputs are 64-bit (so, all 2462 * hash64() overloads and {@link Hive#hash(long[])} for long and double), a modification of the main one to perform 2463 * better on GWT (only used on hash() overloads, and only when inputs are individually 32-bit or less), and 2464 * a simpler algorithm (which was called Jolt) for hash64() on boolean and byte data. 2465 * <br> 2466 * Speed-wise, the main algorithm is about 20% slower than Wisp, but in hash tables it doesn't have clear failure 2467 * cases like Wisp does on some inputs (such as fixed-length Strings with identical prefixes). If collisions are 2468 * expensive or profiling shows that Wisp's algorithm is colliding at a high rate, you should probably use the 2469 * normal IHasher and CrossHash.hash() methods, since those will use Hive. The modified algorithm for GWT is a 2470 * little slower than the main algorithm in the C++ implementation that was used to check SMHasher quality, but it 2471 * may perform similarly to the main algorithm in Java on desktop platforms. Since it avoids creating longs or doing 2472 * any math on them, it should be at least 3x faster than the main algorithm on GWT (a GWT long is internally 2473 * represented by 3 JS numbers, so barring special optimizations it takes at least 3x as many math operations to use 2474 * longs there). 2475 * <br> 2476 * Its design uses two states like {@link Lightning} or {@link Wisp}, updating them differently from each other, and 2477 * bitwise-rotates one at each step. It combines the states (xorshifting one state, multiplying it by a huge 2478 * constant, and adding that to the other state) and then runs that through MurmurHash3's finalization function (its 2479 * {@code fmix64()} function; the main algorithm elides one xorshift at the end that proved unnecessary). Parts of 2480 * the code here are inspired by the design of {@link DiverRNG}, particularly its determine() method since both 2481 * use an XLCG (XOR Linear Congruential Generator, as PractRand calls it) as a processing step. 2482 * <br> 2483 * The name comes from the song I was listening to when I finally got the tests to pass ("Slave The Hive" by High On 2484 * Fire) and from the wide assortment of code that I had to employ to achieve a SMHasher successful run (which 2485 * turned out to be not-so-successful). 2486 */ 2487 public static final class Hive { 2488 public static long hash64(final CharSequence data) { 2489 if (data == null) 2490 return 0L; 2491 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2492 final int len = data.length(); 2493 for (int i = 0; i < len; i++) { 2494 result ^= (z += (data.charAt(i) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2495 result = (result << 54 | result >>> 10); 2496 } 2497 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2498 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2499 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2500 } 2501 2502 public static long hash64(final boolean[] data) { 2503 if (data == null) 2504 return 0L; 2505 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2506 final int len = data.length; 2507 for (int i = 0; i < len; i++) { 2508 result ^= (z += (data[i] ? 0xFF51AFD7ED558CCDL : 0xC4CEB9FE1A85EC53L)); 2509 } 2510 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2511 result ^= result >>> 25 ^ z ^ z >>> 29; 2512 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2513 result = (result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L; 2514 return (result ^ result >>> 33); 2515 } 2516 2517 public static long hash64(final byte[] data) { 2518 if (data == null) 2519 return 0L; 2520 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2521 final int len = data.length; 2522 for (int i = 0; i < len; i++) { 2523 result ^= (z += (data[i] ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L); 2524 } 2525 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2526 result ^= result >>> 25 ^ z ^ z >>> 29; 2527 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2528 result = (result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L; 2529 return (result ^ result >>> 33); 2530 } 2531 2532 public static long hash64(final short[] data) { 2533 if (data == null) 2534 return 0L; 2535 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2536 final int len = data.length; 2537 for (int i = 0; i < len; i++) { 2538 result ^= (z += (data[i] ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2539 result = (result << 54 | result >>> 10); 2540 } 2541 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2542 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2543 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2544 } 2545 2546 public static long hash64(final int[] data) { 2547 if (data == null) 2548 return 0L; 2549 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2550 final int len = data.length; 2551 for (int i = 0; i < len; i++) { 2552 result ^= (z += (data[i] ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2553 result = (result << 54 | result >>> 10); 2554 } 2555 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2556 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2557 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2558 } 2559 2560 public static long hash64(final long[] data) { 2561 if (data == null) 2562 return 0L; 2563 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2564 final int len = data.length; 2565 for (int i = 0; i < len; i++) { 2566 result ^= (z += (data[i] ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2567 result = (result << 54 | result >>> 10); 2568 } 2569 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2570 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2571 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2572 } 2573 2574 public static long hash64(final char[] data) { 2575 if (data == null) 2576 return 0L; 2577 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2578 final int len = data.length; 2579 for (int i = 0; i < len; i++) { 2580 result ^= (z += (data[i] ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2581 result = (result << 54 | result >>> 10); 2582 } 2583 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2584 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2585 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2586 } 2587 2588 public static long hash64(final float[] data) { 2589 if (data == null) 2590 return 0L; 2591 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2592 final int len = data.length; 2593 for (int i = 0; i < len; i++) { 2594 result ^= (z += (floatToIntBits(data[i]) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2595 result = (result << 54 | result >>> 10); 2596 } 2597 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2598 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2599 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2600 } 2601 2602 public static long hash64(final double[] data) { 2603 if (data == null) 2604 return 0L; 2605 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2606 final int len = data.length; 2607 for (int i = 0; i < len; i++) { 2608 result ^= (z += (NumberTools.doubleToLongBits(data[i]) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2609 result = (result << 54 | result >>> 10); 2610 } 2611 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2612 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2613 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2614 } 2615 2616 /** 2617 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 2618 * 2619 * @param data the char array to hash 2620 * @param start the start of the section to hash (inclusive) 2621 * @param end the end of the section to hash (exclusive) 2622 * @return a 32-bit hash code for the requested section of data 2623 */ 2624 public static long hash64(final char[] data, final int start, final int end) { 2625 if (data == null || start >= end) 2626 return 0L; 2627 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2628 final int len = Math.min(end, data.length); 2629 for (int i = start; i < len; i++) { 2630 result ^= (z += (data[i] ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2631 result = (result << 54 | result >>> 10); 2632 } 2633 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2634 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2635 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2636 } 2637 2638 /** 2639 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 2640 * 2641 * @param data the String or other CharSequence to hash 2642 * @param start the start of the section to hash (inclusive) 2643 * @param end the end of the section to hash (exclusive) 2644 * @return a 32-bit hash code for the requested section of data 2645 */ 2646 public static long hash64(final CharSequence data, final int start, final int end) { 2647 if (data == null || start >= end) 2648 return 0L; 2649 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2650 final int len = Math.min(end, data.length()); 2651 for (int i = start; i < len; i++) { 2652 result ^= (z += (data.charAt(i) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2653 result = (result << 54 | result >>> 10); 2654 } 2655 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2656 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2657 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2658 } 2659 2660 /** 2661 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 2662 * moving between chars in increments of step (which is always greater than 0). 2663 * 2664 * @param data the char array to hash 2665 * @param start the start of the section to hash (inclusive) 2666 * @param end the end of the section to hash (exclusive) 2667 * @param step how many elements to advance after using one element from data; must be greater than 0 2668 * @return a 32-bit hash code for the requested section of data 2669 */ 2670 public static long hash64(final char[] data, final int start, final int end, final int step) { 2671 if (data == null || start >= end || step <= 0) 2672 return 0L; 2673 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2674 final int len = Math.min(end, data.length); 2675 for (int i = start; i < len; i += step) { 2676 result ^= (z += (data[i] ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2677 result = (result << 54 | result >>> 10); 2678 } 2679 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2680 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2681 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2682 } 2683 2684 /** 2685 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 2686 * moving between chars in increments of step (which is always greater than 0). 2687 * 2688 * @param data the String or other CharSequence to hash 2689 * @param start the start of the section to hash (inclusive) 2690 * @param end the end of the section to hash (exclusive) 2691 * @param step how many elements to advance after using one element from data; must be greater than 0 2692 * @return a 32-bit hash code for the requested section of data 2693 */ 2694 public static long hash64(final CharSequence data, final int start, final int end, final int step) { 2695 if (data == null || start >= end || step <= 0) 2696 return 0L; 2697 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2698 final int len = Math.min(end, data.length()); 2699 for (int i = start; i < len; i += step) { 2700 result ^= (z += (data.charAt(i) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2701 result = (result << 54 | result >>> 10); 2702 } 2703 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2704 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2705 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2706 } 2707 2708 public static long hash64(final char[][] data) { 2709 if (data == null) 2710 return 0L; 2711 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2712 final int len = data.length; 2713 for (int i = 0; i < len; i++) { 2714 result ^= (z += (hash64(data[i]) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2715 result = (result << 54 | result >>> 10); 2716 } 2717 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2718 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2719 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2720 } 2721 2722 public static long hash64(final int[][] data) { 2723 if (data == null) 2724 return 0L; 2725 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2726 final int len = data.length; 2727 for (int i = 0; i < len; i++) { 2728 result ^= (z += (hash64(data[i]) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2729 result = (result << 54 | result >>> 10); 2730 } 2731 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2732 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2733 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2734 } 2735 2736 public static long hash64(final long[][] data) { 2737 if (data == null) 2738 return 0L; 2739 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2740 final int len = data.length; 2741 for (int i = 0; i < len; i++) { 2742 result ^= (z += (hash64(data[i]) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2743 result = (result << 54 | result >>> 10); 2744 } 2745 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2746 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2747 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2748 } 2749 2750 public static long hash64(final CharSequence[] data) { 2751 if (data == null) 2752 return 0L; 2753 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2754 final int len = data.length; 2755 for (int i = 0; i < len; i++) { 2756 result ^= (z += (hash64(data[i]) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2757 result = (result << 54 | result >>> 10); 2758 } 2759 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2760 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2761 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2762 } 2763 2764 public static long hash64(final CharSequence[]... data) { 2765 if (data == null) 2766 return 0L; 2767 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2768 final int len = data.length; 2769 for (int i = 0; i < len; i++) { 2770 result ^= (z += (hash64(data[i]) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2771 result = (result << 54 | result >>> 10); 2772 } 2773 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2774 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2775 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2776 } 2777 2778 public static long hash64(final Iterable<? extends CharSequence> data) { 2779 if (data == null) 2780 return 0L; 2781 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2782 for (CharSequence datum : data) { 2783 result ^= (z += (hash64(datum) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2784 result = (result << 54 | result >>> 10); 2785 } 2786 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2787 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2788 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2789 2790 } 2791 2792 public static long hash64(final List<? extends CharSequence> data) { 2793 if (data == null) 2794 return 0L; 2795 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2796 final int len = data.size(); 2797 for (int i = 0; i < len; i++) { 2798 result ^= (z += (hash64(data.get(i)) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2799 result = (result << 54 | result >>> 10); 2800 } 2801 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2802 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2803 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2804 2805 } 2806 2807 public static long hash64(final Object[] data) { 2808 if (data == null) 2809 return 0L; 2810 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2811 final int len = data.length; 2812 Object o; 2813 for (int i = 0; i < len; i++) { 2814 result ^= (z += (((o = data[i]) == null ? -1L : o.hashCode()) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2815 result = (result << 54 | result >>> 10); 2816 } 2817 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2818 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2819 return ((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2820 } 2821 2822 public static long hash64(final Object data) { 2823 if (data == null) 2824 return 0L; 2825 long result = data.hashCode() * 0xFF51AFD7ED558CCDL; 2826 result = (result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L; 2827 return (result ^ result >>> 33); 2828 } 2829 2830 2831 public static int hash(final CharSequence data) { 2832 if (data == null) 2833 return 0; 2834 int result = 0x1A976FDF, z = 0x60642E25; 2835 final int len = data.length(); 2836 for (int i = 0; i < len; i++) { 2837 result ^= (z += (data.charAt(i) ^ 0xC3564E95) * 0x9E375); 2838 z ^= (result = (result << 20 | result >>> 12)); 2839 } 2840 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 2841 result = (result ^ result >>> 15) * 0xFF51D; 2842 result = (result ^ result >>> 15) * 0xC4CEB; 2843 return result ^ result >>> 15; 2844 } 2845 2846 public static int hash(final boolean[] data) { 2847 if (data == null) 2848 return 0; 2849 int result = 0x1A976FDF, z = 0x60642E25; 2850 final int len = data.length; 2851 for (int i = 0; i < len; i++) { 2852 result ^= (z += (data[i] ? 0x6F51AFDB : 0xC3564E95)); 2853 z ^= (result = (result << 20 | result >>> 12)); 2854 } 2855 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 2856 result = (result ^ result >>> 15) * 0xFF51D; 2857 result = (result ^ result >>> 15) * 0xC4CEB; 2858 return result ^ result >>> 15; 2859 } 2860 2861 public static int hash(final byte[] data) { 2862 if (data == null) 2863 return 0; 2864 int result = 0x1A976FDF, z = 0x60642E25; 2865 final int len = data.length; 2866 for (int i = 0; i < len; i++) { 2867 result ^= (z += (data[i] ^ 0xC3564E95) * 0x9E375); 2868 z ^= (result = (result << 20 | result >>> 12)); 2869 } 2870 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 2871 result = (result ^ result >>> 15) * 0xFF51D; 2872 result = (result ^ result >>> 15) * 0xC4CEB; 2873 return result ^ result >>> 15; 2874 } 2875 2876 public static int hash(final short[] data) { 2877 if (data == null) 2878 return 0; 2879 int result = 0x1A976FDF, z = 0x60642E25; 2880 final int len = data.length; 2881 for (int i = 0; i < len; i++) { 2882 result ^= (z += (data[i] ^ 0xC3564E95) * 0x9E375); 2883 z ^= (result = (result << 20 | result >>> 12)); 2884 } 2885 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 2886 result = (result ^ result >>> 15) * 0xFF51D; 2887 result = (result ^ result >>> 15) * 0xC4CEB; 2888 return result ^ result >>> 15; 2889 } 2890 2891 public static int hash(final int[] data) { 2892 if (data == null) 2893 return 0; 2894 int result = 0x1A976FDF, z = 0x60642E25; 2895 final int len = data.length; 2896 for (int i = 0; i < len; i++) { 2897 result ^= (z += (data[i] ^ 0xC3564E95) * 0x9E375); 2898 z ^= (result = (result << 20 | result >>> 12)); 2899 } 2900 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 2901 result = (result ^ result >>> 15) * 0xFF51D; 2902 result = (result ^ result >>> 15) * 0xC4CEB; 2903 return result ^ result >>> 15; 2904 } 2905 2906 public static int hash(final long[] data) { 2907 if (data == null) 2908 return 0; 2909 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2910 final int len = data.length; 2911 for (int i = 0; i < len; i++) { 2912 result ^= (z += (data[i] ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2913 result = (result << 54 | result >>> 10); 2914 } 2915 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2916 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2917 return (int)((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2918 } 2919 2920 public static int hash(final char[] data) { 2921 if (data == null) 2922 return 0; 2923 int result = 0x1A976FDF, z = 0x60642E25; 2924 final int len = data.length; 2925 for (int i = 0; i < len; i++) { 2926 result ^= (z += (data[i] ^ 0xC3564E95) * 0x9E375); 2927 z ^= (result = (result << 20 | result >>> 12)); 2928 } 2929 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 2930 result = (result ^ result >>> 15) * 0xFF51D; 2931 result = (result ^ result >>> 15) * 0xC4CEB; 2932 return result ^ result >>> 15; 2933 } 2934 2935 public static int hash(final float[] data) { 2936 if (data == null) 2937 return 0; 2938 int result = 0x1A976FDF, z = 0x60642E25; 2939 final int len = data.length; 2940 for (int i = 0; i < len; i++) { 2941 result ^= (z += (floatToIntBits(data[i]) ^ 0xC3564E95) * 0x9E375); 2942 z ^= (result = (result << 20 | result >>> 12)); 2943 } 2944 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 2945 result = (result ^ result >>> 15) * 0xFF51D; 2946 result = (result ^ result >>> 15) * 0xC4CEB; 2947 return result ^ result >>> 15; 2948 2949 } 2950 2951 public static int hash(final double[] data) { 2952 if (data == null) 2953 return 0; 2954 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 2955 final int len = data.length; 2956 for (int i = 0; i < len; i++) { 2957 result ^= (z += (NumberTools.doubleToLongBits(data[i]) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 2958 result = (result << 54 | result >>> 10); 2959 } 2960 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 2961 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 2962 return (int)((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 2963 } 2964 2965 /** 2966 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 2967 * 2968 * @param data the char array to hash 2969 * @param start the start of the section to hash (inclusive) 2970 * @param end the end of the section to hash (exclusive) 2971 * @return a 32-bit hash code for the requested section of data 2972 */ 2973 public static int hash(final char[] data, final int start, final int end) { 2974 if (data == null || start >= end) 2975 return 0; 2976 int result = 0x1A976FDF, z = 0x60642E25; 2977 final int len = Math.min(end, data.length); 2978 for (int i = start; i < len; i++) { 2979 result ^= (z += (data[i] ^ 0xC3564E95) * 0x9E375); 2980 z ^= (result = (result << 20 | result >>> 12)); 2981 } 2982 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 2983 result = (result ^ result >>> 15) * 0xFF51D; 2984 result = (result ^ result >>> 15) * 0xC4CEB; 2985 return result ^ result >>> 15; 2986 } 2987 2988 /** 2989 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 2990 * 2991 * @param data the String or other CharSequence to hash 2992 * @param start the start of the section to hash (inclusive) 2993 * @param end the end of the section to hash (exclusive) 2994 * @return a 32-bit hash code for the requested section of data 2995 */ 2996 public static int hash(final CharSequence data, final int start, final int end) { 2997 if (data == null || start >= end) 2998 return 0; 2999 int result = 0x1A976FDF, z = 0x60642E25; 3000 final int len = Math.min(end, data.length()); 3001 for (int i = start; i < len; i++) { 3002 result ^= (z += (data.charAt(i) ^ 0xC3564E95) * 0x9E375); 3003 z ^= (result = (result << 20 | result >>> 12)); 3004 } 3005 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3006 result = (result ^ result >>> 15) * 0xFF51D; 3007 result = (result ^ result >>> 15) * 0xC4CEB; 3008 return result ^ result >>> 15; 3009 } 3010 3011 /** 3012 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 3013 * moving between chars in increments of step (which is always greater than 0). 3014 * 3015 * @param data the char array to hash 3016 * @param start the start of the section to hash (inclusive) 3017 * @param end the end of the section to hash (exclusive) 3018 * @param step how many elements to advance after using one element from data; must be greater than 0 3019 * @return a 32-bit hash code for the requested section of data 3020 */ 3021 public static int hash(final char[] data, final int start, final int end, final int step) { 3022 if (data == null || start >= end || step <= 0) 3023 return 0; 3024 int result = 0x1A976FDF, z = 0x60642E25; 3025 final int len = Math.min(end, data.length); 3026 for (int i = start; i < len; i += step) { 3027 result ^= (z += (data[i] ^ 0xC3564E95) * 0x9E375); 3028 z ^= (result = (result << 20 | result >>> 12)); 3029 } 3030 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3031 result = (result ^ result >>> 15) * 0xFF51D; 3032 result = (result ^ result >>> 15) * 0xC4CEB; 3033 return result ^ result >>> 15; 3034 } 3035 3036 /** 3037 * Hashes only a subsection of the given data, starting at start (inclusive), ending before end (exclusive), and 3038 * moving between chars in increments of step (which is always greater than 0). 3039 * 3040 * @param data the String or other CharSequence to hash 3041 * @param start the start of the section to hash (inclusive) 3042 * @param end the end of the section to hash (exclusive) 3043 * @param step how many elements to advance after using one element from data; must be greater than 0 3044 * @return a 32-bit hash code for the requested section of data 3045 */ 3046 public static int hash(final CharSequence data, final int start, final int end, final int step) { 3047 if (data == null || start >= end || step <= 0) 3048 return 0; 3049 int result = 0x1A976FDF, z = 0x60642E25; 3050 final int len = Math.min(end, data.length()); 3051 for (int i = start; i < len; i += step) { 3052 result ^= (z += (data.charAt(i) ^ 0xC3564E95) * 0x9E375); 3053 z ^= (result = (result << 20 | result >>> 12)); 3054 } 3055 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3056 result = (result ^ result >>> 15) * 0xFF51D; 3057 result = (result ^ result >>> 15) * 0xC4CEB; 3058 return result ^ result >>> 15; 3059 } 3060 3061 public static int hash(final char[][] data) { 3062 if (data == null) 3063 return 0; 3064 int result = 0x1A976FDF, z = 0x60642E25; 3065 final int len = data.length; 3066 for (int i = 0; i < len; i++) { 3067 result ^= (z += (hash(data[i]) ^ 0xC3564E95) * 0x9E375); 3068 z ^= (result = (result << 20 | result >>> 12)); 3069 } 3070 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3071 result = (result ^ result >>> 15) * 0xFF51D; 3072 result = (result ^ result >>> 15) * 0xC4CEB; 3073 return result ^ result >>> 15; 3074 } 3075 3076 public static int hash(final int[][] data) { 3077 if (data == null) 3078 return 0; 3079 int result = 0x1A976FDF, z = 0x60642E25; 3080 final int len = data.length; 3081 for (int i = 0; i < len; i++) { 3082 result ^= (z += (hash(data[i]) ^ 0xC3564E95) * 0x9E375); 3083 z ^= (result = (result << 20 | result >>> 12)); 3084 } 3085 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3086 result = (result ^ result >>> 15) * 0xFF51D; 3087 result = (result ^ result >>> 15) * 0xC4CEB; 3088 return result ^ result >>> 15; 3089 } 3090 3091 public static int hash(final long[][] data) { 3092 if (data == null) 3093 return 0; 3094 long result = 0x1A976FDF6BF60B8EL, z = 0x60642E2A34326F15L; 3095 final int len = data.length; 3096 for (int i = 0; i < len; i++) { 3097 result ^= (z += (hash64(data[i]) ^ 0xC6BC279692B5CC85L) * 0x6C8E9CF570932BABL); 3098 result = (result << 54 | result >>> 10); 3099 } 3100 result += (z ^ z >>> 26) * 0x632BE59BD9B4E019L; 3101 result = (result ^ result >>> 33) * 0xFF51AFD7ED558CCDL; 3102 return (int)((result ^ result >>> 33) * 0xC4CEB9FE1A85EC53L); 3103 } 3104 3105 public static int hash(final CharSequence[] data) { 3106 if (data == null) 3107 return 0; 3108 int result = 0x1A976FDF, z = 0x60642E25; 3109 final int len = data.length; 3110 for (int i = 0; i < len; i++) { 3111 result ^= (z += (hash(data[i]) ^ 0xC3564E95) * 0x9E375); 3112 z ^= (result = (result << 20 | result >>> 12)); 3113 } 3114 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3115 result = (result ^ result >>> 15) * 0xFF51D; 3116 result = (result ^ result >>> 15) * 0xC4CEB; 3117 return result ^ result >>> 15; 3118 } 3119 3120 public static int hash(final CharSequence[]... data) { 3121 if (data == null) 3122 return 0; 3123 int result = 0x1A976FDF, z = 0x60642E25; 3124 final int len = data.length; 3125 for (int i = 0; i < len; i++) { 3126 result ^= (z += (hash(data[i]) ^ 0xC3564E95) * 0x9E375); 3127 z ^= (result = (result << 20 | result >>> 12)); 3128 } 3129 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3130 result = (result ^ result >>> 15) * 0xFF51D; 3131 result = (result ^ result >>> 15) * 0xC4CEB; 3132 return result ^ result >>> 15; 3133 } 3134 3135 public static int hash(final Iterable<? extends CharSequence> data) { 3136 if (data == null) 3137 return 0; 3138 int result = 0x1A976FDF, z = 0x60642E25; 3139 for (CharSequence datum : data) { 3140 result ^= (z += (hash(datum) ^ 0xC3564E95) * 0x9E375); 3141 z ^= (result = (result << 20 | result >>> 12)); 3142 } 3143 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3144 result = (result ^ result >>> 15) * 0xFF51D; 3145 result = (result ^ result >>> 15) * 0xC4CEB; 3146 return result ^ result >>> 15; 3147 3148 } 3149 3150 public static int hash(final List<? extends CharSequence> data) { 3151 if (data == null) 3152 return 0; 3153 int result = 0x1A976FDF, z = 0x60642E25; 3154 final int len = data.size(); 3155 for (int i = 0; i < len; i++) { 3156 result ^= (z += (hash(data.get(i)) ^ 0xC3564E95) * 0x9E375); 3157 z ^= (result = (result << 20 | result >>> 12)); 3158 } 3159 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3160 result = (result ^ result >>> 15) * 0xFF51D; 3161 result = (result ^ result >>> 15) * 0xC4CEB; 3162 return result ^ result >>> 15; 3163 3164 } 3165 3166 public static int hash(final Object[] data) { 3167 if (data == null) 3168 return 0; 3169 int result = 0x1A976FDF, z = 0x60642E25; 3170 final int len = data.length; 3171 Object o; 3172 for (int i = 0; i < len; i++) { 3173 result ^= (z += (((o = data[i]) == null ? -1 : o.hashCode()) ^ 0xC3564E95) * 0x9E375); 3174 z ^= (result = (result << 20 | result >>> 12)); 3175 } 3176 result += (z ^ z >>> 15 ^ 0xAE932BD5) * 0x632B9; 3177 result = (result ^ result >>> 15) * 0xFF51D; 3178 result = (result ^ result >>> 15) * 0xC4CEB; 3179 return result ^ result >>> 15; 3180 } 3181 3182 public static int hash(final Object data) { 3183 if (data == null) 3184 return 0; 3185 final int h = data.hashCode() * 0x9E375; 3186 return h ^ (h >>> 16); 3187 } 3188 } 3189 3190 3191 /** 3192 * A fairly fast hashing algorithm in general, Water performs especially well on large arrays, and passes SMHasher's 3193 * newest and most stringent version of tests. The int-hashing {@link #hash(int[])} method is almost twice as fast 3194 * as {@link Hive#hash(int[])} and faster than {@link Arrays#hashCode(int[])}; on longer arrays 3195 * {@link Curlup#hash(int[])} is faster. Based on <a href="https://github.com/wangyi-fudan/wyhash">wyhash</a>, 3196 * specifically <a href="https://github.com/tommyettinger/waterhash">the waterhash variant</a>. This version passes 3197 * SMHasher for both the 32-bit output hash() methods and the 64-bit output hash64() methods (which use the slightly 3198 * tweaked wheathash variant in the waterhash Git repo, or woothash for hashing long arrays). While an earlier 3199 * version passed rurban/smhasher, it failed demerphq/smhasher (Yves' more stringent fork), so some minor tweaks 3200 * allowed the latest code to pass Yves' test. Uses 64-bit math, so it won't be as fast on GWT. Currently, the 3201 * methods that hash types other than int arrays aren't as fast as the int array hash, but they are usually faster 3202 * than the former default Hive implementation, and unlike Hive, these pass SMHasher. If you want to have a seed the 3203 * hash, so hashing the same data with a different seed produces different output, you can use {@link Yolk} or 3204 * {@link Curlup}, preferring Curlup unless all of your data is in small arrays (under 20 length, give or take). 3205 * <br> 3206 * These hash functions are so fast because they operate in bulk on 4 items at a time, such as 4 ints (which is the 3207 * optimal case), 4 bytes, or 4 longs (which uses a different algorithm). This bulk operation usually entails 3 3208 * multiplications and some other, cheaper operations per 4 items hashed. For long arrays, it requires many more 3209 * multiplications, but modern CPUs can pipeline the operations on unrelated longs to run in parallel on one core. 3210 * If any items are left over after the bulk segment, Water uses the least effort possible to hash the remaining 1, 3211 * 2, or 3 items left. Most of these operations use the method {@link #mum(long, long)}, which helps take two inputs 3212 * and multiply them once, getting a more-random result after another small step. The long array code uses 3213 * {@link #wow(long, long)} (similar to mum upside-down), which mixes up its arguments with each other before 3214 * multplying. It finishes with either code similar to mum() for 32-bit output hash() methods, or a somewhat more 3215 * rigorous method for 64-bit output hash64() methods (still similar to mum). 3216 */ 3217 public static final class Water { 3218 /** 3219 * Big constant 0. 3220 */ 3221 public static final long b0 = 0xA0761D6478BD642FL; 3222 /** 3223 * Big constant 1. 3224 */ 3225 public static final long b1 = 0xE7037ED1A0B428DBL; 3226 /** 3227 * Big constant 2. 3228 */ 3229 public static final long b2 = 0x8EBC6AF09C88C6E3L; 3230 /** 3231 * Big constant 3. 3232 */ 3233 public static final long b3 = 0x589965CC75374CC3L; 3234 /** 3235 * Big constant 4. 3236 */ 3237 public static final long b4 = 0x1D8E4E27C47D124FL; 3238 /** 3239 * Big constant 5. 3240 */ 3241 public static final long b5 = 0xEB44ACCAB455D165L; 3242 3243 /** 3244 * Takes two arguments that are technically longs, and should be very different, and uses them to get a result 3245 * that is technically a long and mixes the bits of the inputs. The arguments and result are only technically 3246 * longs because their lower 32 bits matter much more than their upper 32, and giving just any long won't work. 3247 * <br> 3248 * This is very similar to wyhash's mum function, but doesn't use 128-bit math because it expects that its 3249 * arguments are only relevant in their lower 32 bits (allowing their product to fit in 64 bits). 3250 * @param a a long that should probably only hold an int's worth of data 3251 * @param b a long that should probably only hold an int's worth of data 3252 * @return a sort-of randomized output dependent on both inputs 3253 */ 3254 public static long mum(final long a, final long b) { 3255 final long n = a * b; 3256 return n - (n >>> 32); 3257 } 3258 3259 /** 3260 * A slower but higher-quality variant on {@link #mum(long, long)} that can take two arbitrary longs (with any 3261 * of their 64 bits containing relevant data) instead of mum's 32-bit sections of its inputs, and outputs a 3262 * 64-bit result that can have any of its bits used. 3263 * <br> 3264 * This was changed so it distributes bits from both inputs a little better on July 6, 2019. 3265 * @param a any long 3266 * @param b any long 3267 * @return a sort-of randomized output dependent on both inputs 3268 */ 3269 public static long wow(final long a, final long b) { 3270 final long n = (a ^ (b << 39 | b >>> 25)) * (b ^ (a << 39 | a >>> 25)); 3271 return n ^ (n >>> 32); 3272 } 3273 3274 public static long hash64(final boolean[] data) { 3275 if (data == null) return 0; 3276 long seed = 9069147967908697017L;//seed = b1 ^ b1 >>> 29 ^ b1 >>> 43 ^ b1 << 7 ^ b1 << 53; 3277 final int len = data.length; 3278 for (int i = 3; i < len; i+=4) { 3279 seed = mum( 3280 mum((data[i-3] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b1, (data[i-2] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b2) + seed, 3281 mum((data[i-1] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b3, (data[i] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b4)); 3282 } 3283 switch (len & 3) { 3284 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3285 case 1: seed = mum(seed ^ (data[len-1] ? 0x9E37L : 0x7F4AL), b3 ^ (data[len-1] ? 0x79B9L : 0x7C15L)); break; 3286 case 2: seed = mum(seed ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L), b0 ^ (data[len-1] ? 0x9E3779B9L : 0x7F4A7C15L)); break; 3287 case 3: seed = mum(seed ^ (data[len-3] ? 0x9E3779B9L : 0x7F4A7C15L), b2 ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L)) ^ mum(seed ^ (data[len-1] ? 0x9E3779B9 : 0x7F4A7C15), b4); break; 3288 } 3289 seed = (seed ^ seed << 16) * (len ^ b0); 3290 return seed - (seed >>> 31) + (seed << 33); 3291 } 3292 public static long hash64(final byte[] data) { 3293 if (data == null) return 0; 3294 long seed = 9069147967908697017L; 3295 final int len = data.length; 3296 for (int i = 3; i < len; i+=4) { 3297 seed = mum( 3298 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3299 mum(data[i-1] ^ b3, data[i] ^ b4)); 3300 } 3301 switch (len & 3) { 3302 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3303 case 1: seed = mum(seed ^ b2, b1 ^ data[len-1]); break; 3304 case 2: seed = mum(seed ^ b3, data[len-2] ^ data[len-1] << 8 ^ b4); break; 3305 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 8, b2 ^ data[len-1]); break; 3306 } 3307 seed = (seed ^ seed << 16) * (len ^ b0); 3308 return seed - (seed >>> 31) + (seed << 33); 3309 } 3310 3311 public static long hash64(final short[] data) { 3312 if (data == null) return 0; 3313 long seed = 9069147967908697017L; 3314 final int len = data.length; 3315 for (int i = 3; i < len; i+=4) { 3316 seed = mum( 3317 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3318 mum(data[i-1] ^ b3, data[i] ^ b4)); 3319 } 3320 switch (len & 3) { 3321 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3322 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 3323 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 3324 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 3325 } 3326 seed = (seed ^ seed << 16) * (len ^ b0); 3327 return seed - (seed >>> 31) + (seed << 33); 3328 } 3329 3330 public static long hash64(final char[] data) { 3331 if (data == null) return 0; 3332 long seed = 9069147967908697017L; 3333 final int len = data.length; 3334 for (int i = 3; i < len; i+=4) { 3335 seed = mum( 3336 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3337 mum(data[i-1] ^ b3, data[i] ^ b4)); 3338 } 3339 switch (len & 3) { 3340 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3341 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 3342 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 3343 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 3344 } 3345 seed = (seed ^ seed << 16) * (len ^ b0); 3346 return seed - (seed >>> 31) + (seed << 33); 3347 } 3348 3349 public static long hash64(final CharSequence data) { 3350 if (data == null) return 0; 3351 long seed = 9069147967908697017L; 3352 final int len = data.length(); 3353 for (int i = 3; i < len; i+=4) { 3354 seed = mum( 3355 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 3356 mum(data.charAt(i-1) ^ b3, data.charAt(i ) ^ b4)); 3357 } 3358 switch (len & 3) { 3359 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3360 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 3361 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 3362 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 3363 } 3364 seed = (seed ^ seed << 16) * (len ^ b0); 3365 return seed - (seed >>> 31) + (seed << 33); 3366 } 3367 3368 public static long hash64(final int[] data) { 3369 if (data == null) return 0; 3370 long seed = 9069147967908697017L; 3371 final int len = data.length; 3372 for (int i = 3; i < len; i+=4) { 3373 seed = mum( 3374 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3375 mum(data[i-1] ^ b3, data[i] ^ b4)); 3376 } 3377 switch (len & 3) { 3378 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3379 case 1: seed = mum(seed ^ (data[len-1] >>> 16), b3 ^ (data[len-1] & 0xFFFFL)); break; 3380 case 2: seed = mum(seed ^ data[len-2], b0 ^ data[len-1]); break; 3381 case 3: seed = mum(seed ^ data[len-3], b2 ^ data[len-2]) ^ mum(seed ^ data[len-1], b4); break; 3382 } 3383 seed = (seed ^ seed << 16) * (len ^ b0); 3384 return seed - (seed >>> 31) + (seed << 33); 3385 } 3386 3387 public static long hash64(final int[] data, final int length) { 3388 if (data == null) return 0; 3389 long seed = 9069147967908697017L; 3390 for (int i = 3; i < length; i+=4) { 3391 seed = mum( 3392 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3393 mum(data[i-1] ^ b3, data[i] ^ b4)); 3394 } 3395 switch (length & 3) { 3396 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3397 case 1: seed = mum(seed ^ (data[length-1] >>> 16), b3 ^ (data[length-1] & 0xFFFFL)); break; 3398 case 2: seed = mum(seed ^ data[length-2], b0 ^ data[length-1]); break; 3399 case 3: seed = mum(seed ^ data[length-3], b2 ^ data[length-2]) ^ mum(seed ^ data[length-1], b4); break; 3400 } 3401 seed = (seed ^ seed << 16) * (length ^ b0); 3402 return seed - (seed >>> 31) + (seed << 33); 3403 } 3404 3405 public static long hash64(final long[] data) { 3406 if (data == null) return 0; 3407// long seed = b0 ^ b0 >>> 23 ^ b0 >>> 48 ^ b0 << 7 ^ b0 << 53, 3408// a = seed + b4, b = seed + b3, 3409// c = seed + b2, d = seed + b1; 3410 long seed = 0x1E98AE18CA351B28L, 3411 a = 0x3C26FC408EB22D77L, b = 0x773213E53F6C67EBL, 3412 c = 0xAD55190966BDE20BL, d = 0x59C2CEA6AE94403L; 3413 final int len = data.length; 3414 for (int i = 3; i < len; i+=4) { 3415 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 3416 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 3417 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 3418 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 3419 seed += a + b + c + d; 3420 } 3421 seed += b5; 3422 switch (len & 3) { 3423 case 1: seed = wow(seed, b1 ^ data[len-1]); break; 3424 case 2: seed = wow(seed + data[len-2], b2 + data[len-1]); break; 3425 case 3: seed = wow(seed + data[len-3], b2 + data[len-2]) ^ wow(seed + data[len-1], seed ^ b3); break; 3426 } 3427 seed = (seed ^ seed << 16) * (len ^ b0 ^ seed >>> 32); 3428 return seed - (seed >>> 31) + (seed << 33); 3429 } 3430 public static long hash64(final float[] data) { 3431 if (data == null) return 0; 3432 long seed = 9069147967908697017L; 3433 final int len = data.length; 3434 for (int i = 3; i < len; i+=4) { 3435 seed = mum( 3436 mum(floatToIntBits(data[i-3]) ^ b1, floatToIntBits(data[i-2]) ^ b2) + seed, 3437 mum(floatToIntBits(data[i-1]) ^ b3, floatToIntBits(data[i]) ^ b4)); 3438 } 3439 switch (len & 3) { 3440 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3441 case 1: seed = mum(seed ^ (floatToIntBits(data[len-1]) >>> 16), b3 ^ (floatToIntBits(data[len-1]) & 0xFFFFL)); break; 3442 case 2: seed = mum(seed ^ floatToIntBits(data[len-2]), b0 ^ floatToIntBits(data[len-1])); break; 3443 case 3: seed = mum(seed ^ floatToIntBits(data[len-3]), b2 ^ floatToIntBits(data[len-2])) ^ mum(seed ^ floatToIntBits(data[len-1]), b4); break; 3444 } 3445 seed = (seed ^ seed << 16) * (len ^ b0); 3446 return seed - (seed >>> 31) + (seed << 33); 3447 } 3448 public static long hash64(final double[] data) { 3449 if (data == null) return 0; 3450 long seed = 9069147967908697017L; 3451 final int len = data.length; 3452 for (int i = 3; i < len; i+=4) { 3453 seed = mum( 3454 mum(doubleToMixedIntBits(data[i-3]) ^ b1, doubleToMixedIntBits(data[i-2]) ^ b2) + seed, 3455 mum(doubleToMixedIntBits(data[i-1]) ^ b3, doubleToMixedIntBits(data[i]) ^ b4)); 3456 } 3457 switch (len & 3) { 3458 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3459 case 1: seed = mum(seed ^ (doubleToMixedIntBits(data[len-1]) >>> 16), b3 ^ (doubleToMixedIntBits(data[len-1]) & 0xFFFFL)); break; 3460 case 2: seed = mum(seed ^ doubleToMixedIntBits(data[len-2]), b0 ^ doubleToMixedIntBits(data[len-1])); break; 3461 case 3: seed = mum(seed ^ doubleToMixedIntBits(data[len-3]), b2 ^ doubleToMixedIntBits(data[len-2])) ^ mum(seed ^ doubleToMixedIntBits(data[len-1]), b4); break; 3462 } 3463 seed = (seed ^ seed << 16) * (len ^ b0); 3464 return seed - (seed >>> 31) + (seed << 33); 3465 } 3466 3467 /** 3468 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 3469 * 3470 * @param data the char array to hash 3471 * @param start the start of the section to hash (inclusive) 3472 * @param end the end of the section to hash (exclusive) 3473 * @return a 64-bit hash code for the requested section of data 3474 */ 3475 public static long hash64(final char[] data, final int start, final int end) { 3476 if (data == null || start >= end) 3477 return 0; 3478 long seed = 9069147967908697017L; 3479 final int len = Math.min(end, data.length); 3480 for (int i = start + 3; i < len; i+=4) { 3481 seed = mum( 3482 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3483 mum(data[i-1] ^ b3, data[i] ^ b4)); 3484 } 3485 switch (len - start & 3) { 3486 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3487 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 3488 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 3489 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 3490 } 3491 return mum(seed ^ seed << 16, len - start ^ b0); 3492 } 3493 3494 /** 3495 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 3496 * 3497 * @param data the String or other CharSequence to hash 3498 * @param start the start of the section to hash (inclusive) 3499 * @param end the end of the section to hash (exclusive) 3500 * @return a 64-bit hash code for the requested section of data 3501 */ 3502 public static long hash64(final CharSequence data, final int start, final int end) { 3503 if (data == null || start >= end) 3504 return 0; 3505 long seed = 9069147967908697017L; 3506 final int len = Math.min(end, data.length()); 3507 for (int i = start + 3; i < len; i+=4) { 3508 seed = mum( 3509 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 3510 mum(data.charAt(i-1) ^ b3, data.charAt(i) ^ b4)); 3511 } 3512 switch (len - start & 3) { 3513 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3514 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 3515 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 3516 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 3517 } 3518 return mum(seed ^ seed << 16, len - start ^ b0); 3519 } 3520 3521 3522 public static long hash64(final char[][] data) { 3523 if (data == null) return 0; 3524 long seed = 9069147967908697017L; 3525 final int len = data.length; 3526 for (int i = 3; i < len; i+=4) { 3527 seed = mum( 3528 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3529 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3530 } 3531 int t; 3532 switch (len & 3) { 3533 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3534 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3535 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3536 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3537 } 3538 seed = (seed ^ seed << 16) * (len ^ b0); 3539 return seed - (seed >>> 31) + (seed << 33); 3540 } 3541 3542 public static long hash64(final int[][] data) { 3543 if (data == null) return 0; 3544 long seed = 9069147967908697017L; 3545 final int len = data.length; 3546 for (int i = 3; i < len; i+=4) { 3547 seed = mum( 3548 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3549 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3550 } 3551 int t; 3552 switch (len & 3) { 3553 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3554 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3555 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3556 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3557 } 3558 seed = (seed ^ seed << 16) * (len ^ b0); 3559 return seed - (seed >>> 31) + (seed << 33); 3560 } 3561 3562 public static long hash64(final long[][] data) { 3563 if (data == null) return 0; 3564 long seed = 9069147967908697017L; 3565 final int len = data.length; 3566 for (int i = 3; i < len; i+=4) { 3567 seed = mum( 3568 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3569 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3570 } 3571 int t; 3572 switch (len & 3) { 3573 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3574 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3575 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3576 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3577 } 3578 seed = (seed ^ seed << 16) * (len ^ b0); 3579 return seed - (seed >>> 31) + (seed << 33); 3580 } 3581 3582 public static long hash64(final CharSequence[] data) { 3583 if (data == null) return 0; 3584 long seed = 9069147967908697017L; 3585 final int len = data.length; 3586 for (int i = 3; i < len; i+=4) { 3587 seed = mum( 3588 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3589 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3590 } 3591 int t; 3592 switch (len & 3) { 3593 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3594 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3595 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3596 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3597 } 3598 seed = (seed ^ seed << 16) * (len ^ b0); 3599 return seed - (seed >>> 31) + (seed << 33); 3600 } 3601 3602 public static long hash64(final CharSequence[]... data) { 3603 if (data == null) return 0; 3604 long seed = 9069147967908697017L; 3605 final int len = data.length; 3606 for (int i = 3; i < len; i+=4) { 3607 seed = mum( 3608 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3609 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3610 } 3611 int t; 3612 switch (len & 3) { 3613 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3614 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3615 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3616 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3617 } 3618 seed = (seed ^ seed << 16) * (len ^ b0); 3619 return seed - (seed >>> 31) + (seed << 33); 3620 } 3621 3622 public static long hash64(final Iterable<? extends CharSequence> data) { 3623 if (data == null) return 0; 3624 long seed = 9069147967908697017L; 3625 final Iterator<? extends CharSequence> it = data.iterator(); 3626 int len = 0; 3627 while (it.hasNext()) 3628 { 3629 ++len; 3630 seed = mum( 3631 mum(hash(it.next()) ^ b1, (it.hasNext() ? hash(it.next()) ^ b2 ^ ++len : b2)) + seed, 3632 mum((it.hasNext() ? hash(it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(it.next()) ^ b4 ^ ++len : b4))); 3633 } 3634 seed = (seed ^ seed << 16) * (len ^ b0); 3635 return seed - (seed >>> 31) + (seed << 33); 3636 } 3637 3638 public static long hash64(final List<? extends CharSequence> data) { 3639 if (data == null) return 0; 3640 long seed = 9069147967908697017L; 3641 final int len = data.size(); 3642 for (int i = 3; i < len; i+=4) { 3643 seed = mum( 3644 mum(hash(data.get(i-3)) ^ b1, hash(data.get(i-2)) ^ b2) + seed, 3645 mum(hash(data.get(i-1)) ^ b3, hash(data.get(i )) ^ b4)); 3646 } 3647 int t; 3648 switch (len & 3) { 3649 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3650 case 1: seed = mum(seed ^((t = hash(data.get(len-1))) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3651 case 2: seed = mum(seed ^ hash(data.get(len-2)), b0 ^ hash(data.get(len-1))); break; 3652 case 3: seed = mum(seed ^ hash(data.get(len-3)), b2 ^ hash(data.get(len-2))) ^ mum(seed ^ hash(data.get(len-1)), b4); break; 3653 } 3654 seed = (seed ^ seed << 16) * (len ^ b0); 3655 return seed - (seed >>> 31) + (seed << 33); 3656 3657 } 3658 3659 public static long hash64(final Object[] data) { 3660 if (data == null) return 0; 3661 long seed = 9069147967908697017L; 3662 final int len = data.length; 3663 for (int i = 3; i < len; i+=4) { 3664 seed = mum( 3665 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3666 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3667 } 3668 int t; 3669 switch (len & 3) { 3670 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3671 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3672 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3673 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3674 } 3675 seed = (seed ^ seed << 16) * (len ^ b0); 3676 return seed - (seed >>> 31) + (seed << 33); 3677 } 3678 3679 public static long hash64(final Object data) { 3680 if (data == null) 3681 return 0; 3682 final long h = data.hashCode() * 0x9E3779B97F4A7C15L; 3683 return h - (h >>> 31) + (h << 33); 3684 } 3685 3686 3687 public static int hash(final boolean[] data) { 3688 if (data == null) return 0; 3689 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3690 final int len = data.length; 3691 for (int i = 3; i < len; i+=4) { 3692 seed = mum( 3693 mum((data[i-3] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b1, (data[i-2] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b2) + seed, 3694 mum((data[i-1] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b3, (data[i] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b4)); 3695 } 3696 switch (len & 3) { 3697 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3698 case 1: seed = mum(seed ^ (data[len-1] ? 0x9E37L : 0x7F4AL), b3 ^ (data[len-1] ? 0x79B9L : 0x7C15L)); break; 3699 case 2: seed = mum(seed ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L), b0 ^ (data[len-1] ? 0x9E3779B9L : 0x7F4A7C15L)); break; 3700 case 3: seed = mum(seed ^ (data[len-3] ? 0x9E3779B9L : 0x7F4A7C15L), b2 ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L)) ^ mum(seed ^ (data[len-1] ? 0x9E3779B9 : 0x7F4A7C15), b4); break; 3701 } 3702 return (int) mum(seed ^ seed << 16, len ^ b0); 3703 } 3704 public static int hash(final byte[] data) { 3705 if (data == null) return 0; 3706 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3707 final int len = data.length; 3708 for (int i = 3; i < len; i+=4) { 3709 seed = mum( 3710 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3711 mum(data[i-1] ^ b3, data[i] ^ b4)); 3712 } 3713 switch (len & 3) { 3714 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3715 case 1: seed = mum(seed ^ b2, b1 ^ data[len-1]); break; 3716 case 2: seed = mum(seed ^ b3, data[len-2] ^ data[len-1] << 8 ^ b4); break; 3717 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 8, b2 ^ data[len-1]); break; 3718 } 3719 return (int) mum(seed ^ seed << 16, len ^ b0); 3720 } 3721 3722 public static int hash(final short[] data) { 3723 if (data == null) return 0; 3724 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3725 final int len = data.length; 3726 for (int i = 3; i < len; i+=4) { 3727 seed = mum( 3728 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3729 mum(data[i-1] ^ b3, data[i] ^ b4)); 3730 } 3731 switch (len & 3) { 3732 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3733 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 3734 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 3735 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 3736 } 3737 return (int) mum(seed ^ seed << 16, len ^ b0); 3738 } 3739 3740 public static int hash(final char[] data) { 3741 if (data == null) return 0; 3742 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3743 final int len = data.length; 3744 for (int i = 3; i < len; i+=4) { 3745 seed = mum( 3746 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3747 mum(data[i-1] ^ b3, data[i] ^ b4)); 3748 } 3749 switch (len & 3) { 3750 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3751 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 3752 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 3753 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 3754 } 3755 return (int) mum(seed ^ seed << 16, len ^ b0); 3756 } 3757 3758 public static int hash(final CharSequence data) { 3759 if (data == null) return 0; 3760 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3761 final int len = data.length(); 3762 for (int i = 3; i < len; i+=4) { 3763 seed = mum( 3764 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 3765 mum(data.charAt(i-1) ^ b3, data.charAt(i ) ^ b4)); 3766 } 3767 switch (len & 3) { 3768 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3769 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 3770 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 3771 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 3772 } 3773 return (int) mum(seed ^ seed << 16, len ^ b0); 3774 } 3775 public static int hash(final int[] data) { 3776 if (data == null) return 0; 3777 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3778 final int len = data.length; 3779 for (int i = 3; i < len; i+=4) { 3780 seed = mum( 3781 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3782 mum(data[i-1] ^ b3, data[i] ^ b4)); 3783 } 3784 switch (len & 3) { 3785 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3786 case 1: seed = mum(seed ^ (data[len-1] >>> 16), b3 ^ (data[len-1] & 0xFFFFL)); break; 3787 case 2: seed = mum(seed ^ data[len-2], b0 ^ data[len-1]); break; 3788 case 3: seed = mum(seed ^ data[len-3], b2 ^ data[len-2]) ^ mum(seed ^ data[len-1], b4); break; 3789 } 3790 return (int) mum(seed ^ seed << 16, len ^ b0); 3791 } 3792 public static int hash(final int[] data, final int length) { 3793 if (data == null) return 0; 3794 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3795 for (int i = 3; i < length; i+=4) { 3796 seed = mum( 3797 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3798 mum(data[i-1] ^ b3, data[i] ^ b4)); 3799 } 3800 switch (length & 3) { 3801 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3802 case 1: seed = mum(seed ^ (data[length-1] >>> 16), b3 ^ (data[length-1] & 0xFFFFL)); break; 3803 case 2: seed = mum(seed ^ data[length-2], b0 ^ data[length-1]); break; 3804 case 3: seed = mum(seed ^ data[length-3], b2 ^ data[length-2]) ^ mum(seed ^ data[length-1], b4); break; 3805 } 3806 return (int) mum(seed ^ seed << 16, length ^ b0); 3807 } 3808 3809 public static int hash(final long[] data) { 3810 if (data == null) return 0; 3811 //long seed = 0x1E98AE18CA351B28L,// seed = b0 ^ b0 >>> 23 ^ b0 >>> 48 ^ b0 << 7 ^ b0 << 53, 3812// a = seed ^ b4, b = (seed << 17 | seed >>> 47) ^ b3, 3813// c = (seed << 31 | seed >>> 33) ^ b2, d = (seed << 47 | seed >>> 17) ^ b1; 3814 //a = 0x316E03F0E480967L, b = 0x4A8F1A6436771F2L, 3815 // c = 0xEBA6E76493C491EFL, d = 0x6A97719DF7B84DC1L; 3816 long seed = 0x1E98AE18CA351B28L, a = 0x3C26FC408EB22D77L, b = 0x773213E53F6C67EBL, c = 0xAD55190966BDE20BL, d = 0x59C2CEA6AE94403L; 3817 final int len = data.length; 3818 for (int i = 3; i < len; i+=4) { 3819 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 3820 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 3821 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 3822 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 3823 seed += a + b + c + d; 3824 } 3825 seed += b5; 3826 switch (len & 3) { 3827 case 1: seed = wow(seed, b1 ^ data[len-1]); break; 3828 case 2: seed = wow(seed + data[len-2], b2 + data[len-1]); break; 3829 case 3: seed = wow(seed + data[len-3], b2 + data[len-2]) ^ wow(seed + data[len-1], seed ^ b3); break; 3830 } 3831 seed = (seed ^ seed << 16) * (len ^ b0 ^ seed >>> 32); 3832 return (int)(seed - (seed >>> 32)); 3833 } 3834 3835 public static int hash(final float[] data) { 3836 if (data == null) return 0; 3837 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3838 final int len = data.length; 3839 for (int i = 3; i < len; i+=4) { 3840 seed = mum( 3841 mum(floatToIntBits(data[i-3]) ^ b1, floatToIntBits(data[i-2]) ^ b2) + seed, 3842 mum(floatToIntBits(data[i-1]) ^ b3, floatToIntBits(data[i]) ^ b4)); 3843 } 3844 switch (len & 3) { 3845 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3846 case 1: seed = mum(seed ^ (floatToIntBits(data[len-1]) >>> 16), b3 ^ (floatToIntBits(data[len-1]) & 0xFFFFL)); break; 3847 case 2: seed = mum(seed ^ floatToIntBits(data[len-2]), b0 ^ floatToIntBits(data[len-1])); break; 3848 case 3: seed = mum(seed ^ floatToIntBits(data[len-3]), b2 ^ floatToIntBits(data[len-2])) ^ mum(seed ^ floatToIntBits(data[len-1]), b4); break; 3849 } 3850 return (int) mum(seed ^ seed << 16, len ^ b0); 3851 } 3852 public static int hash(final double[] data) { 3853 if (data == null) return 0; 3854 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3855 final int len = data.length; 3856 for (int i = 3; i < len; i+=4) { 3857 seed = mum( 3858 mum(doubleToMixedIntBits(data[i-3]) ^ b1, doubleToMixedIntBits(data[i-2]) ^ b2) + seed, 3859 mum(doubleToMixedIntBits(data[i-1]) ^ b3, doubleToMixedIntBits(data[i]) ^ b4)); 3860 } 3861 switch (len & 3) { 3862 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3863 case 1: seed = mum(seed ^ (doubleToMixedIntBits(data[len-1]) >>> 16), b3 ^ (doubleToMixedIntBits(data[len-1]) & 0xFFFFL)); break; 3864 case 2: seed = mum(seed ^ doubleToMixedIntBits(data[len-2]), b0 ^ doubleToMixedIntBits(data[len-1])); break; 3865 case 3: seed = mum(seed ^ doubleToMixedIntBits(data[len-3]), b2 ^ doubleToMixedIntBits(data[len-2])) ^ mum(seed ^ doubleToMixedIntBits(data[len-1]), b4); break; 3866 } 3867 return (int) mum(seed ^ seed << 16, len ^ b0); 3868 } 3869 3870 /** 3871 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 3872 * 3873 * @param data the char array to hash 3874 * @param start the start of the section to hash (inclusive) 3875 * @param end the end of the section to hash (exclusive) 3876 * @return a 32-bit hash code for the requested section of data 3877 */ 3878 public static int hash(final char[] data, final int start, final int end) { 3879 if (data == null || start >= end) 3880 return 0; 3881 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3882 final int len = Math.min(end, data.length); 3883 for (int i = start + 3; i < len; i+=4) { 3884 seed = mum( 3885 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 3886 mum(data[i-1] ^ b3, data[i] ^ b4)); 3887 } 3888 switch (len - start & 3) { 3889 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3890 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 3891 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 3892 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 3893 } 3894 return (int) mum(seed ^ seed << 16, len - start ^ b0); 3895 } 3896 3897 /** 3898 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 3899 * 3900 * @param data the String or other CharSequence to hash 3901 * @param start the start of the section to hash (inclusive) 3902 * @param end the end of the section to hash (exclusive) 3903 * @return a 32-bit hash code for the requested section of data 3904 */ 3905 public static int hash(final CharSequence data, final int start, final int end) { 3906 if (data == null || start >= end) 3907 return 0; 3908 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3909 final int len = Math.min(end, data.length()); 3910 for (int i = start + 3; i < len; i+=4) { 3911 seed = mum( 3912 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 3913 mum(data.charAt(i-1) ^ b3, data.charAt(i) ^ b4)); 3914 } 3915 switch (len - start & 3) { 3916 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3917 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 3918 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 3919 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 3920 } 3921 return (int) mum(seed ^ seed << 16, len - start ^ b0); 3922 } 3923 3924 3925 public static int hash(final char[][] data) { 3926 if (data == null) return 0; 3927 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3928 final int len = data.length; 3929 for (int i = 3; i < len; i+=4) { 3930 seed = mum( 3931 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3932 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3933 } 3934 int t; 3935 switch (len & 3) { 3936 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3937 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3938 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3939 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3940 } 3941 return (int) mum(seed ^ seed << 16, len ^ b0); 3942 } 3943 3944 public static int hash(final int[][] data) { 3945 if (data == null) return 0; 3946 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3947 final int len = data.length; 3948 for (int i = 3; i < len; i+=4) { 3949 seed = mum( 3950 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3951 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3952 } 3953 int t; 3954 switch (len & 3) { 3955 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3956 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3957 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3958 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3959 } 3960 return (int) mum(seed ^ seed << 16, len ^ b0); 3961 } 3962 3963 public static int hash(final long[][] data) { 3964 if (data == null) return 0; 3965 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3966 final int len = data.length; 3967 for (int i = 3; i < len; i+=4) { 3968 seed = mum( 3969 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3970 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3971 } 3972 int t; 3973 switch (len & 3) { 3974 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3975 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3976 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3977 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3978 } 3979 return (int) mum(seed ^ seed << 16, len ^ b0); 3980 } 3981 3982 public static int hash(final CharSequence[] data) { 3983 if (data == null) return 0; 3984 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 3985 final int len = data.length; 3986 for (int i = 3; i < len; i+=4) { 3987 seed = mum( 3988 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 3989 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 3990 } 3991 int t; 3992 switch (len & 3) { 3993 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 3994 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 3995 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 3996 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 3997 } 3998 return (int) mum(seed ^ seed << 16, len ^ b0); 3999 } 4000 4001 public static int hash(final CharSequence[]... data) { 4002 if (data == null) return 0; 4003 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 4004 final int len = data.length; 4005 for (int i = 3; i < len; i+=4) { 4006 seed = mum( 4007 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4008 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4009 } 4010 int t; 4011 switch (len & 3) { 4012 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4013 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4014 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4015 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4016 } 4017 return (int) mum(seed ^ seed << 16, len ^ b0); 4018 } 4019 4020 public static int hash(final Iterable<? extends CharSequence> data) { 4021 if (data == null) return 0; 4022 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 4023 final Iterator<? extends CharSequence> it = data.iterator(); 4024 int len = 0; 4025 while (it.hasNext()) 4026 { 4027 ++len; 4028 seed = mum( 4029 mum(hash(it.next()) ^ b1, (it.hasNext() ? hash(it.next()) ^ b2 ^ ++len : b2)) + seed, 4030 mum((it.hasNext() ? hash(it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(it.next()) ^ b4 ^ ++len : b4))); 4031 } 4032 return (int) mum(seed ^ seed << 16, len ^ b0); 4033 } 4034 4035 public static int hash(final List<? extends CharSequence> data) { 4036 if (data == null) return 0; 4037 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 4038 final int len = data.size(); 4039 for (int i = 3; i < len; i+=4) { 4040 seed = mum( 4041 mum(hash(data.get(i-3)) ^ b1, hash(data.get(i-2)) ^ b2) + seed, 4042 mum(hash(data.get(i-1)) ^ b3, hash(data.get(i )) ^ b4)); 4043 } 4044 int t; 4045 switch (len & 3) { 4046 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4047 case 1: seed = mum(seed ^((t = hash(data.get(len-1))) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4048 case 2: seed = mum(seed ^ hash(data.get(len-2)), b0 ^ hash(data.get(len-1))); break; 4049 case 3: seed = mum(seed ^ hash(data.get(len-3)), b2 ^ hash(data.get(len-2))) ^ mum(seed ^ hash(data.get(len-1)), b4); break; 4050 } 4051 return (int) mum(seed ^ seed << 16, len ^ b0); 4052 } 4053 4054 public static int hash(final Object[] data) { 4055 if (data == null) return 0; 4056 long seed = -260224914646652572L;//b1 ^ b1 >>> 41 ^ b1 << 53; 4057 final int len = data.length; 4058 for (int i = 3; i < len; i+=4) { 4059 seed = mum( 4060 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4061 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4062 } 4063 int t; 4064 switch (len & 3) { 4065 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4066 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4067 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4068 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4069 } 4070 return (int) mum(seed ^ seed << 16, len ^ b0); 4071 } 4072 4073 public static int hash(final Object data) { 4074 if (data == null) 4075 return 0; 4076 final int h = data.hashCode() * 0x9E375; 4077 return h ^ (h >>> 16); 4078 } 4079 } 4080 4081 /** 4082 * Like Mist, this is a class for hash functors, each an object with a 64-bit long seed, but it uses about the same 4083 * algorithm as {@link Water} instead of the older, less-robust style Mist uses. This can be faster than 4084 * {@link Curlup}, but only for small arrays as input (20 length or less); it tends to be slower on larger arrays, 4085 * though not by much, and should be the same for {@code long[]} since they share an implementation for that type. 4086 * Normally you should prefer Curlup if you know some or all of your arrays will be of moderate size or larger. 4087 * Has a lot of predefined functors (192, named after 24 Greek letters and 72 Goetic demons, see 4088 * <a href="https://en.wikipedia.org/wiki/Lesser_Key_of_Solomon#The_Seventy-Two_Demons">Wikipedia for the demons</a>, 4089 * in both lower case and lower case with a trailing underscore). You probably want to use {@link #predefined} 4090 * instead of wrangling demon names; you can always choose an element from predefined with a 7-bit number, and there 4091 * are 64 numbers outside that range so you can choose any of those when a functor must be different. 4092 */ 4093 public static final class Yolk { 4094 private final long seed; 4095 4096 public Yolk(){ 4097 this.seed = 9069147967908697017L; 4098 } 4099 public Yolk(long seed) 4100 { 4101 seed += b1; 4102 this.seed = seed ^ seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 4103 } 4104 public Yolk(final CharSequence seed) 4105 { 4106 this(Hive.hash64(seed)); 4107 } 4108 4109 public static final Yolk alpha = new Yolk("alpha"), beta = new Yolk("beta"), gamma = new Yolk("gamma"), 4110 delta = new Yolk("delta"), epsilon = new Yolk("epsilon"), zeta = new Yolk("zeta"), 4111 eta = new Yolk("eta"), theta = new Yolk("theta"), iota = new Yolk("iota"), 4112 kappa = new Yolk("kappa"), lambda = new Yolk("lambda"), mu = new Yolk("mu"), 4113 nu = new Yolk("nu"), xi = new Yolk("xi"), omicron = new Yolk("omicron"), pi = new Yolk("pi"), 4114 rho = new Yolk("rho"), sigma = new Yolk("sigma"), tau = new Yolk("tau"), 4115 upsilon = new Yolk("upsilon"), phi = new Yolk("phi"), chi = new Yolk("chi"), psi = new Yolk("psi"), 4116 omega = new Yolk("omega"), 4117 alpha_ = new Yolk("ALPHA"), beta_ = new Yolk("BETA"), gamma_ = new Yolk("GAMMA"), 4118 delta_ = new Yolk("DELTA"), epsilon_ = new Yolk("EPSILON"), zeta_ = new Yolk("ZETA"), 4119 eta_ = new Yolk("ETA"), theta_ = new Yolk("THETA"), iota_ = new Yolk("IOTA"), 4120 kappa_ = new Yolk("KAPPA"), lambda_ = new Yolk("LAMBDA"), mu_ = new Yolk("MU"), 4121 nu_ = new Yolk("NU"), xi_ = new Yolk("XI"), omicron_ = new Yolk("OMICRON"), pi_ = new Yolk("PI"), 4122 rho_ = new Yolk("RHO"), sigma_ = new Yolk("SIGMA"), tau_ = new Yolk("TAU"), 4123 upsilon_ = new Yolk("UPSILON"), phi_ = new Yolk("PHI"), chi_ = new Yolk("CHI"), psi_ = new Yolk("PSI"), 4124 omega_ = new Yolk("OMEGA"), 4125 baal = new Yolk("baal"), agares = new Yolk("agares"), vassago = new Yolk("vassago"), samigina = new Yolk("samigina"), 4126 marbas = new Yolk("marbas"), valefor = new Yolk("valefor"), amon = new Yolk("amon"), barbatos = new Yolk("barbatos"), 4127 paimon = new Yolk("paimon"), buer = new Yolk("buer"), gusion = new Yolk("gusion"), sitri = new Yolk("sitri"), 4128 beleth = new Yolk("beleth"), leraje = new Yolk("leraje"), eligos = new Yolk("eligos"), zepar = new Yolk("zepar"), 4129 botis = new Yolk("botis"), bathin = new Yolk("bathin"), sallos = new Yolk("sallos"), purson = new Yolk("purson"), 4130 marax = new Yolk("marax"), ipos = new Yolk("ipos"), aim = new Yolk("aim"), naberius = new Yolk("naberius"), 4131 glasya_labolas = new Yolk("glasya_labolas"), bune = new Yolk("bune"), ronove = new Yolk("ronove"), berith = new Yolk("berith"), 4132 astaroth = new Yolk("astaroth"), forneus = new Yolk("forneus"), foras = new Yolk("foras"), asmoday = new Yolk("asmoday"), 4133 gaap = new Yolk("gaap"), furfur = new Yolk("furfur"), marchosias = new Yolk("marchosias"), stolas = new Yolk("stolas"), 4134 phenex = new Yolk("phenex"), halphas = new Yolk("halphas"), malphas = new Yolk("malphas"), raum = new Yolk("raum"), 4135 focalor = new Yolk("focalor"), vepar = new Yolk("vepar"), sabnock = new Yolk("sabnock"), shax = new Yolk("shax"), 4136 vine = new Yolk("vine"), bifrons = new Yolk("bifrons"), vual = new Yolk("vual"), haagenti = new Yolk("haagenti"), 4137 crocell = new Yolk("crocell"), furcas = new Yolk("furcas"), balam = new Yolk("balam"), alloces = new Yolk("alloces"), 4138 caim = new Yolk("caim"), murmur = new Yolk("murmur"), orobas = new Yolk("orobas"), gremory = new Yolk("gremory"), 4139 ose = new Yolk("ose"), amy = new Yolk("amy"), orias = new Yolk("orias"), vapula = new Yolk("vapula"), 4140 zagan = new Yolk("zagan"), valac = new Yolk("valac"), andras = new Yolk("andras"), flauros = new Yolk("flauros"), 4141 andrealphus = new Yolk("andrealphus"), kimaris = new Yolk("kimaris"), amdusias = new Yolk("amdusias"), belial = new Yolk("belial"), 4142 decarabia = new Yolk("decarabia"), seere = new Yolk("seere"), dantalion = new Yolk("dantalion"), andromalius = new Yolk("andromalius"), 4143 baal_ = new Yolk("BAAL"), agares_ = new Yolk("AGARES"), vassago_ = new Yolk("VASSAGO"), samigina_ = new Yolk("SAMIGINA"), 4144 marbas_ = new Yolk("MARBAS"), valefor_ = new Yolk("VALEFOR"), amon_ = new Yolk("AMON"), barbatos_ = new Yolk("BARBATOS"), 4145 paimon_ = new Yolk("PAIMON"), buer_ = new Yolk("BUER"), gusion_ = new Yolk("GUSION"), sitri_ = new Yolk("SITRI"), 4146 beleth_ = new Yolk("BELETH"), leraje_ = new Yolk("LERAJE"), eligos_ = new Yolk("ELIGOS"), zepar_ = new Yolk("ZEPAR"), 4147 botis_ = new Yolk("BOTIS"), bathin_ = new Yolk("BATHIN"), sallos_ = new Yolk("SALLOS"), purson_ = new Yolk("PURSON"), 4148 marax_ = new Yolk("MARAX"), ipos_ = new Yolk("IPOS"), aim_ = new Yolk("AIM"), naberius_ = new Yolk("NABERIUS"), 4149 glasya_labolas_ = new Yolk("GLASYA_LABOLAS"), bune_ = new Yolk("BUNE"), ronove_ = new Yolk("RONOVE"), berith_ = new Yolk("BERITH"), 4150 astaroth_ = new Yolk("ASTAROTH"), forneus_ = new Yolk("FORNEUS"), foras_ = new Yolk("FORAS"), asmoday_ = new Yolk("ASMODAY"), 4151 gaap_ = new Yolk("GAAP"), furfur_ = new Yolk("FURFUR"), marchosias_ = new Yolk("MARCHOSIAS"), stolas_ = new Yolk("STOLAS"), 4152 phenex_ = new Yolk("PHENEX"), halphas_ = new Yolk("HALPHAS"), malphas_ = new Yolk("MALPHAS"), raum_ = new Yolk("RAUM"), 4153 focalor_ = new Yolk("FOCALOR"), vepar_ = new Yolk("VEPAR"), sabnock_ = new Yolk("SABNOCK"), shax_ = new Yolk("SHAX"), 4154 vine_ = new Yolk("VINE"), bifrons_ = new Yolk("BIFRONS"), vual_ = new Yolk("VUAL"), haagenti_ = new Yolk("HAAGENTI"), 4155 crocell_ = new Yolk("CROCELL"), furcas_ = new Yolk("FURCAS"), balam_ = new Yolk("BALAM"), alloces_ = new Yolk("ALLOCES"), 4156 caim_ = new Yolk("CAIM"), murmur_ = new Yolk("MURMUR"), orobas_ = new Yolk("OROBAS"), gremory_ = new Yolk("GREMORY"), 4157 ose_ = new Yolk("OSE"), amy_ = new Yolk("AMY"), orias_ = new Yolk("ORIAS"), vapula_ = new Yolk("VAPULA"), 4158 zagan_ = new Yolk("ZAGAN"), valac_ = new Yolk("VALAC"), andras_ = new Yolk("ANDRAS"), flauros_ = new Yolk("FLAUROS"), 4159 andrealphus_ = new Yolk("ANDREALPHUS"), kimaris_ = new Yolk("KIMARIS"), amdusias_ = new Yolk("AMDUSIAS"), belial_ = new Yolk("BELIAL"), 4160 decarabia_ = new Yolk("DECARABIA"), seere_ = new Yolk("SEERE"), dantalion_ = new Yolk("DANTALION"), andromalius_ = new Yolk("ANDROMALIUS") 4161 ; 4162 /** 4163 * Has a length of 192, which may be relevant if automatically choosing a predefined hash functor. 4164 */ 4165 public static final Yolk[] predefined = new Yolk[]{alpha, beta, gamma, delta, epsilon, zeta, eta, theta, iota, 4166 kappa, lambda, mu, nu, xi, omicron, pi, rho, sigma, tau, upsilon, phi, chi, psi, omega, 4167 alpha_, beta_, gamma_, delta_, epsilon_, zeta_, eta_, theta_, iota_, 4168 kappa_, lambda_, mu_, nu_, xi_, omicron_, pi_, rho_, sigma_, tau_, upsilon_, phi_, chi_, psi_, omega_, 4169 baal, agares, vassago, samigina, marbas, valefor, amon, barbatos, 4170 paimon, buer, gusion, sitri, beleth, leraje, eligos, zepar, 4171 botis, bathin, sallos, purson, marax, ipos, aim, naberius, 4172 glasya_labolas, bune, ronove, berith, astaroth, forneus, foras, asmoday, 4173 gaap, furfur, marchosias, stolas, phenex, halphas, malphas, raum, 4174 focalor, vepar, sabnock, shax, vine, bifrons, vual, haagenti, 4175 crocell, furcas, balam, alloces, caim, murmur, orobas, gremory, 4176 ose, amy, orias, vapula, zagan, valac, andras, flauros, 4177 andrealphus, kimaris, amdusias, belial, decarabia, seere, dantalion, andromalius, 4178 baal_, agares_, vassago_, samigina_, marbas_, valefor_, amon_, barbatos_, 4179 paimon_, buer_, gusion_, sitri_, beleth_, leraje_, eligos_, zepar_, 4180 botis_, bathin_, sallos_, purson_, marax_, ipos_, aim_, naberius_, 4181 glasya_labolas_, bune_, ronove_, berith_, astaroth_, forneus_, foras_, asmoday_, 4182 gaap_, furfur_, marchosias_, stolas_, phenex_, halphas_, malphas_, raum_, 4183 focalor_, vepar_, sabnock_, shax_, vine_, bifrons_, vual_, haagenti_, 4184 crocell_, furcas_, balam_, alloces_, caim_, murmur_, orobas_, gremory_, 4185 ose_, amy_, orias_, vapula_, zagan_, valac_, andras_, flauros_, 4186 andrealphus_, kimaris_, amdusias_, belial_, decarabia_, seere_, dantalion_, andromalius_}; 4187 4188 4189 public long hash64(final boolean[] data) { 4190 if (data == null) return 0; 4191 long seed = this.seed;//seed = b1 ^ b1 >>> 29 ^ b1 >>> 43 ^ b1 << 7 ^ b1 << 53; 4192 final int len = data.length; 4193 for (int i = 3; i < len; i+=4) { 4194 seed = mum( 4195 mum((data[i-3] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b1, (data[i-2] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b2) + seed, 4196 mum((data[i-1] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b3, (data[i] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b4)); 4197 } 4198 switch (len & 3) { 4199 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4200 case 1: seed = mum(seed ^ (data[len-1] ? 0x9E37L : 0x7F4AL), b3 ^ (data[len-1] ? 0x79B9L : 0x7C15L)); break; 4201 case 2: seed = mum(seed ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L), b0 ^ (data[len-1] ? 0x9E3779B9L : 0x7F4A7C15L)); break; 4202 case 3: seed = mum(seed ^ (data[len-3] ? 0x9E3779B9L : 0x7F4A7C15L), b2 ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L)) ^ mum(seed ^ (data[len-1] ? 0x9E3779B9 : 0x7F4A7C15), b4); break; 4203 } 4204 seed = (seed ^ seed << 16) * (len ^ b0); 4205 return seed - (seed >>> 31) + (seed << 33); 4206 } 4207 public long hash64(final byte[] data) { 4208 if (data == null) return 0; 4209 long seed = this.seed; 4210 final int len = data.length; 4211 for (int i = 3; i < len; i+=4) { 4212 seed = mum( 4213 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4214 mum(data[i-1] ^ b3, data[i] ^ b4)); 4215 } 4216 switch (len & 3) { 4217 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4218 case 1: seed = mum(seed ^ b2, b1 ^ data[len-1]); break; 4219 case 2: seed = mum(seed ^ b3, data[len-2] ^ data[len-1] << 8 ^ b4); break; 4220 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 8, b2 ^ data[len-1]); break; 4221 } 4222 seed = (seed ^ seed << 16) * (len ^ b0); 4223 return seed - (seed >>> 31) + (seed << 33); 4224 } 4225 4226 public long hash64(final short[] data) { 4227 if (data == null) return 0; 4228 long seed = this.seed; 4229 final int len = data.length; 4230 for (int i = 3; i < len; i+=4) { 4231 seed = mum( 4232 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4233 mum(data[i-1] ^ b3, data[i] ^ b4)); 4234 } 4235 switch (len & 3) { 4236 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4237 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 4238 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 4239 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 4240 } 4241 seed = (seed ^ seed << 16) * (len ^ b0); 4242 return seed - (seed >>> 31) + (seed << 33); 4243 } 4244 4245 public long hash64(final char[] data) { 4246 if (data == null) return 0; 4247 long seed = this.seed; 4248 final int len = data.length; 4249 for (int i = 3; i < len; i+=4) { 4250 seed = mum( 4251 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4252 mum(data[i-1] ^ b3, data[i] ^ b4)); 4253 } 4254 switch (len & 3) { 4255 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4256 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 4257 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 4258 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 4259 } 4260 seed = (seed ^ seed << 16) * (len ^ b0); 4261 return seed - (seed >>> 31) + (seed << 33); 4262 } 4263 4264 public long hash64(final CharSequence data) { 4265 if (data == null) return 0; 4266 long seed = this.seed; 4267 final int len = data.length(); 4268 for (int i = 3; i < len; i+=4) { 4269 seed = mum( 4270 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 4271 mum(data.charAt(i-1) ^ b3, data.charAt(i ) ^ b4)); 4272 } 4273 switch (len & 3) { 4274 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4275 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 4276 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 4277 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 4278 } 4279 seed = (seed ^ seed << 16) * (len ^ b0); 4280 return seed - (seed >>> 31) + (seed << 33); 4281 } 4282 4283 public long hash64(final int[] data) { 4284 if (data == null) return 0; 4285 long seed = this.seed; 4286 final int len = data.length; 4287 for (int i = 3; i < len; i+=4) { 4288 seed = mum( 4289 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4290 mum(data[i-1] ^ b3, data[i] ^ b4)); 4291 } 4292 switch (len & 3) { 4293 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4294 case 1: seed = mum(seed ^ (data[len-1] >>> 16), b3 ^ (data[len-1] & 0xFFFFL)); break; 4295 case 2: seed = mum(seed ^ data[len-2], b0 ^ data[len-1]); break; 4296 case 3: seed = mum(seed ^ data[len-3], b2 ^ data[len-2]) ^ mum(seed ^ data[len-1], b4); break; 4297 } 4298 seed = (seed ^ seed << 16) * (len ^ b0); 4299 return seed - (seed >>> 31) + (seed << 33); 4300 } 4301 4302 public long hash64(final int[] data, final int length) { 4303 if (data == null) return 0; 4304 long seed = this.seed; 4305 for (int i = 3; i < length; i+=4) { 4306 seed = mum( 4307 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4308 mum(data[i-1] ^ b3, data[i] ^ b4)); 4309 } 4310 switch (length & 3) { 4311 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4312 case 1: seed = mum(seed ^ (data[length-1] >>> 16), b3 ^ (data[length-1] & 0xFFFFL)); break; 4313 case 2: seed = mum(seed ^ data[length-2], b0 ^ data[length-1]); break; 4314 case 3: seed = mum(seed ^ data[length-3], b2 ^ data[length-2]) ^ mum(seed ^ data[length-1], b4); break; 4315 } 4316 seed = (seed ^ seed << 16) * (length ^ b0); 4317 return seed - (seed >>> 31) + (seed << 33); 4318 } 4319 4320 public long hash64(final long[] data) { 4321 if (data == null) return 0; 4322 long seed = this.seed, a = this.seed + b4, b = this.seed + b3, c = this.seed + b2, d = this.seed + b1; 4323 final int len = data.length; 4324 for (int i = 3; i < len; i+=4) { 4325 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 4326 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 4327 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 4328 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 4329 seed += a + b + c + d; 4330 } 4331 seed += b5; 4332 switch (len & 3) { 4333 case 1: seed = wow(seed, b1 ^ data[len-1]); break; 4334 case 2: seed = wow(seed + data[len-2], b2 + data[len-1]); break; 4335 case 3: seed = wow(seed + data[len-3], b2 + data[len-2]) ^ wow(seed + data[len-1], seed ^ b3); break; 4336 } 4337 seed = (seed ^ seed << 16) * (len ^ b0 ^ seed >>> 32); 4338 return seed - (seed >>> 31) + (seed << 33); 4339 } 4340 public long hash64(final float[] data) { 4341 if (data == null) return 0; 4342 long seed = this.seed; 4343 final int len = data.length; 4344 for (int i = 3; i < len; i+=4) { 4345 seed = mum( 4346 mum(floatToIntBits(data[i-3]) ^ b1, floatToIntBits(data[i-2]) ^ b2) + seed, 4347 mum(floatToIntBits(data[i-1]) ^ b3, floatToIntBits(data[i]) ^ b4)); 4348 } 4349 switch (len & 3) { 4350 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4351 case 1: seed = mum(seed ^ (floatToIntBits(data[len-1]) >>> 16), b3 ^ (floatToIntBits(data[len-1]) & 0xFFFFL)); break; 4352 case 2: seed = mum(seed ^ floatToIntBits(data[len-2]), b0 ^ floatToIntBits(data[len-1])); break; 4353 case 3: seed = mum(seed ^ floatToIntBits(data[len-3]), b2 ^ floatToIntBits(data[len-2])) ^ mum(seed ^ floatToIntBits(data[len-1]), b4); break; 4354 } 4355 seed = (seed ^ seed << 16) * (len ^ b0); 4356 return seed - (seed >>> 31) + (seed << 33); 4357 } 4358 public long hash64(final double[] data) { 4359 if (data == null) return 0; 4360 long seed = this.seed; 4361 final int len = data.length; 4362 for (int i = 3; i < len; i+=4) { 4363 seed = mum( 4364 mum(doubleToMixedIntBits(data[i-3]) ^ b1, doubleToMixedIntBits(data[i-2]) ^ b2) + seed, 4365 mum(doubleToMixedIntBits(data[i-1]) ^ b3, doubleToMixedIntBits(data[i]) ^ b4)); 4366 } 4367 switch (len & 3) { 4368 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4369 case 1: seed = mum(seed ^ (doubleToMixedIntBits(data[len-1]) >>> 16), b3 ^ (doubleToMixedIntBits(data[len-1]) & 0xFFFFL)); break; 4370 case 2: seed = mum(seed ^ doubleToMixedIntBits(data[len-2]), b0 ^ doubleToMixedIntBits(data[len-1])); break; 4371 case 3: seed = mum(seed ^ doubleToMixedIntBits(data[len-3]), b2 ^ doubleToMixedIntBits(data[len-2])) ^ mum(seed ^ doubleToMixedIntBits(data[len-1]), b4); break; 4372 } 4373 seed = (seed ^ seed << 16) * (len ^ b0); 4374 return seed - (seed >>> 31) + (seed << 33); 4375 } 4376 4377 /** 4378 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 4379 * 4380 * @param data the char array to hash 4381 * @param start the start of the section to hash (inclusive) 4382 * @param end the end of the section to hash (exclusive) 4383 * @return a 64-bit hash code for the requested section of data 4384 */ 4385 public long hash64(final char[] data, final int start, final int end) { 4386 if (data == null || start >= end) 4387 return 0; 4388 long seed = this.seed; 4389 final int len = Math.min(end, data.length); 4390 for (int i = start + 3; i < len; i+=4) { 4391 seed = mum( 4392 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4393 mum(data[i-1] ^ b3, data[i] ^ b4)); 4394 } 4395 switch (len - start & 3) { 4396 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4397 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 4398 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 4399 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 4400 } 4401 return mum(seed ^ seed << 16, len - start ^ Water.b0); 4402 } 4403 4404 /** 4405 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 4406 * 4407 * @param data the String or other CharSequence to hash 4408 * @param start the start of the section to hash (inclusive) 4409 * @param end the end of the section to hash (exclusive) 4410 * @return a 64-bit hash code for the requested section of data 4411 */ 4412 public long hash64(final CharSequence data, final int start, final int end) { 4413 if (data == null || start >= end) 4414 return 0; 4415 long seed = this.seed; 4416 final int len = Math.min(end, data.length()); 4417 for (int i = start + 3; i < len; i+=4) { 4418 seed = mum( 4419 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 4420 mum(data.charAt(i-1) ^ b3, data.charAt(i) ^ b4)); 4421 } 4422 switch (len - start & 3) { 4423 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4424 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 4425 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 4426 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 4427 } 4428 return mum(seed ^ seed << 16, len - start ^ b0); 4429 } 4430 4431 4432 public long hash64(final char[][] data) { 4433 if (data == null) return 0; 4434 long seed = this.seed; 4435 final int len = data.length; 4436 for (int i = 3; i < len; i+=4) { 4437 seed = mum( 4438 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4439 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4440 } 4441 int t; 4442 switch (len & 3) { 4443 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4444 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4445 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4446 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4447 } 4448 seed = (seed ^ seed << 16) * (len ^ b0); 4449 return seed - (seed >>> 31) + (seed << 33); 4450 } 4451 4452 public long hash64(final int[][] data) { 4453 if (data == null) return 0; 4454 long seed = this.seed; 4455 final int len = data.length; 4456 for (int i = 3; i < len; i+=4) { 4457 seed = mum( 4458 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4459 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4460 } 4461 int t; 4462 switch (len & 3) { 4463 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4464 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4465 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4466 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4467 } 4468 seed = (seed ^ seed << 16) * (len ^ b0); 4469 return seed - (seed >>> 31) + (seed << 33); 4470 } 4471 4472 public long hash64(final long[][] data) { 4473 if (data == null) return 0; 4474 long seed = this.seed; 4475 final int len = data.length; 4476 for (int i = 3; i < len; i+=4) { 4477 seed = mum( 4478 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4479 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4480 } 4481 int t; 4482 switch (len & 3) { 4483 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4484 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4485 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4486 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4487 } 4488 seed = (seed ^ seed << 16) * (len ^ b0); 4489 return seed - (seed >>> 31) + (seed << 33); 4490 } 4491 4492 public long hash64(final CharSequence[] data) { 4493 if (data == null) return 0; 4494 long seed = this.seed; 4495 final int len = data.length; 4496 for (int i = 3; i < len; i+=4) { 4497 seed = mum( 4498 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4499 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4500 } 4501 int t; 4502 switch (len & 3) { 4503 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4504 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4505 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4506 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4507 } 4508 seed = (seed ^ seed << 16) * (len ^ b0); 4509 return seed - (seed >>> 31) + (seed << 33); 4510 } 4511 4512 public long hash64(final CharSequence[]... data) { 4513 if (data == null) return 0; 4514 long seed = this.seed; 4515 final int len = data.length; 4516 for (int i = 3; i < len; i+=4) { 4517 seed = mum( 4518 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4519 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4520 } 4521 int t; 4522 switch (len & 3) { 4523 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4524 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4525 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4526 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4527 } 4528 seed = (seed ^ seed << 16) * (len ^ b0); 4529 return seed - (seed >>> 31) + (seed << 33); 4530 } 4531 4532 public long hash64(final Iterable<? extends CharSequence> data) { 4533 if (data == null) return 0; 4534 long seed = this.seed; 4535 final Iterator<? extends CharSequence> it = data.iterator(); 4536 int len = 0; 4537 while (it.hasNext()) 4538 { 4539 ++len; 4540 seed = mum( 4541 mum(hash(it.next()) ^ b1, (it.hasNext() ? hash(it.next()) ^ b2 ^ ++len : b2)) + seed, 4542 mum((it.hasNext() ? hash(it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(it.next()) ^ b4 ^ ++len : b4))); 4543 } 4544 seed = (seed ^ seed << 16) * (len ^ b0); 4545 return seed - (seed >>> 31) + (seed << 33); 4546 } 4547 4548 public long hash64(final List<? extends CharSequence> data) { 4549 if (data == null) return 0; 4550 long seed = this.seed; 4551 final int len = data.size(); 4552 for (int i = 3; i < len; i+=4) { 4553 seed = mum( 4554 mum(hash(data.get(i-3)) ^ b1, hash(data.get(i-2)) ^ b2) + seed, 4555 mum(hash(data.get(i-1)) ^ b3, hash(data.get(i )) ^ b4)); 4556 } 4557 int t; 4558 switch (len & 3) { 4559 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4560 case 1: seed = mum(seed ^((t = hash(data.get(len-1))) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4561 case 2: seed = mum(seed ^ hash(data.get(len-2)), b0 ^ hash(data.get(len-1))); break; 4562 case 3: seed = mum(seed ^ hash(data.get(len-3)), b2 ^ hash(data.get(len-2))) ^ mum(seed ^ hash(data.get(len-1)), b4); break; 4563 } 4564 seed = (seed ^ seed << 16) * (len ^ b0); 4565 return seed - (seed >>> 31) + (seed << 33); 4566 4567 } 4568 4569 public long hash64(final Object[] data) { 4570 if (data == null) return 0; 4571 long seed = this.seed; 4572 final int len = data.length; 4573 for (int i = 3; i < len; i+=4) { 4574 seed = mum( 4575 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4576 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4577 } 4578 int t; 4579 switch (len & 3) { 4580 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4581 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4582 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4583 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4584 } 4585 seed = (seed ^ seed << 16) * (len ^ b0); 4586 return seed - (seed >>> 31) + (seed << 33); 4587 } 4588 4589 public long hash64(final Object data) { 4590 if (data == null) 4591 return 0; 4592 final long h = (data.hashCode() + seed) * 0x9E3779B97F4A7C15L; 4593 return h - (h >>> 31) + (h << 33); 4594 } 4595 4596 4597 public int hash(final boolean[] data) { 4598 if (data == null) return 0; 4599 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4600 final int len = data.length; 4601 for (int i = 3; i < len; i+=4) { 4602 seed = mum( 4603 mum((data[i-3] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b1, (data[i-2] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b2) + seed, 4604 mum((data[i-1] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b3, (data[i] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b4)); 4605 } 4606 switch (len & 3) { 4607 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4608 case 1: seed = mum(seed ^ (data[len-1] ? 0x9E37L : 0x7F4AL), b3 ^ (data[len-1] ? 0x79B9L : 0x7C15L)); break; 4609 case 2: seed = mum(seed ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L), b0 ^ (data[len-1] ? 0x9E3779B9L : 0x7F4A7C15L)); break; 4610 case 3: seed = mum(seed ^ (data[len-3] ? 0x9E3779B9L : 0x7F4A7C15L), b2 ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L)) ^ mum(seed ^ (data[len-1] ? 0x9E3779B9 : 0x7F4A7C15), b4); break; 4611 } 4612 return (int) mum(seed ^ seed << 16, len ^ b0); 4613 } 4614 public int hash(final byte[] data) { 4615 if (data == null) return 0; 4616 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4617 final int len = data.length; 4618 for (int i = 3; i < len; i+=4) { 4619 seed = mum( 4620 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4621 mum(data[i-1] ^ b3, data[i] ^ b4)); 4622 } 4623 switch (len & 3) { 4624 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4625 case 1: seed = mum(seed ^ b2, b1 ^ data[len-1]); break; 4626 case 2: seed = mum(seed ^ b3, data[len-2] ^ data[len-1] << 8 ^ b4); break; 4627 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 8, b2 ^ data[len-1]); break; 4628 } 4629 return (int) mum(seed ^ seed << 16, len ^ b0); 4630 } 4631 4632 public int hash(final short[] data) { 4633 if (data == null) return 0; 4634 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4635 final int len = data.length; 4636 for (int i = 3; i < len; i+=4) { 4637 seed = mum( 4638 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4639 mum(data[i-1] ^ b3, data[i] ^ b4)); 4640 } 4641 switch (len & 3) { 4642 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4643 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 4644 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 4645 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 4646 } 4647 return (int) mum(seed ^ seed << 16, len ^ b0); 4648 } 4649 4650 public int hash(final char[] data) { 4651 if (data == null) return 0; 4652 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4653 final int len = data.length; 4654 for (int i = 3; i < len; i+=4) { 4655 seed = mum( 4656 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4657 mum(data[i-1] ^ b3, data[i] ^ b4)); 4658 } 4659 switch (len & 3) { 4660 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4661 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 4662 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 4663 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 4664 } 4665 return (int) mum(seed ^ seed << 16, len ^ b0); 4666 } 4667 4668 public int hash(final CharSequence data) { 4669 if (data == null) return 0; 4670 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4671 final int len = data.length(); 4672 for (int i = 3; i < len; i+=4) { 4673 seed = mum( 4674 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 4675 mum(data.charAt(i-1) ^ b3, data.charAt(i ) ^ b4)); 4676 } 4677 switch (len & 3) { 4678 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4679 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 4680 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 4681 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 4682 } 4683 return (int) mum(seed ^ seed << 16, len ^ b0); 4684 } 4685 public int hash(final int[] data) { 4686 if (data == null) return 0; 4687 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4688 final int len = data.length; 4689 for (int i = 3; i < len; i+=4) { 4690 seed = mum( 4691 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4692 mum(data[i-1] ^ b3, data[i] ^ b4)); 4693 } 4694 switch (len & 3) { 4695 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4696 case 1: seed = mum(seed ^ (data[len-1] >>> 16), b3 ^ (data[len-1] & 0xFFFFL)); break; 4697 case 2: seed = mum(seed ^ data[len-2], b0 ^ data[len-1]); break; 4698 case 3: seed = mum(seed ^ data[len-3], b2 ^ data[len-2]) ^ mum(seed ^ data[len-1], b4); break; 4699 } 4700 return (int) mum(seed ^ seed << 16, len ^ b0); 4701 } 4702 public int hash(final int[] data, final int length) { 4703 if (data == null) return 0; 4704 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4705 for (int i = 3; i < length; i+=4) { 4706 seed = mum( 4707 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4708 mum(data[i-1] ^ b3, data[i] ^ b4)); 4709 } 4710 switch (length & 3) { 4711 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4712 case 1: seed = mum(seed ^ (data[length-1] >>> 16), b3 ^ (data[length-1] & 0xFFFFL)); break; 4713 case 2: seed = mum(seed ^ data[length-2], b0 ^ data[length-1]); break; 4714 case 3: seed = mum(seed ^ data[length-3], b2 ^ data[length-2]) ^ mum(seed ^ data[length-1], b4); break; 4715 } 4716 return (int) mum(seed ^ seed << 16, length ^ b0); 4717 } 4718 4719 public int hash(final long[] data) { 4720 if (data == null) return 0; 4721 long seed = this.seed, a = this.seed + b4, b = this.seed + b3, c = this.seed + b2, d = this.seed + b1; 4722 final int len = data.length; 4723 for (int i = 3; i < len; i+=4) { 4724 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 4725 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 4726 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 4727 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 4728 seed += a + b + c + d; 4729 } 4730 seed += b5; 4731 switch (len & 3) { 4732 case 1: seed = wow(seed, b1 ^ data[len-1]); break; 4733 case 2: seed = wow(seed + data[len-2], b2 + data[len-1]); break; 4734 case 3: seed = wow(seed + data[len-3], b2 + data[len-2]) ^ wow(seed + data[len-1], seed ^ b3); break; 4735 } 4736 seed = (seed ^ seed << 16) * (len ^ b0 ^ seed >>> 32); 4737 return (int)(seed - (seed >>> 32)); 4738 } 4739 4740 public int hash(final float[] data) { 4741 if (data == null) return 0; 4742 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4743 final int len = data.length; 4744 for (int i = 3; i < len; i+=4) { 4745 seed = mum( 4746 mum(floatToIntBits(data[i-3]) ^ b1, floatToIntBits(data[i-2]) ^ b2) + seed, 4747 mum(floatToIntBits(data[i-1]) ^ b3, floatToIntBits(data[i]) ^ b4)); 4748 } 4749 switch (len & 3) { 4750 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4751 case 1: seed = mum(seed ^ (floatToIntBits(data[len-1]) >>> 16), b3 ^ (floatToIntBits(data[len-1]) & 0xFFFFL)); break; 4752 case 2: seed = mum(seed ^ floatToIntBits(data[len-2]), b0 ^ floatToIntBits(data[len-1])); break; 4753 case 3: seed = mum(seed ^ floatToIntBits(data[len-3]), b2 ^ floatToIntBits(data[len-2])) ^ mum(seed ^ floatToIntBits(data[len-1]), b4); break; 4754 } 4755 return (int) mum(seed ^ seed << 16, len ^ b0); 4756 } 4757 public int hash(final double[] data) { 4758 if (data == null) return 0; 4759 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4760 final int len = data.length; 4761 for (int i = 3; i < len; i+=4) { 4762 seed = mum( 4763 mum(doubleToMixedIntBits(data[i-3]) ^ b1, doubleToMixedIntBits(data[i-2]) ^ b2) + seed, 4764 mum(doubleToMixedIntBits(data[i-1]) ^ b3, doubleToMixedIntBits(data[i]) ^ b4)); 4765 } 4766 switch (len & 3) { 4767 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4768 case 1: seed = mum(seed ^ (doubleToMixedIntBits(data[len-1]) >>> 16), b3 ^ (doubleToMixedIntBits(data[len-1]) & 0xFFFFL)); break; 4769 case 2: seed = mum(seed ^ doubleToMixedIntBits(data[len-2]), b0 ^ doubleToMixedIntBits(data[len-1])); break; 4770 case 3: seed = mum(seed ^ doubleToMixedIntBits(data[len-3]), b2 ^ doubleToMixedIntBits(data[len-2])) ^ mum(seed ^ doubleToMixedIntBits(data[len-1]), b4); break; 4771 } 4772 return (int) mum(seed ^ seed << 16, len ^ b0); 4773 } 4774 4775 /** 4776 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 4777 * 4778 * @param data the char array to hash 4779 * @param start the start of the section to hash (inclusive) 4780 * @param end the end of the section to hash (exclusive) 4781 * @return a 32-bit hash code for the requested section of data 4782 */ 4783 public int hash(final char[] data, final int start, final int end) { 4784 if (data == null || start >= end) 4785 return 0; 4786 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4787 final int len = Math.min(end, data.length); 4788 for (int i = start + 3; i < len; i+=4) { 4789 seed = mum( 4790 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 4791 mum(data[i-1] ^ b3, data[i] ^ b4)); 4792 } 4793 switch (len - start & 3) { 4794 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4795 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 4796 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 4797 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 4798 } 4799 return (int) mum(seed ^ seed << 16, len - start ^ b0); 4800 } 4801 4802 /** 4803 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 4804 * 4805 * @param data the String or other CharSequence to hash 4806 * @param start the start of the section to hash (inclusive) 4807 * @param end the end of the section to hash (exclusive) 4808 * @return a 32-bit hash code for the requested section of data 4809 */ 4810 public int hash(final CharSequence data, final int start, final int end) { 4811 if (data == null || start >= end) 4812 return 0; 4813 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4814 final int len = Math.min(end, data.length()); 4815 for (int i = start + 3; i < len; i+=4) { 4816 seed = mum( 4817 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 4818 mum(data.charAt(i-1) ^ b3, data.charAt(i) ^ b4)); 4819 } 4820 switch (len - start & 3) { 4821 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4822 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 4823 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 4824 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 4825 } 4826 return (int) mum(seed ^ seed << 16, len - start ^ b0); 4827 } 4828 4829 4830 public int hash(final char[][] data) { 4831 if (data == null) return 0; 4832 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4833 final int len = data.length; 4834 for (int i = 3; i < len; i+=4) { 4835 seed = mum( 4836 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4837 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4838 } 4839 int t; 4840 switch (len & 3) { 4841 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4842 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4843 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4844 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4845 } 4846 return (int) mum(seed ^ seed << 16, len ^ b0); 4847 } 4848 4849 public int hash(final int[][] data) { 4850 if (data == null) return 0; 4851 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4852 final int len = data.length; 4853 for (int i = 3; i < len; i+=4) { 4854 seed = mum( 4855 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4856 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4857 } 4858 int t; 4859 switch (len & 3) { 4860 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4861 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4862 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4863 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4864 } 4865 return (int) mum(seed ^ seed << 16, len ^ b0); 4866 } 4867 4868 public int hash(final long[][] data) { 4869 if (data == null) return 0; 4870 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4871 final int len = data.length; 4872 for (int i = 3; i < len; i+=4) { 4873 seed = mum( 4874 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4875 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4876 } 4877 int t; 4878 switch (len & 3) { 4879 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4880 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4881 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4882 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4883 } 4884 return (int) mum(seed ^ seed << 16, len ^ b0); 4885 } 4886 4887 public int hash(final CharSequence[] data) { 4888 if (data == null) return 0; 4889 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4890 final int len = data.length; 4891 for (int i = 3; i < len; i+=4) { 4892 seed = mum( 4893 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4894 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4895 } 4896 int t; 4897 switch (len & 3) { 4898 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4899 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4900 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4901 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4902 } 4903 return (int) mum(seed ^ seed << 16, len ^ b0); 4904 } 4905 4906 public int hash(final CharSequence[]... data) { 4907 if (data == null) return 0; 4908 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4909 final int len = data.length; 4910 for (int i = 3; i < len; i+=4) { 4911 seed = mum( 4912 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4913 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4914 } 4915 int t; 4916 switch (len & 3) { 4917 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4918 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4919 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4920 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4921 } 4922 return (int) mum(seed ^ seed << 16, len ^ b0); 4923 } 4924 4925 public int hash(final Iterable<? extends CharSequence> data) { 4926 if (data == null) return 0; 4927 long seed = this.seed; 4928 final Iterator<? extends CharSequence> it = data.iterator(); 4929 int len = 0; 4930 while (it.hasNext()) 4931 { 4932 ++len; 4933 seed = mum( 4934 mum(hash(it.next()) ^ b1, (it.hasNext() ? hash(it.next()) ^ b2 ^ ++len : b2)) + seed, 4935 mum((it.hasNext() ? hash(it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(it.next()) ^ b4 ^ ++len : b4))); 4936 } 4937 return (int) mum(seed ^ seed << 16, len ^ b0); 4938 } 4939 4940 public int hash(final List<? extends CharSequence> data) { 4941 if (data == null) return 0; 4942 long seed = this.seed;//b1 ^ b1 >>> 41 ^ b1 << 53; 4943 final int len = data.size(); 4944 for (int i = 3; i < len; i+=4) { 4945 seed = mum( 4946 mum(hash(data.get(i-3)) ^ b1, hash(data.get(i-2)) ^ b2) + seed, 4947 mum(hash(data.get(i-1)) ^ b3, hash(data.get(i )) ^ b4)); 4948 } 4949 int t; 4950 switch (len & 3) { 4951 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4952 case 1: seed = mum(seed ^((t = hash(data.get(len-1))) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4953 case 2: seed = mum(seed ^ hash(data.get(len-2)), b0 ^ hash(data.get(len-1))); break; 4954 case 3: seed = mum(seed ^ hash(data.get(len-3)), b2 ^ hash(data.get(len-2))) ^ mum(seed ^ hash(data.get(len-1)), b4); break; 4955 } 4956 return (int) mum(seed ^ seed << 16, len ^ b0); 4957 } 4958 4959 public int hash(final Object[] data) { 4960 if (data == null) return 0; 4961 long seed = this.seed; 4962 final int len = data.length; 4963 for (int i = 3; i < len; i+=4) { 4964 seed = mum( 4965 mum(hash(data[i-3]) ^ b1, hash(data[i-2]) ^ b2) + seed, 4966 mum(hash(data[i-1]) ^ b3, hash(data[i ]) ^ b4)); 4967 } 4968 int t; 4969 switch (len & 3) { 4970 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4971 case 1: seed = mum(seed ^((t = hash(data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 4972 case 2: seed = mum(seed ^ hash(data[len-2]), b0 ^ hash(data[len-1])); break; 4973 case 3: seed = mum(seed ^ hash(data[len-3]), b2 ^ hash(data[len-2])) ^ mum(seed ^ hash(data[len-1]), b4); break; 4974 } 4975 return (int) mum(seed ^ seed << 16, len ^ b0); 4976 } 4977 4978 public int hash(final Object data) { 4979 if (data == null) return 0; 4980 return (int)((data.hashCode() + seed) * 0x9E3779B97F4A7C15L >>> 32); 4981 } 4982 4983 4984 public static long hash64(long seed, final boolean[] data) { 4985 if (data == null) return 0L; 4986 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 4987 final int len = data.length; 4988 for (int i = 3; i < len; i+=4) { 4989 seed = mum( 4990 mum((data[i-3] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b1, (data[i-2] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b2) + seed, 4991 mum((data[i-1] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b3, (data[i] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b4)); 4992 } 4993 switch (len & 3) { 4994 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 4995 case 1: seed = mum(seed ^ (data[len-1] ? 0x9E37L : 0x7F4AL), b3 ^ (data[len-1] ? 0x79B9L : 0x7C15L)); break; 4996 case 2: seed = mum(seed ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L), b0 ^ (data[len-1] ? 0x9E3779B9L : 0x7F4A7C15L)); break; 4997 case 3: seed = mum(seed ^ (data[len-3] ? 0x9E3779B9L : 0x7F4A7C15L), b2 ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L)) ^ mum(seed ^ (data[len-1] ? 0x9E3779B9 : 0x7F4A7C15), b4); break; 4998 } 4999 seed = (seed ^ seed << 16) * (len ^ b0); 5000 return seed - (seed >>> 31) + (seed << 33); 5001 } 5002 public static long hash64(long seed, final byte[] data) { 5003 if (data == null) return 0L; 5004 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5005 final int len = data.length; 5006 for (int i = 3; i < len; i+=4) { 5007 seed = mum( 5008 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5009 mum(data[i-1] ^ b3, data[i] ^ b4)); 5010 } 5011 switch (len & 3) { 5012 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5013 case 1: seed = mum(seed ^ b2, b1 ^ data[len-1]); break; 5014 case 2: seed = mum(seed ^ b3, data[len-2] ^ data[len-1] << 8 ^ b4); break; 5015 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 8, b2 ^ data[len-1]); break; 5016 } 5017 seed = (seed ^ seed << 16) * (len ^ b0); 5018 return seed - (seed >>> 31) + (seed << 33); 5019 } 5020 5021 public static long hash64(long seed, final short[] data) { 5022 if (data == null) return 0L; 5023 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5024 final int len = data.length; 5025 for (int i = 3; i < len; i+=4) { 5026 seed = mum( 5027 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5028 mum(data[i-1] ^ b3, data[i] ^ b4)); 5029 } 5030 switch (len & 3) { 5031 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5032 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 5033 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 5034 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 5035 } 5036 seed = (seed ^ seed << 16) * (len ^ b0); 5037 return seed - (seed >>> 31) + (seed << 33); 5038 } 5039 5040 public static long hash64(long seed, final char[] data) { 5041 if (data == null) return 0L; 5042 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5043 final int len = data.length; 5044 for (int i = 3; i < len; i+=4) { 5045 seed = mum( 5046 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5047 mum(data[i-1] ^ b3, data[i] ^ b4)); 5048 } 5049 switch (len & 3) { 5050 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5051 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 5052 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 5053 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 5054 } 5055 seed = (seed ^ seed << 16) * (len ^ b0); 5056 return seed - (seed >>> 31) + (seed << 33); 5057 } 5058 5059 public static long hash64(long seed, final CharSequence data) { 5060 if (data == null) return 0L; 5061 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5062 final int len = data.length(); 5063 for (int i = 3; i < len; i+=4) { 5064 seed = mum( 5065 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 5066 mum(data.charAt(i-1) ^ b3, data.charAt(i ) ^ b4)); 5067 } 5068 switch (len & 3) { 5069 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5070 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 5071 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 5072 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 5073 } 5074 seed = (seed ^ seed << 16) * (len ^ b0); 5075 return seed - (seed >>> 31) + (seed << 33); 5076 } 5077 5078 public static long hash64(long seed, final int[] data) { 5079 if (data == null) return 0L; 5080 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5081 final int len = data.length; 5082 for (int i = 3; i < len; i+=4) { 5083 seed = mum( 5084 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5085 mum(data[i-1] ^ b3, data[i] ^ b4)); 5086 } 5087 switch (len & 3) { 5088 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5089 case 1: seed = mum(seed ^ (data[len-1] >>> 16), b3 ^ (data[len-1] & 0xFFFFL)); break; 5090 case 2: seed = mum(seed ^ data[len-2], b0 ^ data[len-1]); break; 5091 case 3: seed = mum(seed ^ data[len-3], b2 ^ data[len-2]) ^ mum(seed ^ data[len-1], b4); break; 5092 } 5093 seed = (seed ^ seed << 16) * (len ^ b0); 5094 return seed - (seed >>> 31) + (seed << 33); 5095 } 5096 5097 public static long hash64(long seed, final int[] data, final int length) { 5098 if (data == null) return 0L; 5099 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5100 for (int i = 3; i < length; i+=4) { 5101 seed = mum( 5102 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5103 mum(data[i-1] ^ b3, data[i] ^ b4)); 5104 } 5105 switch (length & 3) { 5106 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5107 case 1: seed = mum(seed ^ (data[length-1] >>> 16), b3 ^ (data[length-1] & 0xFFFFL)); break; 5108 case 2: seed = mum(seed ^ data[length-2], b0 ^ data[length-1]); break; 5109 case 3: seed = mum(seed ^ data[length-3], b2 ^ data[length-2]) ^ mum(seed ^ data[length-1], b4); break; 5110 } 5111 seed = (seed ^ seed << 16) * (length ^ b0); 5112 return seed - (seed >>> 31) + (seed << 33); 5113 } 5114 5115 public static long hash64(long seed, final long[] data) { 5116 if (data == null) return 0L; 5117 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5118 long a = seed + b4, b = seed + b3, c = seed + b2, d = seed + b1; 5119 final int len = data.length; 5120 for (int i = 3; i < len; i+=4) { 5121 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 5122 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 5123 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 5124 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 5125 seed += a + b + c + d; 5126 } 5127 seed += b5; 5128 switch (len & 3) { 5129 case 1: seed = wow(seed, b1 ^ data[len-1]); break; 5130 case 2: seed = wow(seed + data[len-2], b2 + data[len-1]); break; 5131 case 3: seed = wow(seed + data[len-3], b2 + data[len-2]) ^ wow(seed + data[len-1], seed ^ b3); break; 5132 } 5133 seed = (seed ^ seed << 16) * (len ^ b0 ^ seed >>> 32); 5134 return seed - (seed >>> 31) + (seed << 33); 5135 } 5136 public static long hash64(long seed, final float[] data) { 5137 if (data == null) return 0L; 5138 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5139 final int len = data.length; 5140 for (int i = 3; i < len; i+=4) { 5141 seed = mum( 5142 mum(floatToIntBits(data[i-3]) ^ b1, floatToIntBits(data[i-2]) ^ b2) + seed, 5143 mum(floatToIntBits(data[i-1]) ^ b3, floatToIntBits(data[i]) ^ b4)); 5144 } 5145 switch (len & 3) { 5146 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5147 case 1: seed = mum(seed ^ (floatToIntBits(data[len-1]) >>> 16), b3 ^ (floatToIntBits(data[len-1]) & 0xFFFFL)); break; 5148 case 2: seed = mum(seed ^ floatToIntBits(data[len-2]), b0 ^ floatToIntBits(data[len-1])); break; 5149 case 3: seed = mum(seed ^ floatToIntBits(data[len-3]), b2 ^ floatToIntBits(data[len-2])) ^ mum(seed ^ floatToIntBits(data[len-1]), b4); break; 5150 } 5151 seed = (seed ^ seed << 16) * (len ^ b0); 5152 return seed - (seed >>> 31) + (seed << 33); 5153 } 5154 public static long hash64(long seed, final double[] data) { 5155 if (data == null) return 0L; 5156 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5157 final int len = data.length; 5158 for (int i = 3; i < len; i+=4) { 5159 seed = mum( 5160 mum(doubleToMixedIntBits(data[i-3]) ^ b1, doubleToMixedIntBits(data[i-2]) ^ b2) + seed, 5161 mum(doubleToMixedIntBits(data[i-1]) ^ b3, doubleToMixedIntBits(data[i]) ^ b4)); 5162 } 5163 switch (len & 3) { 5164 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5165 case 1: seed = mum(seed ^ (doubleToMixedIntBits(data[len-1]) >>> 16), b3 ^ (doubleToMixedIntBits(data[len-1]) & 0xFFFFL)); break; 5166 case 2: seed = mum(seed ^ doubleToMixedIntBits(data[len-2]), b0 ^ doubleToMixedIntBits(data[len-1])); break; 5167 case 3: seed = mum(seed ^ doubleToMixedIntBits(data[len-3]), b2 ^ doubleToMixedIntBits(data[len-2])) ^ mum(seed ^ doubleToMixedIntBits(data[len-1]), b4); break; 5168 } 5169 seed = (seed ^ seed << 16) * (len ^ b0); 5170 return seed - (seed >>> 31) + (seed << 33); 5171 } 5172 5173 /** 5174 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 5175 * 5176 * @param data the char array to hash 5177 * @param start the start of the section to hash (inclusive) 5178 * @param end the end of the section to hash (exclusive) 5179 * @return a 32-bit hash code for the requested section of data 5180 */ 5181 public static long hash64(long seed, final char[] data, final int start, final int end) { 5182 if (data == null || start >= end) 5183 return 0L; 5184 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5185 final int len = Math.min(end, data.length); 5186 for (int i = start + 3; i < len; i+=4) { 5187 seed = mum( 5188 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5189 mum(data[i-1] ^ b3, data[i] ^ b4)); 5190 } 5191 switch (len - start & 3) { 5192 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5193 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 5194 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 5195 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 5196 } 5197 return mum(seed ^ seed << 16, len - start ^ b0); 5198 } 5199 5200 /** 5201 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 5202 * 5203 * @param data the String or other CharSequence to hash 5204 * @param start the start of the section to hash (inclusive) 5205 * @param end the end of the section to hash (exclusive) 5206 * @return a 32-bit hash code for the requested section of data 5207 */ 5208 public static long hash64(long seed, final CharSequence data, final int start, final int end) { 5209 if (data == null || start >= end) 5210 return 0L; 5211 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5212 final int len = Math.min(end, data.length()); 5213 for (int i = start + 3; i < len; i+=4) { 5214 seed = mum( 5215 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 5216 mum(data.charAt(i-1) ^ b3, data.charAt(i) ^ b4)); 5217 } 5218 switch (len - start & 3) { 5219 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5220 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 5221 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 5222 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 5223 } 5224 return mum(seed ^ seed << 16, len - start ^ b0); 5225 } 5226 5227 5228 public static long hash64(long seed, final char[][] data) { 5229 if (data == null) return 0L; 5230 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5231 final int len = data.length; 5232 for (int i = 3; i < len; i+=4) { 5233 seed = mum( 5234 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5235 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5236 } 5237 int t; 5238 switch (len & 3) { 5239 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5240 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5241 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5242 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5243 } 5244 seed = (seed ^ seed << 16) * (len ^ b0); 5245 return seed - (seed >>> 31) + (seed << 33); 5246 } 5247 5248 public static long hash64(long seed, final int[][] data) { 5249 if (data == null) return 0L; 5250 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5251 final int len = data.length; 5252 for (int i = 3; i < len; i+=4) { 5253 seed = mum( 5254 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5255 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5256 } 5257 int t; 5258 switch (len & 3) { 5259 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5260 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5261 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5262 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5263 } 5264 seed = (seed ^ seed << 16) * (len ^ b0); 5265 return seed - (seed >>> 31) + (seed << 33); 5266 } 5267 5268 public static long hash64(long seed, final long[][] data) { 5269 if (data == null) return 0L; 5270 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5271 final int len = data.length; 5272 for (int i = 3; i < len; i+=4) { 5273 seed = mum( 5274 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5275 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5276 } 5277 int t; 5278 switch (len & 3) { 5279 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5280 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5281 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5282 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5283 } 5284 seed = (seed ^ seed << 16) * (len ^ b0); 5285 return seed - (seed >>> 31) + (seed << 33); 5286 } 5287 5288 public static long hash64(long seed, final CharSequence[] data) { 5289 if (data == null) return 0L; 5290 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5291 final int len = data.length; 5292 for (int i = 3; i < len; i+=4) { 5293 seed = mum( 5294 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5295 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5296 } 5297 int t; 5298 switch (len & 3) { 5299 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5300 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5301 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5302 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5303 } 5304 seed = (seed ^ seed << 16) * (len ^ b0); 5305 return seed - (seed >>> 31) + (seed << 33); 5306 } 5307 5308 public static long hash64(long seed, final CharSequence[]... data) { 5309 if (data == null) return 0L; 5310 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5311 final int len = data.length; 5312 for (int i = 3; i < len; i+=4) { 5313 seed = mum( 5314 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5315 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5316 } 5317 int t; 5318 switch (len & 3) { 5319 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5320 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5321 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5322 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5323 } 5324 seed = (seed ^ seed << 16) * (len ^ b0); 5325 return seed - (seed >>> 31) + (seed << 33); 5326 } 5327 5328 public static long hash64(long seed, final Iterable<? extends CharSequence> data) { 5329 if (data == null) return 0L; 5330 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5331 final Iterator<? extends CharSequence> it = data.iterator(); 5332 int len = 0; 5333 while (it.hasNext()) 5334 { 5335 ++len; 5336 seed = mum( 5337 mum(hash(seed, it.next()) ^ b1, (it.hasNext() ? hash(seed, it.next()) ^ b2 ^ ++len : b2)) + seed, 5338 mum((it.hasNext() ? hash(seed, it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(seed, it.next()) ^ b4 ^ ++len : b4))); 5339 } 5340 seed = (seed ^ seed << 16) * (len ^ b0); 5341 return seed - (seed >>> 31) + (seed << 33); 5342 } 5343 5344 public static long hash64(long seed, final List<? extends CharSequence> data) { 5345 if (data == null) return 0L; 5346 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5347 final int len = data.size(); 5348 for (int i = 3; i < len; i+=4) { 5349 seed = mum( 5350 mum(hash(seed, data.get(i-3)) ^ b1, hash(seed, data.get(i-2)) ^ b2) + seed, 5351 mum(hash(seed, data.get(i-1)) ^ b3, hash(seed, data.get(i )) ^ b4)); 5352 } 5353 int t; 5354 switch (len & 3) { 5355 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5356 case 1: seed = mum(seed ^((t = hash(seed, data.get(len-1))) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5357 case 2: seed = mum(seed ^ hash(seed, data.get(len-2)), b0 ^ hash(seed, data.get(len-1))); break; 5358 case 3: seed = mum(seed ^ hash(seed, data.get(len-3)), b2 ^ hash(seed, data.get(len-2))) ^ mum(seed ^ hash(seed, data.get(len-1)), b4); break; 5359 } 5360 seed = (seed ^ seed << 16) * (len ^ b0); 5361 return seed - (seed >>> 31) + (seed << 33); 5362 5363 } 5364 5365 public static long hash64(long seed, final Object[] data) { 5366 if (data == null) return 0L; 5367 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5368 final int len = data.length; 5369 for (int i = 3; i < len; i+=4) { 5370 seed = mum( 5371 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5372 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5373 } 5374 int t; 5375 switch (len & 3) { 5376 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5377 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5378 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5379 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5380 } 5381 seed = (seed ^ seed << 16) * (len ^ b0); 5382 return seed - (seed >>> 31) + (seed << 33); 5383 } 5384 5385 public static long hash64(long seed, final Object data) { 5386 if (data == null) 5387 return 0; 5388 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5389 final long h = (data.hashCode() + seed) * 0x9E3779B97F4A7C15L; 5390 return h - (h >>> 31) + (h << 33); 5391 } 5392 5393 5394 public static int hash(long seed, final boolean[] data) { 5395 if (data == null) return 0; 5396 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5397 final int len = data.length; 5398 for (int i = 3; i < len; i+=4) { 5399 seed = mum( 5400 mum((data[i-3] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b1, (data[i-2] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b2) + seed, 5401 mum((data[i-1] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b3, (data[i] ? 0x9E3779B9L : 0x7F4A7C15L) ^ b4)); 5402 } 5403 switch (len & 3) { 5404 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5405 case 1: seed = mum(seed ^ (data[len-1] ? 0x9E37L : 0x7F4AL), b3 ^ (data[len-1] ? 0x79B9L : 0x7C15L)); break; 5406 case 2: seed = mum(seed ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L), b0 ^ (data[len-1] ? 0x9E3779B9L : 0x7F4A7C15L)); break; 5407 case 3: seed = mum(seed ^ (data[len-3] ? 0x9E3779B9L : 0x7F4A7C15L), b2 ^ (data[len-2] ? 0x9E3779B9L : 0x7F4A7C15L)) ^ mum(seed ^ (data[len-1] ? 0x9E3779B9 : 0x7F4A7C15), b4); break; 5408 } 5409 return (int) mum(seed ^ seed << 16, len ^ b0); 5410 } 5411 public static int hash(long seed, final byte[] data) { 5412 if (data == null) return 0; 5413 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5414 final int len = data.length; 5415 for (int i = 3; i < len; i+=4) { 5416 seed = mum( 5417 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5418 mum(data[i-1] ^ b3, data[i] ^ b4)); 5419 } 5420 switch (len & 3) { 5421 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5422 case 1: seed = mum(seed ^ b2, b1 ^ data[len-1]); break; 5423 case 2: seed = mum(seed ^ b3, data[len-2] ^ data[len-1] << 8 ^ b4); break; 5424 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 8, b2 ^ data[len-1]); break; 5425 } 5426 return (int) mum(seed ^ seed << 16, len ^ b0); 5427 } 5428 5429 public static int hash(long seed, final short[] data) { 5430 if (data == null) return 0; 5431 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5432 final int len = data.length; 5433 for (int i = 3; i < len; i+=4) { 5434 seed = mum( 5435 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5436 mum(data[i-1] ^ b3, data[i] ^ b4)); 5437 } 5438 switch (len & 3) { 5439 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5440 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 5441 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 5442 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 5443 } 5444 return (int) mum(seed ^ seed << 16, len ^ b0); 5445 } 5446 5447 public static int hash(long seed, final char[] data) { 5448 if (data == null) return 0; 5449 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5450 final int len = data.length; 5451 for (int i = 3; i < len; i+=4) { 5452 seed = mum( 5453 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5454 mum(data[i-1] ^ b3, data[i] ^ b4)); 5455 } 5456 switch (len & 3) { 5457 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5458 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 5459 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 5460 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 5461 } 5462 return (int) mum(seed ^ seed << 16, len ^ b0); 5463 } 5464 5465 public static int hash(long seed, final CharSequence data) { 5466 if (data == null) return 0; 5467 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5468 final int len = data.length(); 5469 for (int i = 3; i < len; i+=4) { 5470 seed = mum( 5471 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 5472 mum(data.charAt(i-1) ^ b3, data.charAt(i ) ^ b4)); 5473 } 5474 switch (len & 3) { 5475 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5476 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 5477 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 5478 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 5479 } 5480 return (int) mum(seed ^ seed << 16, len ^ b0); 5481 } 5482 public static int hash(long seed, final int[] data) { 5483 if (data == null) return 0; 5484 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5485 final int len = data.length; 5486 for (int i = 3; i < len; i+=4) { 5487 seed = mum( 5488 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5489 mum(data[i-1] ^ b3, data[i] ^ b4)); 5490 } 5491 switch (len & 3) { 5492 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5493 case 1: seed = mum(seed ^ (data[len-1] >>> 16), b3 ^ (data[len-1] & 0xFFFFL)); break; 5494 case 2: seed = mum(seed ^ data[len-2], b0 ^ data[len-1]); break; 5495 case 3: seed = mum(seed ^ data[len-3], b2 ^ data[len-2]) ^ mum(seed ^ data[len-1], b4); break; 5496 } 5497 return (int) mum(seed ^ seed << 16, len ^ b0); 5498 } 5499 public static int hash(long seed, final int[] data, final int length) { 5500 if (data == null) return 0; 5501 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5502 for (int i = 3; i < length; i+=4) { 5503 seed = mum( 5504 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5505 mum(data[i-1] ^ b3, data[i] ^ b4)); 5506 } 5507 switch (length & 3) { 5508 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5509 case 1: seed = mum(seed ^ (data[length-1] >>> 16), b3 ^ (data[length-1] & 0xFFFFL)); break; 5510 case 2: seed = mum(seed ^ data[length-2], b0 ^ data[length-1]); break; 5511 case 3: seed = mum(seed ^ data[length-3], b2 ^ data[length-2]) ^ mum(seed ^ data[length-1], b4); break; 5512 } 5513 return (int) mum(seed ^ seed << 16, length ^ b0); 5514 } 5515 5516 public static int hash(long seed, final long[] data) { 5517 if (data == null) return 0; 5518 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5519 long a = seed + b4, b = seed + b3, c = seed + b2, d = seed + b1; 5520 final int len = data.length; 5521 for (int i = 3; i < len; i+=4) { 5522 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 5523 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 5524 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 5525 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 5526 seed += a + b + c + d; 5527 } 5528 seed += b5; 5529 switch (len & 3) { 5530 case 1: seed = wow(seed, b1 ^ data[len-1]); break; 5531 case 2: seed = wow(seed + data[len-2], b2 + data[len-1]); break; 5532 case 3: seed = wow(seed + data[len-3], b2 + data[len-2]) ^ wow(seed + data[len-1], seed ^ b3); break; 5533 } 5534 seed = (seed ^ seed << 16) * (len ^ b0 ^ seed >>> 32); 5535 return (int)(seed - (seed >>> 32)); 5536 } 5537 5538 public static int hash(long seed, final float[] data) { 5539 if (data == null) return 0; 5540 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5541 final int len = data.length; 5542 for (int i = 3; i < len; i+=4) { 5543 seed = mum( 5544 mum(floatToIntBits(data[i-3]) ^ b1, floatToIntBits(data[i-2]) ^ b2) + seed, 5545 mum(floatToIntBits(data[i-1]) ^ b3, floatToIntBits(data[i]) ^ b4)); 5546 } 5547 switch (len & 3) { 5548 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5549 case 1: seed = mum(seed ^ (floatToIntBits(data[len-1]) >>> 16), b3 ^ (floatToIntBits(data[len-1]) & 0xFFFFL)); break; 5550 case 2: seed = mum(seed ^ floatToIntBits(data[len-2]), b0 ^ floatToIntBits(data[len-1])); break; 5551 case 3: seed = mum(seed ^ floatToIntBits(data[len-3]), b2 ^ floatToIntBits(data[len-2])) ^ mum(seed ^ floatToIntBits(data[len-1]), b4); break; 5552 } 5553 return (int) mum(seed ^ seed << 16, len ^ b0); 5554 } 5555 public static int hash(long seed, final double[] data) { 5556 if (data == null) return 0; 5557 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5558 final int len = data.length; 5559 for (int i = 3; i < len; i+=4) { 5560 seed = mum( 5561 mum(doubleToMixedIntBits(data[i-3]) ^ b1, doubleToMixedIntBits(data[i-2]) ^ b2) + seed, 5562 mum(doubleToMixedIntBits(data[i-1]) ^ b3, doubleToMixedIntBits(data[i]) ^ b4)); 5563 } 5564 switch (len & 3) { 5565 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5566 case 1: seed = mum(seed ^ (doubleToMixedIntBits(data[len-1]) >>> 16), b3 ^ (doubleToMixedIntBits(data[len-1]) & 0xFFFFL)); break; 5567 case 2: seed = mum(seed ^ doubleToMixedIntBits(data[len-2]), b0 ^ doubleToMixedIntBits(data[len-1])); break; 5568 case 3: seed = mum(seed ^ doubleToMixedIntBits(data[len-3]), b2 ^ doubleToMixedIntBits(data[len-2])) ^ mum(seed ^ doubleToMixedIntBits(data[len-1]), b4); break; 5569 } 5570 return (int) mum(seed ^ seed << 16, len ^ b0); 5571 } 5572 5573 /** 5574 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 5575 * 5576 * @param data the char array to hash 5577 * @param start the start of the section to hash (inclusive) 5578 * @param end the end of the section to hash (exclusive) 5579 * @return a 32-bit hash code for the requested section of data 5580 */ 5581 public static int hash(long seed, final char[] data, final int start, final int end) { 5582 if (data == null || start >= end) 5583 return 0; 5584 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5585 final int len = Math.min(end, data.length); 5586 for (int i = start + 3; i < len; i+=4) { 5587 seed = mum( 5588 mum(data[i-3] ^ b1, data[i-2] ^ b2) + seed, 5589 mum(data[i-1] ^ b3, data[i] ^ b4)); 5590 } 5591 switch (len - start & 3) { 5592 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5593 case 1: seed = mum(seed ^ b3, b4 ^ data[len-1]); break; 5594 case 2: seed = mum(seed ^ data[len-2], b3 ^ data[len-1]); break; 5595 case 3: seed = mum(seed ^ data[len-3] ^ data[len-2] << 16, b1 ^ data[len-1]); break; 5596 } 5597 return (int) mum(seed ^ seed << 16, len - start ^ b0); 5598 } 5599 5600 /** 5601 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 5602 * 5603 * @param data the String or other CharSequence to hash 5604 * @param start the start of the section to hash (inclusive) 5605 * @param end the end of the section to hash (exclusive) 5606 * @return a 32-bit hash code for the requested section of data 5607 */ 5608 public static int hash(long seed, final CharSequence data, final int start, final int end) { 5609 if (data == null || start >= end) 5610 return 0; 5611 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5612 final int len = Math.min(end, data.length()); 5613 for (int i = start + 3; i < len; i+=4) { 5614 seed = mum( 5615 mum(data.charAt(i-3) ^ b1, data.charAt(i-2) ^ b2) + seed, 5616 mum(data.charAt(i-1) ^ b3, data.charAt(i) ^ b4)); 5617 } 5618 switch (len - start & 3) { 5619 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5620 case 1: seed = mum(seed ^ b3, b4 ^ data.charAt(len-1)); break; 5621 case 2: seed = mum(seed ^ data.charAt(len-2), b3 ^ data.charAt(len-1)); break; 5622 case 3: seed = mum(seed ^ data.charAt(len-3) ^ data.charAt(len-2) << 16, b1 ^ data.charAt(len-1)); break; 5623 } 5624 return (int) mum(seed ^ seed << 16, len - start ^ b0); 5625 } 5626 5627 5628 public static int hash(long seed, final char[][] data) { 5629 if (data == null) return 0; 5630 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5631 final int len = data.length; 5632 for (int i = 3; i < len; i+=4) { 5633 seed = mum( 5634 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5635 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5636 } 5637 int t; 5638 switch (len & 3) { 5639 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5640 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5641 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5642 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5643 } 5644 return (int) mum(seed ^ seed << 16, len ^ b0); 5645 } 5646 5647 public static int hash(long seed, final int[][] data) { 5648 if (data == null) return 0; 5649 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5650 final int len = data.length; 5651 for (int i = 3; i < len; i+=4) { 5652 seed = mum( 5653 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5654 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5655 } 5656 int t; 5657 switch (len & 3) { 5658 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5659 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5660 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5661 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5662 } 5663 return (int) mum(seed ^ seed << 16, len ^ b0); 5664 } 5665 5666 public static int hash(long seed, final long[][] data) { 5667 if (data == null) return 0; 5668 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5669 final int len = data.length; 5670 for (int i = 3; i < len; i+=4) { 5671 seed = mum( 5672 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5673 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5674 } 5675 int t; 5676 switch (len & 3) { 5677 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5678 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5679 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5680 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5681 } 5682 return (int) mum(seed ^ seed << 16, len ^ b0); 5683 } 5684 5685 public static int hash(long seed, final CharSequence[] data) { 5686 if (data == null) return 0; 5687 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5688 final int len = data.length; 5689 for (int i = 3; i < len; i+=4) { 5690 seed = mum( 5691 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5692 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5693 } 5694 int t; 5695 switch (len & 3) { 5696 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5697 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5698 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5699 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5700 } 5701 return (int) mum(seed ^ seed << 16, len ^ b0); 5702 } 5703 5704 public static int hash(long seed, final CharSequence[]... data) { 5705 if (data == null) return 0; 5706 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5707 final int len = data.length; 5708 for (int i = 3; i < len; i+=4) { 5709 seed = mum( 5710 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5711 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5712 } 5713 int t; 5714 switch (len & 3) { 5715 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5716 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5717 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5718 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5719 } 5720 return (int) mum(seed ^ seed << 16, len ^ b0); 5721 } 5722 5723 public static int hash(long seed, final Iterable<? extends CharSequence> data) { 5724 if (data == null) return 0; 5725 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5726 final Iterator<? extends CharSequence> it = data.iterator(); 5727 int len = 0; 5728 while (it.hasNext()) 5729 { 5730 ++len; 5731 seed = mum( 5732 mum(hash(seed, it.next()) ^ b1, (it.hasNext() ? hash(seed, it.next()) ^ b2 ^ ++len : b2)) + seed, 5733 mum((it.hasNext() ? hash(seed, it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(seed, it.next()) ^ b4 ^ ++len : b4))); 5734 } 5735 return (int) mum(seed ^ seed << 16, len ^ b0); 5736 } 5737 5738 public static int hash(long seed, final List<? extends CharSequence> data) { 5739 if (data == null) return 0; 5740 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5741 final int len = data.size(); 5742 for (int i = 3; i < len; i+=4) { 5743 seed = mum( 5744 mum(hash(seed, data.get(i-3)) ^ b1, hash(seed, data.get(i-2)) ^ b2) + seed, 5745 mum(hash(seed, data.get(i-1)) ^ b3, hash(seed, data.get(i )) ^ b4)); 5746 } 5747 int t; 5748 switch (len & 3) { 5749 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5750 case 1: seed = mum(seed ^((t = hash(seed, data.get(len-1))) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5751 case 2: seed = mum(seed ^ hash(seed, data.get(len-2)), b0 ^ hash(seed, data.get(len-1))); break; 5752 case 3: seed = mum(seed ^ hash(seed, data.get(len-3)), b2 ^ hash(seed, data.get(len-2))) ^ mum(seed ^ hash(seed, data.get(len-1)), b4); break; 5753 } 5754 return (int) mum(seed ^ seed << 16, len ^ b0); 5755 } 5756 5757 public static int hash(long seed, final Object[] data) { 5758 if (data == null) return 0; 5759 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5760 final int len = data.length; 5761 for (int i = 3; i < len; i+=4) { 5762 seed = mum( 5763 mum(hash(seed, data[i-3]) ^ b1, hash(seed, data[i-2]) ^ b2) + seed, 5764 mum(hash(seed, data[i-1]) ^ b3, hash(seed, data[i ]) ^ b4)); 5765 } 5766 int t; 5767 switch (len & 3) { 5768 case 0: seed = mum(b1 ^ seed, b4 + seed); break; 5769 case 1: seed = mum(seed ^((t = hash(seed, data[len-1])) >>> 16), b3 ^ (t & 0xFFFFL)); break; 5770 case 2: seed = mum(seed ^ hash(seed, data[len-2]), b0 ^ hash(seed, data[len-1])); break; 5771 case 3: seed = mum(seed ^ hash(seed, data[len-3]), b2 ^ hash(seed, data[len-2])) ^ mum(seed ^ hash(seed, data[len-1]), b4); break; 5772 } 5773 return (int) mum(seed ^ seed << 16, len ^ b0); 5774 } 5775 5776 public static int hash(long seed, final Object data) { 5777 if (data == null) 5778 return 0; 5779 seed += b1; seed ^= seed >>> 23 ^ seed >>> 48 ^ seed << 7 ^ seed << 53; 5780 return (int)((data.hashCode() + seed) * 0x9E3779B97F4A7C15L >>> 32); 5781 } 5782 5783 5784 } 5785 5786 /** 5787 * Like Yolk, this is a class for hash functors, each an object with a 64-bit long seed. It uses an odd-but-fast 5788 * SIMD-friendly technique when hashing 32-bit items or smaller, and falls back to Yolk's algorithm when hashing 5789 * long values. If you are mainly hashing int arrays, short arrays, or byte arrays, this is probably the fastest 5790 * hash here unless the arrays are small (it outperforms all of the other hashes here on int arrays when those 5791 * arrays have length 50, and probably is faster than some sooner than that). Notably, on arrays 50 or longer this 5792 * runs in very close to half the time of {@link Arrays#hashCode(int[])}. This passes SMHasher for at least 64-bit 5793 * output. Has a lot of predefined functors (192, named after 24 Greek letters and 72 Goetic demons, see 5794 * <a href="https://en.wikipedia.org/wiki/Lesser_Key_of_Solomon#The_Seventy-Two_Demons">Wikipedia for the demons</a>, 5795 * in both lower case and lower case with a trailing underscore). You probably want to use {@link #predefined} 5796 * instead of wrangling demon names; you can always choose an element from predefined with a 7-bit number, and there 5797 * are 64 numbers outside that range so you can choose any of those when a functor must be different. 5798 * <br> 5799 * This hash is much more effective with large inputs because it takes advantage of HotSpot's optimizations for code 5800 * that looks like a dot product over part of an array. The general concept for this hash came from the "Unrolled" 5801 * hash in <a href="https://richardstartin.github.io/posts/collecting-rocks-and-benchmarks">one of Richard Startin's 5802 * blog posts</a>, which traces back to 5803 * <a href="http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-September/028898.html">Peter Levart posting a 5804 * related improvement on String.hashCode()</a> in 2014. This isn't as fast as Startin's "Vectorized" hash, but this 5805 * works on variable array lengths and also passes SMHasher. 5806 * <br> 5807 * The name curlup comes from an M.C. Escher painting of a creature, whose name translates to curl-up, that could 5808 * walk on six legs to climb stairs, or roll at high speeds when the conditions were right. 5809 */ 5810 public static final class Curlup { 5811 private final long seed; 5812 5813 public Curlup(){ 5814 this.seed = 0xC4CEB9FE1A85EC53L; 5815 } 5816 public Curlup(long seed) 5817 { 5818 this.seed = randomize(seed); 5819 } 5820 5821 /** 5822 * Very similar to Pelican and related unary hashes; uses "xor rotate xor rotate" as an early step to mix any 5823 * clustered bits all around the result, then the rest is like MurmurHash3's mixer. 5824 * @param seed any long; there is no fix point at 0 5825 * @return any long 5826 */ 5827 public static long randomize(long seed) { 5828 seed ^= (seed << 41 | seed >>> 23) ^ (seed << 17 | seed >>> 47) ^ 0xCB9C59B3F9F87D4DL; 5829 seed *= 0x369DEA0F31A53F85L; 5830 seed ^= seed >>> 31; 5831 seed *= 0xDB4F0B9175AE2165L; 5832 return seed ^ seed >>> 28; 5833 } 5834 5835 public Curlup(final CharSequence seed) 5836 { 5837 this(Water.hash64(seed)); 5838 } 5839 5840 public static final Curlup alpha = new Curlup("alpha"), beta = new Curlup("beta"), gamma = new Curlup("gamma"), 5841 delta = new Curlup("delta"), epsilon = new Curlup("epsilon"), zeta = new Curlup("zeta"), 5842 eta = new Curlup("eta"), theta = new Curlup("theta"), iota = new Curlup("iota"), 5843 kappa = new Curlup("kappa"), lambda = new Curlup("lambda"), mu = new Curlup("mu"), 5844 nu = new Curlup("nu"), xi = new Curlup("xi"), omicron = new Curlup("omicron"), pi = new Curlup("pi"), 5845 rho = new Curlup("rho"), sigma = new Curlup("sigma"), tau = new Curlup("tau"), 5846 upsilon = new Curlup("upsilon"), phi = new Curlup("phi"), chi = new Curlup("chi"), psi = new Curlup("psi"), 5847 omega = new Curlup("omega"), 5848 alpha_ = new Curlup("ALPHA"), beta_ = new Curlup("BETA"), gamma_ = new Curlup("GAMMA"), 5849 delta_ = new Curlup("DELTA"), epsilon_ = new Curlup("EPSILON"), zeta_ = new Curlup("ZETA"), 5850 eta_ = new Curlup("ETA"), theta_ = new Curlup("THETA"), iota_ = new Curlup("IOTA"), 5851 kappa_ = new Curlup("KAPPA"), lambda_ = new Curlup("LAMBDA"), mu_ = new Curlup("MU"), 5852 nu_ = new Curlup("NU"), xi_ = new Curlup("XI"), omicron_ = new Curlup("OMICRON"), pi_ = new Curlup("PI"), 5853 rho_ = new Curlup("RHO"), sigma_ = new Curlup("SIGMA"), tau_ = new Curlup("TAU"), 5854 upsilon_ = new Curlup("UPSILON"), phi_ = new Curlup("PHI"), chi_ = new Curlup("CHI"), psi_ = new Curlup("PSI"), 5855 omega_ = new Curlup("OMEGA"), 5856 baal = new Curlup("baal"), agares = new Curlup("agares"), vassago = new Curlup("vassago"), samigina = new Curlup("samigina"), 5857 marbas = new Curlup("marbas"), valefor = new Curlup("valefor"), amon = new Curlup("amon"), barbatos = new Curlup("barbatos"), 5858 paimon = new Curlup("paimon"), buer = new Curlup("buer"), gusion = new Curlup("gusion"), sitri = new Curlup("sitri"), 5859 beleth = new Curlup("beleth"), leraje = new Curlup("leraje"), eligos = new Curlup("eligos"), zepar = new Curlup("zepar"), 5860 botis = new Curlup("botis"), bathin = new Curlup("bathin"), sallos = new Curlup("sallos"), purson = new Curlup("purson"), 5861 marax = new Curlup("marax"), ipos = new Curlup("ipos"), aim = new Curlup("aim"), naberius = new Curlup("naberius"), 5862 glasya_labolas = new Curlup("glasya_labolas"), bune = new Curlup("bune"), ronove = new Curlup("ronove"), berith = new Curlup("berith"), 5863 astaroth = new Curlup("astaroth"), forneus = new Curlup("forneus"), foras = new Curlup("foras"), asmoday = new Curlup("asmoday"), 5864 gaap = new Curlup("gaap"), furfur = new Curlup("furfur"), marchosias = new Curlup("marchosias"), stolas = new Curlup("stolas"), 5865 phenex = new Curlup("phenex"), halphas = new Curlup("halphas"), malphas = new Curlup("malphas"), raum = new Curlup("raum"), 5866 focalor = new Curlup("focalor"), vepar = new Curlup("vepar"), sabnock = new Curlup("sabnock"), shax = new Curlup("shax"), 5867 vine = new Curlup("vine"), bifrons = new Curlup("bifrons"), vual = new Curlup("vual"), haagenti = new Curlup("haagenti"), 5868 crocell = new Curlup("crocell"), furcas = new Curlup("furcas"), balam = new Curlup("balam"), alloces = new Curlup("alloces"), 5869 caim = new Curlup("caim"), murmur = new Curlup("murmur"), orobas = new Curlup("orobas"), gremory = new Curlup("gremory"), 5870 ose = new Curlup("ose"), amy = new Curlup("amy"), orias = new Curlup("orias"), vapula = new Curlup("vapula"), 5871 zagan = new Curlup("zagan"), valac = new Curlup("valac"), andras = new Curlup("andras"), flauros = new Curlup("flauros"), 5872 andrealphus = new Curlup("andrealphus"), kimaris = new Curlup("kimaris"), amdusias = new Curlup("amdusias"), belial = new Curlup("belial"), 5873 decarabia = new Curlup("decarabia"), seere = new Curlup("seere"), dantalion = new Curlup("dantalion"), andromalius = new Curlup("andromalius"), 5874 baal_ = new Curlup("BAAL"), agares_ = new Curlup("AGARES"), vassago_ = new Curlup("VASSAGO"), samigina_ = new Curlup("SAMIGINA"), 5875 marbas_ = new Curlup("MARBAS"), valefor_ = new Curlup("VALEFOR"), amon_ = new Curlup("AMON"), barbatos_ = new Curlup("BARBATOS"), 5876 paimon_ = new Curlup("PAIMON"), buer_ = new Curlup("BUER"), gusion_ = new Curlup("GUSION"), sitri_ = new Curlup("SITRI"), 5877 beleth_ = new Curlup("BELETH"), leraje_ = new Curlup("LERAJE"), eligos_ = new Curlup("ELIGOS"), zepar_ = new Curlup("ZEPAR"), 5878 botis_ = new Curlup("BOTIS"), bathin_ = new Curlup("BATHIN"), sallos_ = new Curlup("SALLOS"), purson_ = new Curlup("PURSON"), 5879 marax_ = new Curlup("MARAX"), ipos_ = new Curlup("IPOS"), aim_ = new Curlup("AIM"), naberius_ = new Curlup("NABERIUS"), 5880 glasya_labolas_ = new Curlup("GLASYA_LABOLAS"), bune_ = new Curlup("BUNE"), ronove_ = new Curlup("RONOVE"), berith_ = new Curlup("BERITH"), 5881 astaroth_ = new Curlup("ASTAROTH"), forneus_ = new Curlup("FORNEUS"), foras_ = new Curlup("FORAS"), asmoday_ = new Curlup("ASMODAY"), 5882 gaap_ = new Curlup("GAAP"), furfur_ = new Curlup("FURFUR"), marchosias_ = new Curlup("MARCHOSIAS"), stolas_ = new Curlup("STOLAS"), 5883 phenex_ = new Curlup("PHENEX"), halphas_ = new Curlup("HALPHAS"), malphas_ = new Curlup("MALPHAS"), raum_ = new Curlup("RAUM"), 5884 focalor_ = new Curlup("FOCALOR"), vepar_ = new Curlup("VEPAR"), sabnock_ = new Curlup("SABNOCK"), shax_ = new Curlup("SHAX"), 5885 vine_ = new Curlup("VINE"), bifrons_ = new Curlup("BIFRONS"), vual_ = new Curlup("VUAL"), haagenti_ = new Curlup("HAAGENTI"), 5886 crocell_ = new Curlup("CROCELL"), furcas_ = new Curlup("FURCAS"), balam_ = new Curlup("BALAM"), alloces_ = new Curlup("ALLOCES"), 5887 caim_ = new Curlup("CAIM"), murmur_ = new Curlup("MURMUR"), orobas_ = new Curlup("OROBAS"), gremory_ = new Curlup("GREMORY"), 5888 ose_ = new Curlup("OSE"), amy_ = new Curlup("AMY"), orias_ = new Curlup("ORIAS"), vapula_ = new Curlup("VAPULA"), 5889 zagan_ = new Curlup("ZAGAN"), valac_ = new Curlup("VALAC"), andras_ = new Curlup("ANDRAS"), flauros_ = new Curlup("FLAUROS"), 5890 andrealphus_ = new Curlup("ANDREALPHUS"), kimaris_ = new Curlup("KIMARIS"), amdusias_ = new Curlup("AMDUSIAS"), belial_ = new Curlup("BELIAL"), 5891 decarabia_ = new Curlup("DECARABIA"), seere_ = new Curlup("SEERE"), dantalion_ = new Curlup("DANTALION"), andromalius_ = new Curlup("ANDROMALIUS") 5892 ; 5893 /** 5894 * Has a length of 192, which may be relevant if automatically choosing a predefined hash functor. 5895 */ 5896 public static final Curlup[] predefined = new Curlup[]{alpha, beta, gamma, delta, epsilon, zeta, eta, theta, iota, 5897 kappa, lambda, mu, nu, xi, omicron, pi, rho, sigma, tau, upsilon, phi, chi, psi, omega, 5898 alpha_, beta_, gamma_, delta_, epsilon_, zeta_, eta_, theta_, iota_, 5899 kappa_, lambda_, mu_, nu_, xi_, omicron_, pi_, rho_, sigma_, tau_, upsilon_, phi_, chi_, psi_, omega_, 5900 baal, agares, vassago, samigina, marbas, valefor, amon, barbatos, 5901 paimon, buer, gusion, sitri, beleth, leraje, eligos, zepar, 5902 botis, bathin, sallos, purson, marax, ipos, aim, naberius, 5903 glasya_labolas, bune, ronove, berith, astaroth, forneus, foras, asmoday, 5904 gaap, furfur, marchosias, stolas, phenex, halphas, malphas, raum, 5905 focalor, vepar, sabnock, shax, vine, bifrons, vual, haagenti, 5906 crocell, furcas, balam, alloces, caim, murmur, orobas, gremory, 5907 ose, amy, orias, vapula, zagan, valac, andras, flauros, 5908 andrealphus, kimaris, amdusias, belial, decarabia, seere, dantalion, andromalius, 5909 baal_, agares_, vassago_, samigina_, marbas_, valefor_, amon_, barbatos_, 5910 paimon_, buer_, gusion_, sitri_, beleth_, leraje_, eligos_, zepar_, 5911 botis_, bathin_, sallos_, purson_, marax_, ipos_, aim_, naberius_, 5912 glasya_labolas_, bune_, ronove_, berith_, astaroth_, forneus_, foras_, asmoday_, 5913 gaap_, furfur_, marchosias_, stolas_, phenex_, halphas_, malphas_, raum_, 5914 focalor_, vepar_, sabnock_, shax_, vine_, bifrons_, vual_, haagenti_, 5915 crocell_, furcas_, balam_, alloces_, caim_, murmur_, orobas_, gremory_, 5916 ose_, amy_, orias_, vapula_, zagan_, valac_, andras_, flauros_, 5917 andrealphus_, kimaris_, amdusias_, belial_, decarabia_, seere_, dantalion_, andromalius_}; 5918 5919 5920 public long hash64(final boolean[] data) { 5921 if (data == null) return 0; 5922 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 5923 int i = 0; 5924 for (; i + 7 < data.length; i += 8) { 5925 result = result * 0xEBEDEED9D803C815L 5926 + (data[i] ? 0xD96EB1A810CAAF5FL : 0xCAAF5FD96EB1A810L) 5927 + (data[i + 1] ? 0xC862B36DAF790DD5L : 0x790DD5C862B36DAFL) 5928 + (data[i + 2] ? 0xB8ACD90C142FE10BL : 0x2FE10BB8ACD90C14L) 5929 + (data[i + 3] ? 0xAA324F90DED86B69L : 0xD86B69AA324F90DEL) 5930 + (data[i + 4] ? 0x9CDA5E693FEA10AFL : 0xEA10AF9CDA5E693FL) 5931 + (data[i + 5] ? 0x908E3D2C82567A73L : 0x567A73908E3D2C82L) 5932 + (data[i + 6] ? 0x8538ECB5BD456EA3L : 0x456EA38538ECB5BDL) 5933 + (data[i + 7] ? 0xD1B54A32D192ED03L : 0x92ED03D1B54A32D1L) 5934 ; 5935 } 5936 for (; i < data.length; i++) { 5937 result = 0x9E3779B97F4A7C15L * result + (data[i] ? 0xEBEDEED9D803C815L : 0xD9D803C815EBEDEEL); 5938 } 5939 result *= 0x94D049BB133111EBL; 5940 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 5941 result *= 0x369DEA0F31A53F85L; 5942 result ^= result >>> 31; 5943 result *= 0xDB4F0B9175AE2165L; 5944 return (result ^ result >>> 28); 5945 } 5946 public long hash64(final byte[] data) { 5947 if (data == null) return 0; 5948 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 5949 int i = 0; 5950 for (; i + 7 < data.length; i += 8) { 5951 result = 0xEBEDEED9D803C815L * result 5952 + 0xD96EB1A810CAAF5FL * data[i] 5953 + 0xC862B36DAF790DD5L * data[i + 1] 5954 + 0xB8ACD90C142FE10BL * data[i + 2] 5955 + 0xAA324F90DED86B69L * data[i + 3] 5956 + 0x9CDA5E693FEA10AFL * data[i + 4] 5957 + 0x908E3D2C82567A73L * data[i + 5] 5958 + 0x8538ECB5BD456EA3L * data[i + 6] 5959 + 0xD1B54A32D192ED03L * data[i + 7] 5960 ; 5961 } 5962 for (; i < data.length; i++) { 5963 result = 0x9E3779B97F4A7C15L * result + data[i]; 5964 } 5965 result *= 0x94D049BB133111EBL; 5966 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 5967 result *= 0x369DEA0F31A53F85L; 5968 result ^= result >>> 31; 5969 result *= 0xDB4F0B9175AE2165L; 5970 return (result ^ result >>> 28); 5971 } 5972 5973 public long hash64(final short[] data) { 5974 if (data == null) return 0; 5975 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 5976 int i = 0; 5977 for (; i + 7 < data.length; i += 8) { 5978 result = 0xEBEDEED9D803C815L * result 5979 + 0xD96EB1A810CAAF5FL * data[i] 5980 + 0xC862B36DAF790DD5L * data[i + 1] 5981 + 0xB8ACD90C142FE10BL * data[i + 2] 5982 + 0xAA324F90DED86B69L * data[i + 3] 5983 + 0x9CDA5E693FEA10AFL * data[i + 4] 5984 + 0x908E3D2C82567A73L * data[i + 5] 5985 + 0x8538ECB5BD456EA3L * data[i + 6] 5986 + 0xD1B54A32D192ED03L * data[i + 7] 5987 ; 5988 } 5989 for (; i < data.length; i++) { 5990 result = 0x9E3779B97F4A7C15L * result + data[i]; 5991 } 5992 result *= 0x94D049BB133111EBL; 5993 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 5994 result *= 0x369DEA0F31A53F85L; 5995 result ^= result >>> 31; 5996 result *= 0xDB4F0B9175AE2165L; 5997 return (result ^ result >>> 28); 5998 } 5999 6000 public long hash64(final char[] data) { 6001 if (data == null) return 0; 6002 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6003 int i = 0; 6004 for (; i + 7 < data.length; i += 8) { 6005 result = 0xEBEDEED9D803C815L * result 6006 + 0xD96EB1A810CAAF5FL * data[i] 6007 + 0xC862B36DAF790DD5L * data[i + 1] 6008 + 0xB8ACD90C142FE10BL * data[i + 2] 6009 + 0xAA324F90DED86B69L * data[i + 3] 6010 + 0x9CDA5E693FEA10AFL * data[i + 4] 6011 + 0x908E3D2C82567A73L * data[i + 5] 6012 + 0x8538ECB5BD456EA3L * data[i + 6] 6013 + 0xD1B54A32D192ED03L * data[i + 7] 6014 ; 6015 } 6016 for (; i < data.length; i++) { 6017 result = 0x9E3779B97F4A7C15L * result + data[i]; 6018 } 6019 result *= 0x94D049BB133111EBL; 6020 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6021 result *= 0x369DEA0F31A53F85L; 6022 result ^= result >>> 31; 6023 result *= 0xDB4F0B9175AE2165L; 6024 return (result ^ result >>> 28); 6025 } 6026 6027 public long hash64(final CharSequence data) { 6028 if (data == null) return 0; 6029 final int length = data.length(); 6030 long result = seed ^ length * 0x9E3779B97F4A7C15L; 6031 int i = 0; 6032 for (; i + 7 < length; i += 8) { 6033 result = 0xEBEDEED9D803C815L * result 6034 + 0xD96EB1A810CAAF5FL * data.charAt(i) 6035 + 0xC862B36DAF790DD5L * data.charAt(i + 1) 6036 + 0xB8ACD90C142FE10BL * data.charAt(i + 2) 6037 + 0xAA324F90DED86B69L * data.charAt(i + 3) 6038 + 0x9CDA5E693FEA10AFL * data.charAt(i + 4) 6039 + 0x908E3D2C82567A73L * data.charAt(i + 5) 6040 + 0x8538ECB5BD456EA3L * data.charAt(i + 6) 6041 + 0xD1B54A32D192ED03L * data.charAt(i + 7) 6042 ; 6043 } 6044 for (; i < length; i++) { 6045 result = 0x9E3779B97F4A7C15L * result + data.charAt(i); 6046 } 6047 result *= 0x94D049BB133111EBL; 6048 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6049 result *= 0x369DEA0F31A53F85L; 6050 result ^= result >>> 31; 6051 result *= 0xDB4F0B9175AE2165L; 6052 return (result ^ result >>> 28); 6053 } 6054 6055 public long hash64(final int[] data) { 6056 if (data == null) return 0; 6057 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6058 int i = 0; 6059 for (; i + 7 < data.length; i += 8) { 6060 result = 0xEBEDEED9D803C815L * result 6061 + 0xD96EB1A810CAAF5FL * data[i] 6062 + 0xC862B36DAF790DD5L * data[i + 1] 6063 + 0xB8ACD90C142FE10BL * data[i + 2] 6064 + 0xAA324F90DED86B69L * data[i + 3] 6065 + 0x9CDA5E693FEA10AFL * data[i + 4] 6066 + 0x908E3D2C82567A73L * data[i + 5] 6067 + 0x8538ECB5BD456EA3L * data[i + 6] 6068 + 0xD1B54A32D192ED03L * data[i + 7] 6069 ; 6070 } 6071 for (; i < data.length; i++) { 6072 result = 0x9E3779B97F4A7C15L * result + data[i]; 6073 } 6074 result *= 0x94D049BB133111EBL; 6075 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6076 result *= 0x369DEA0F31A53F85L; 6077 result ^= result >>> 31; 6078 result *= 0xDB4F0B9175AE2165L; 6079 return (result ^ result >>> 28); 6080 } 6081 6082 public long hash64(final int[] data, final int length) { 6083 if (data == null) return 0; 6084 final int len = Math.min(length, data.length); 6085 long result = seed ^ len * 0x9E3779B97F4A7C15L; 6086 int i = 0; 6087 for (; i + 7 < len; i += 8) { 6088 result = 0xEBEDEED9D803C815L * result 6089 + 0xD96EB1A810CAAF5FL * data[i] 6090 + 0xC862B36DAF790DD5L * data[i + 1] 6091 + 0xB8ACD90C142FE10BL * data[i + 2] 6092 + 0xAA324F90DED86B69L * data[i + 3] 6093 + 0x9CDA5E693FEA10AFL * data[i + 4] 6094 + 0x908E3D2C82567A73L * data[i + 5] 6095 + 0x8538ECB5BD456EA3L * data[i + 6] 6096 + 0xD1B54A32D192ED03L * data[i + 7] 6097 ; 6098 } 6099 for (; i < len; i++) { 6100 result = 0x9E3779B97F4A7C15L * result + data[i]; 6101 } 6102 result *= 0x94D049BB133111EBL; 6103 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6104 result *= 0x369DEA0F31A53F85L; 6105 result ^= result >>> 31; 6106 result *= 0xDB4F0B9175AE2165L; 6107 return (result ^ result >>> 28); 6108 } 6109 6110 public long hash64(final long[] data) { 6111 if (data == null) return 0; 6112 long seed = this.seed, a = this.seed + b4, b = this.seed + b3, c = this.seed + b2, d = this.seed + b1; 6113 final int len = data.length; 6114 for (int i = 3; i < len; i+=4) { 6115 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 6116 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 6117 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 6118 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 6119 seed += a + b + c + d; 6120 } 6121 seed += b5; 6122 switch (len & 3) { 6123 case 1: seed = wow(seed, b1 ^ data[len-1]); break; 6124 case 2: seed = wow(seed + data[len-2], b2 + data[len-1]); break; 6125 case 3: seed = wow(seed + data[len-3], b2 + data[len-2]) ^ wow(seed + data[len-1], seed ^ b3); break; 6126 } 6127 seed = (seed ^ seed << 16) * (len ^ b0 ^ seed >>> 32); 6128 return seed - (seed >>> 31) + (seed << 33); 6129 } 6130 public long hash64(final float[] data) { 6131 if (data == null) return 0; 6132 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6133 int i = 0; 6134 for (; i + 7 < data.length; i += 8) { 6135 result = 0xEBEDEED9D803C815L * result 6136 + 0xD96EB1A810CAAF5FL * floatToIntBits(data[i]) 6137 + 0xC862B36DAF790DD5L * floatToIntBits(data[i + 1]) 6138 + 0xB8ACD90C142FE10BL * floatToIntBits(data[i + 2]) 6139 + 0xAA324F90DED86B69L * floatToIntBits(data[i + 3]) 6140 + 0x9CDA5E693FEA10AFL * floatToIntBits(data[i + 4]) 6141 + 0x908E3D2C82567A73L * floatToIntBits(data[i + 5]) 6142 + 0x8538ECB5BD456EA3L * floatToIntBits(data[i + 6]) 6143 + 0xD1B54A32D192ED03L * floatToIntBits(data[i + 7]) 6144 ; 6145 } 6146 for (; i < data.length; i++) { 6147 result = 0x9E3779B97F4A7C15L * result + floatToIntBits(data[i]); 6148 } 6149 result *= 0x94D049BB133111EBL; 6150 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6151 result *= 0x369DEA0F31A53F85L; 6152 result ^= result >>> 31; 6153 result *= 0xDB4F0B9175AE2165L; 6154 return (result ^ result >>> 28); 6155 } 6156 public long hash64(final double[] data) { 6157 if (data == null) return 0; 6158 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6159 int i = 0; 6160 for (; i + 7 < data.length; i += 8) { 6161 result = 0xEBEDEED9D803C815L * result 6162 + 0xD96EB1A810CAAF5FL * doubleToMixedIntBits(data[i]) 6163 + 0xC862B36DAF790DD5L * doubleToMixedIntBits(data[i + 1]) 6164 + 0xB8ACD90C142FE10BL * doubleToMixedIntBits(data[i + 2]) 6165 + 0xAA324F90DED86B69L * doubleToMixedIntBits(data[i + 3]) 6166 + 0x9CDA5E693FEA10AFL * doubleToMixedIntBits(data[i + 4]) 6167 + 0x908E3D2C82567A73L * doubleToMixedIntBits(data[i + 5]) 6168 + 0x8538ECB5BD456EA3L * doubleToMixedIntBits(data[i + 6]) 6169 + 0xD1B54A32D192ED03L * doubleToMixedIntBits(data[i + 7]) 6170 ; 6171 } 6172 for (; i < data.length; i++) { 6173 result = 0x9E3779B97F4A7C15L * result + doubleToMixedIntBits(data[i]); 6174 } 6175 result *= 0x94D049BB133111EBL; 6176 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6177 result *= 0x369DEA0F31A53F85L; 6178 result ^= result >>> 31; 6179 result *= 0xDB4F0B9175AE2165L; 6180 return (result ^ result >>> 28); 6181 } 6182 6183 /** 6184 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 6185 * 6186 * @param data the char array to hash 6187 * @param start the start of the section to hash (inclusive) 6188 * @param end the end of the section to hash (exclusive) 6189 * @return a 64-bit hash code for the requested section of data 6190 */ 6191 public long hash64(final char[] data, final int start, final int end) { 6192 if (data == null || start >= end) return 0; 6193 final int len = Math.min(end, data.length); 6194 6195 long result = seed ^ (len - start) * 0x9E3779B97F4A7C15L; 6196 int i = start; 6197 for (; i + 7 < len; i += 8) { 6198 result = 0xEBEDEED9D803C815L * result 6199 + 0xD96EB1A810CAAF5FL * data[i] 6200 + 0xC862B36DAF790DD5L * data[i + 1] 6201 + 0xB8ACD90C142FE10BL * data[i + 2] 6202 + 0xAA324F90DED86B69L * data[i + 3] 6203 + 0x9CDA5E693FEA10AFL * data[i + 4] 6204 + 0x908E3D2C82567A73L * data[i + 5] 6205 + 0x8538ECB5BD456EA3L * data[i + 6] 6206 + 0xD1B54A32D192ED03L * data[i + 7] 6207 ; 6208 } 6209 for (; i < len; i++) { 6210 result = 0x9E3779B97F4A7C15L * result + data[i]; 6211 } 6212 result *= 0x94D049BB133111EBL; 6213 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6214 result *= 0x369DEA0F31A53F85L; 6215 result ^= result >>> 31; 6216 result *= 0xDB4F0B9175AE2165L; 6217 return (result ^ result >>> 28); 6218 } 6219 6220 /** 6221 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 6222 * 6223 * @param data the String or other CharSequence to hash 6224 * @param start the start of the section to hash (inclusive) 6225 * @param end the end of the section to hash (exclusive) 6226 * @return a 64-bit hash code for the requested section of data 6227 */ 6228 public long hash64(final CharSequence data, final int start, final int end) { 6229 if (data == null || start >= end) return 0; 6230 final int len = Math.min(end, data.length()); 6231 6232 long result = seed ^ (len - start) * 0x9E3779B97F4A7C15L; 6233 int i = start; 6234 for (; i + 7 < len; i += 8) { 6235 result = 0xEBEDEED9D803C815L * result 6236 + 0xD96EB1A810CAAF5FL * data.charAt(i) 6237 + 0xC862B36DAF790DD5L * data.charAt(i + 1) 6238 + 0xB8ACD90C142FE10BL * data.charAt(i + 2) 6239 + 0xAA324F90DED86B69L * data.charAt(i + 3) 6240 + 0x9CDA5E693FEA10AFL * data.charAt(i + 4) 6241 + 0x908E3D2C82567A73L * data.charAt(i + 5) 6242 + 0x8538ECB5BD456EA3L * data.charAt(i + 6) 6243 + 0xD1B54A32D192ED03L * data.charAt(i + 7) 6244 ; 6245 } 6246 for (; i < len; i++) { 6247 result = 0x9E3779B97F4A7C15L * result + data.charAt(i); 6248 } 6249 result *= 0x94D049BB133111EBL; 6250 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6251 result *= 0x369DEA0F31A53F85L; 6252 result ^= result >>> 31; 6253 result *= 0xDB4F0B9175AE2165L; 6254 return (result ^ result >>> 28); 6255 } 6256 6257 6258 public long hash64(final char[][] data) { 6259 if (data == null) return 0; 6260 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6261 int i = 0; 6262 for (; i + 7 < data.length; i += 8) { 6263 result = 0xEBEDEED9D803C815L * result 6264 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6265 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6266 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6267 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6268 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6269 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6270 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6271 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6272 ; 6273 } 6274 for (; i < data.length; i++) { 6275 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6276 } 6277 result *= 0x94D049BB133111EBL; 6278 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6279 result *= 0x369DEA0F31A53F85L; 6280 result ^= result >>> 31; 6281 result *= 0xDB4F0B9175AE2165L; 6282 return (result ^ result >>> 28); 6283 } 6284 6285 public long hash64(final int[][] data) { 6286 if (data == null) return 0; 6287 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6288 int i = 0; 6289 for (; i + 7 < data.length; i += 8) { 6290 result = 0xEBEDEED9D803C815L * result 6291 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6292 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6293 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6294 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6295 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6296 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6297 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6298 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6299 ; 6300 } 6301 for (; i < data.length; i++) { 6302 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6303 } 6304 result *= 0x94D049BB133111EBL; 6305 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6306 result *= 0x369DEA0F31A53F85L; 6307 result ^= result >>> 31; 6308 result *= 0xDB4F0B9175AE2165L; 6309 return (result ^ result >>> 28); 6310 } 6311 6312 public long hash64(final long[][] data) { 6313 if (data == null) return 0; 6314 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6315 int i = 0; 6316 for (; i + 7 < data.length; i += 8) { 6317 result = 0xEBEDEED9D803C815L * result 6318 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6319 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6320 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6321 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6322 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6323 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6324 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6325 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6326 ; 6327 } 6328 for (; i < data.length; i++) { 6329 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6330 } 6331 result *= 0x94D049BB133111EBL; 6332 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6333 result *= 0x369DEA0F31A53F85L; 6334 result ^= result >>> 31; 6335 result *= 0xDB4F0B9175AE2165L; 6336 return (result ^ result >>> 28); 6337 } 6338 6339 public long hash64(final CharSequence[] data) { 6340 if (data == null) return 0; 6341 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6342 int i = 0; 6343 for (; i + 7 < data.length; i += 8) { 6344 result = 0xEBEDEED9D803C815L * result 6345 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6346 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6347 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6348 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6349 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6350 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6351 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6352 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6353 ; 6354 } 6355 for (; i < data.length; i++) { 6356 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6357 } 6358 result *= 0x94D049BB133111EBL; 6359 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6360 result *= 0x369DEA0F31A53F85L; 6361 result ^= result >>> 31; 6362 result *= 0xDB4F0B9175AE2165L; 6363 return (result ^ result >>> 28); 6364 } 6365 6366 public long hash64(final CharSequence[]... data) { 6367 if (data == null) return 0; 6368 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6369 int i = 0; 6370 for (; i + 7 < data.length; i += 8) { 6371 result = 0xEBEDEED9D803C815L * result 6372 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6373 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6374 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6375 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6376 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6377 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6378 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6379 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6380 ; 6381 } 6382 for (; i < data.length; i++) { 6383 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6384 } 6385 result *= 0x94D049BB133111EBL; 6386 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6387 result *= 0x369DEA0F31A53F85L; 6388 result ^= result >>> 31; 6389 result *= 0xDB4F0B9175AE2165L; 6390 return (result ^ result >>> 28); 6391 } 6392 6393 public long hash64(final Iterable<? extends CharSequence> data) { 6394 if (data == null) return 0; 6395 long seed = this.seed; 6396 final Iterator<? extends CharSequence> it = data.iterator(); 6397 int len = 0; 6398 while (it.hasNext()) 6399 { 6400 ++len; 6401 seed = mum( 6402 mum(hash(it.next()) ^ b1, (it.hasNext() ? hash(it.next()) ^ b2 ^ ++len : b2)) + seed, 6403 mum((it.hasNext() ? hash(it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(it.next()) ^ b4 ^ ++len : b4))); 6404 } 6405 seed = (seed ^ seed << 16) * (len ^ b0); 6406 return seed - (seed >>> 31) + (seed << 33); 6407 } 6408 6409 public long hash64(final List<? extends CharSequence> data) { 6410 if (data == null) return 0; 6411 final int len = data.size(); 6412 long result = seed ^ len * 0x9E3779B97F4A7C15L; 6413 int i = 0; 6414 for (; i + 7 < len; i += 8) { 6415 result = 0xEBEDEED9D803C815L * result 6416 + 0xD96EB1A810CAAF5FL * hash(data.get(i)) 6417 + 0xC862B36DAF790DD5L * hash(data.get(i + 1)) 6418 + 0xB8ACD90C142FE10BL * hash(data.get(i + 2)) 6419 + 0xAA324F90DED86B69L * hash(data.get(i + 3)) 6420 + 0x9CDA5E693FEA10AFL * hash(data.get(i + 4)) 6421 + 0x908E3D2C82567A73L * hash(data.get(i + 5)) 6422 + 0x8538ECB5BD456EA3L * hash(data.get(i + 6)) 6423 + 0xD1B54A32D192ED03L * hash(data.get(i + 7)) 6424 ; 6425 } 6426 for (; i < len; i++) { 6427 result = 0x9E3779B97F4A7C15L * result + hash(data.get(i)); 6428 } 6429 result *= 0x94D049BB133111EBL; 6430 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6431 result *= 0x369DEA0F31A53F85L; 6432 result ^= result >>> 31; 6433 result *= 0xDB4F0B9175AE2165L; 6434 return (result ^ result >>> 28); 6435 6436 } 6437 6438 public long hash64(final Object[] data) { 6439 if (data == null) return 0; 6440 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6441 int i = 0; 6442 for (; i + 7 < data.length; i += 8) { 6443 result = 0xEBEDEED9D803C815L * result 6444 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6445 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6446 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6447 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6448 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6449 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6450 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6451 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6452 ; 6453 } 6454 for (; i < data.length; i++) { 6455 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6456 } 6457 result *= 0x94D049BB133111EBL; 6458 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6459 result *= 0x369DEA0F31A53F85L; 6460 result ^= result >>> 31; 6461 result *= 0xDB4F0B9175AE2165L; 6462 return (result ^ result >>> 28); 6463 } 6464 6465 public long hash64(final Object data) { 6466 if (data == null) 6467 return 0; 6468 final long h = (data.hashCode() + seed) * 0x9E3779B97F4A7C15L; 6469 return h - (h >>> 31) + (h << 33); 6470 } 6471 6472 public int hash(final boolean[] data) { 6473 if (data == null) return 0; 6474 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6475 int i = 0; 6476 for (; i + 7 < data.length; i += 8) { 6477 result = result * 0xEBEDEED9D803C815L 6478 + (data[i] ? 0xD96EB1A810CAAF5FL : 0xCAAF5FD96EB1A810L) 6479 + (data[i + 1] ? 0xC862B36DAF790DD5L : 0x790DD5C862B36DAFL) 6480 + (data[i + 2] ? 0xB8ACD90C142FE10BL : 0x2FE10BB8ACD90C14L) 6481 + (data[i + 3] ? 0xAA324F90DED86B69L : 0xD86B69AA324F90DEL) 6482 + (data[i + 4] ? 0x9CDA5E693FEA10AFL : 0xEA10AF9CDA5E693FL) 6483 + (data[i + 5] ? 0x908E3D2C82567A73L : 0x567A73908E3D2C82L) 6484 + (data[i + 6] ? 0x8538ECB5BD456EA3L : 0x456EA38538ECB5BDL) 6485 + (data[i + 7] ? 0xD1B54A32D192ED03L : 0x92ED03D1B54A32D1L) 6486 ; 6487 } 6488 for (; i < data.length; i++) { 6489 result = 0x9E3779B97F4A7C15L * result + (data[i] ? 0xEBEDEED9D803C815L : 0xD9D803C815EBEDEEL); 6490 } 6491 result *= 0x94D049BB133111EBL; 6492 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6493 result *= 0x369DEA0F31A53F85L; 6494 result ^= result >>> 31; 6495 result *= 0xDB4F0B9175AE2165L; 6496 return (int)(result ^ result >>> 28); 6497 } 6498 public int hash(final byte[] data) { 6499 if (data == null) return 0; 6500 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6501 int i = 0; 6502 for (; i + 7 < data.length; i += 8) { 6503 result = 0xEBEDEED9D803C815L * result 6504 + 0xD96EB1A810CAAF5FL * data[i] 6505 + 0xC862B36DAF790DD5L * data[i + 1] 6506 + 0xB8ACD90C142FE10BL * data[i + 2] 6507 + 0xAA324F90DED86B69L * data[i + 3] 6508 + 0x9CDA5E693FEA10AFL * data[i + 4] 6509 + 0x908E3D2C82567A73L * data[i + 5] 6510 + 0x8538ECB5BD456EA3L * data[i + 6] 6511 + 0xD1B54A32D192ED03L * data[i + 7] 6512 ; 6513 } 6514 for (; i < data.length; i++) { 6515 result = 0x9E3779B97F4A7C15L * result + data[i]; 6516 } 6517 result *= 0x94D049BB133111EBL; 6518 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6519 result *= 0x369DEA0F31A53F85L; 6520 result ^= result >>> 31; 6521 result *= 0xDB4F0B9175AE2165L; 6522 return (int)(result ^ result >>> 28); 6523 } 6524 6525 public int hash(final short[] data) { 6526 if (data == null) return 0; 6527 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6528 int i = 0; 6529 for (; i + 7 < data.length; i += 8) { 6530 result = 0xEBEDEED9D803C815L * result 6531 + 0xD96EB1A810CAAF5FL * data[i] 6532 + 0xC862B36DAF790DD5L * data[i + 1] 6533 + 0xB8ACD90C142FE10BL * data[i + 2] 6534 + 0xAA324F90DED86B69L * data[i + 3] 6535 + 0x9CDA5E693FEA10AFL * data[i + 4] 6536 + 0x908E3D2C82567A73L * data[i + 5] 6537 + 0x8538ECB5BD456EA3L * data[i + 6] 6538 + 0xD1B54A32D192ED03L * data[i + 7] 6539 ; 6540 } 6541 for (; i < data.length; i++) { 6542 result = 0x9E3779B97F4A7C15L * result + data[i]; 6543 } 6544 result *= 0x94D049BB133111EBL; 6545 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6546 result *= 0x369DEA0F31A53F85L; 6547 result ^= result >>> 31; 6548 result *= 0xDB4F0B9175AE2165L; 6549 return (int)(result ^ result >>> 28); 6550 } 6551 6552 public int hash(final char[] data) { 6553 if (data == null) return 0; 6554 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6555 int i = 0; 6556 for (; i + 7 < data.length; i += 8) { 6557 result = 0xEBEDEED9D803C815L * result 6558 + 0xD96EB1A810CAAF5FL * data[i] 6559 + 0xC862B36DAF790DD5L * data[i + 1] 6560 + 0xB8ACD90C142FE10BL * data[i + 2] 6561 + 0xAA324F90DED86B69L * data[i + 3] 6562 + 0x9CDA5E693FEA10AFL * data[i + 4] 6563 + 0x908E3D2C82567A73L * data[i + 5] 6564 + 0x8538ECB5BD456EA3L * data[i + 6] 6565 + 0xD1B54A32D192ED03L * data[i + 7] 6566 ; 6567 } 6568 for (; i < data.length; i++) { 6569 result = 0x9E3779B97F4A7C15L * result + data[i]; 6570 } 6571 result *= 0x94D049BB133111EBL; 6572 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6573 result *= 0x369DEA0F31A53F85L; 6574 result ^= result >>> 31; 6575 result *= 0xDB4F0B9175AE2165L; 6576 return (int)(result ^ result >>> 28); 6577 } 6578 6579 public int hash(final CharSequence data) { 6580 if (data == null) return 0; 6581 final int length = data.length(); 6582 long result = seed ^ length * 0x9E3779B97F4A7C15L; 6583 int i = 0; 6584 for (; i + 7 < length; i += 8) { 6585 result = 0xEBEDEED9D803C815L * result 6586 + 0xD96EB1A810CAAF5FL * data.charAt(i) 6587 + 0xC862B36DAF790DD5L * data.charAt(i + 1) 6588 + 0xB8ACD90C142FE10BL * data.charAt(i + 2) 6589 + 0xAA324F90DED86B69L * data.charAt(i + 3) 6590 + 0x9CDA5E693FEA10AFL * data.charAt(i + 4) 6591 + 0x908E3D2C82567A73L * data.charAt(i + 5) 6592 + 0x8538ECB5BD456EA3L * data.charAt(i + 6) 6593 + 0xD1B54A32D192ED03L * data.charAt(i + 7) 6594 ; 6595 } 6596 for (; i < length; i++) { 6597 result = 0x9E3779B97F4A7C15L * result + data.charAt(i); 6598 } 6599 result *= 0x94D049BB133111EBL; 6600 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6601 result *= 0x369DEA0F31A53F85L; 6602 result ^= result >>> 31; 6603 result *= 0xDB4F0B9175AE2165L; 6604 return (int)(result ^ result >>> 28); 6605 } 6606 6607 public int hash(final int[] data) { 6608 if (data == null) return 0; 6609 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6610 int i = 0; 6611 for (; i + 7 < data.length; i += 8) { 6612 result = 0xEBEDEED9D803C815L * result 6613 + 0xD96EB1A810CAAF5FL * data[i] 6614 + 0xC862B36DAF790DD5L * data[i + 1] 6615 + 0xB8ACD90C142FE10BL * data[i + 2] 6616 + 0xAA324F90DED86B69L * data[i + 3] 6617 + 0x9CDA5E693FEA10AFL * data[i + 4] 6618 + 0x908E3D2C82567A73L * data[i + 5] 6619 + 0x8538ECB5BD456EA3L * data[i + 6] 6620 + 0xD1B54A32D192ED03L * data[i + 7] 6621 ; 6622 } 6623 for (; i < data.length; i++) { 6624 result = 0x9E3779B97F4A7C15L * result + data[i]; 6625 } 6626 result *= 0x94D049BB133111EBL; 6627 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6628 result *= 0x369DEA0F31A53F85L; 6629 result ^= result >>> 31; 6630 result *= 0xDB4F0B9175AE2165L; 6631 return (int)(result ^ result >>> 28); 6632 } 6633 6634 public int hash(final int[] data, final int length) { 6635 if (data == null) return 0; 6636 final int len = Math.min(length, data.length); 6637 long result = seed ^ len * 0x9E3779B97F4A7C15L; 6638 int i = 0; 6639 for (; i + 7 < len; i += 8) { 6640 result = 0xEBEDEED9D803C815L * result 6641 + 0xD96EB1A810CAAF5FL * data[i] 6642 + 0xC862B36DAF790DD5L * data[i + 1] 6643 + 0xB8ACD90C142FE10BL * data[i + 2] 6644 + 0xAA324F90DED86B69L * data[i + 3] 6645 + 0x9CDA5E693FEA10AFL * data[i + 4] 6646 + 0x908E3D2C82567A73L * data[i + 5] 6647 + 0x8538ECB5BD456EA3L * data[i + 6] 6648 + 0xD1B54A32D192ED03L * data[i + 7] 6649 ; 6650 } 6651 for (; i < len; i++) { 6652 result = 0x9E3779B97F4A7C15L * result + data[i]; 6653 } 6654 result *= 0x94D049BB133111EBL; 6655 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6656 result *= 0x369DEA0F31A53F85L; 6657 result ^= result >>> 31; 6658 result *= 0xDB4F0B9175AE2165L; 6659 return (int)(result ^ result >>> 28); 6660 } 6661 6662 public int hash(final long[] data) { 6663 if (data == null) return 0; 6664 long seed = this.seed, a = this.seed + b4, b = this.seed + b3, c = this.seed + b2, d = this.seed + b1; 6665 final int len = data.length; 6666 for (int i = 3; i < len; i+=4) { 6667 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 6668 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 6669 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 6670 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 6671 seed += a + b + c + d; 6672 } 6673 seed += b5; 6674 switch (len & 3) { 6675 case 1: seed = wow(seed, b1 ^ data[len-1]); break; 6676 case 2: seed = wow(seed + data[len-2], b2 + data[len-1]); break; 6677 case 3: seed = wow(seed + data[len-3], b2 + data[len-2]) ^ wow(seed + data[len-1], seed ^ b3); break; 6678 } 6679 seed = (seed ^ seed << 16) * (len ^ b0 ^ seed >>> 32); 6680 return (int)(seed - (seed >>> 32)); 6681 } 6682 6683 public int hash(final float[] data) { 6684 if (data == null) return 0; 6685 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6686 int i = 0; 6687 for (; i + 7 < data.length; i += 8) { 6688 result = 0xEBEDEED9D803C815L * result 6689 + 0xD96EB1A810CAAF5FL * floatToIntBits(data[i]) 6690 + 0xC862B36DAF790DD5L * floatToIntBits(data[i + 1]) 6691 + 0xB8ACD90C142FE10BL * floatToIntBits(data[i + 2]) 6692 + 0xAA324F90DED86B69L * floatToIntBits(data[i + 3]) 6693 + 0x9CDA5E693FEA10AFL * floatToIntBits(data[i + 4]) 6694 + 0x908E3D2C82567A73L * floatToIntBits(data[i + 5]) 6695 + 0x8538ECB5BD456EA3L * floatToIntBits(data[i + 6]) 6696 + 0xD1B54A32D192ED03L * floatToIntBits(data[i + 7]) 6697 ; 6698 } 6699 for (; i < data.length; i++) { 6700 result = 0x9E3779B97F4A7C15L * result + floatToIntBits(data[i]); 6701 } 6702 result *= 0x94D049BB133111EBL; 6703 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6704 result *= 0x369DEA0F31A53F85L; 6705 result ^= result >>> 31; 6706 result *= 0xDB4F0B9175AE2165L; 6707 return (int)(result ^ result >>> 28); 6708 } 6709 public int hash(final double[] data) { 6710 if (data == null) return 0; 6711 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6712 int i = 0; 6713 for (; i + 7 < data.length; i += 8) { 6714 result = 0xEBEDEED9D803C815L * result 6715 + 0xD96EB1A810CAAF5FL * doubleToMixedIntBits(data[i]) 6716 + 0xC862B36DAF790DD5L * doubleToMixedIntBits(data[i + 1]) 6717 + 0xB8ACD90C142FE10BL * doubleToMixedIntBits(data[i + 2]) 6718 + 0xAA324F90DED86B69L * doubleToMixedIntBits(data[i + 3]) 6719 + 0x9CDA5E693FEA10AFL * doubleToMixedIntBits(data[i + 4]) 6720 + 0x908E3D2C82567A73L * doubleToMixedIntBits(data[i + 5]) 6721 + 0x8538ECB5BD456EA3L * doubleToMixedIntBits(data[i + 6]) 6722 + 0xD1B54A32D192ED03L * doubleToMixedIntBits(data[i + 7]) 6723 ; 6724 } 6725 for (; i < data.length; i++) { 6726 result = 0x9E3779B97F4A7C15L * result + doubleToMixedIntBits(data[i]); 6727 } 6728 result *= 0x94D049BB133111EBL; 6729 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6730 result *= 0x369DEA0F31A53F85L; 6731 result ^= result >>> 31; 6732 result *= 0xDB4F0B9175AE2165L; 6733 return (int)(result ^ result >>> 28); 6734 } 6735 6736 /** 6737 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 6738 * 6739 * @param data the char array to hash 6740 * @param start the start of the section to hash (inclusive) 6741 * @param end the end of the section to hash (exclusive) 6742 * @return a 64-bit hash code for the requested section of data 6743 */ 6744 public int hash(final char[] data, final int start, final int end) { 6745 if (data == null || start >= end) return 0; 6746 final int len = Math.min(end, data.length); 6747 6748 long result = seed ^ (len - start) * 0x9E3779B97F4A7C15L; 6749 int i = start; 6750 for (; i + 7 < len; i += 8) { 6751 result = 0xEBEDEED9D803C815L * result 6752 + 0xD96EB1A810CAAF5FL * data[i] 6753 + 0xC862B36DAF790DD5L * data[i + 1] 6754 + 0xB8ACD90C142FE10BL * data[i + 2] 6755 + 0xAA324F90DED86B69L * data[i + 3] 6756 + 0x9CDA5E693FEA10AFL * data[i + 4] 6757 + 0x908E3D2C82567A73L * data[i + 5] 6758 + 0x8538ECB5BD456EA3L * data[i + 6] 6759 + 0xD1B54A32D192ED03L * data[i + 7] 6760 ; 6761 } 6762 for (; i < len; i++) { 6763 result = 0x9E3779B97F4A7C15L * result + data[i]; 6764 } 6765 result *= 0x94D049BB133111EBL; 6766 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6767 result *= 0x369DEA0F31A53F85L; 6768 result ^= result >>> 31; 6769 result *= 0xDB4F0B9175AE2165L; 6770 return (int)(result ^ result >>> 28); 6771 } 6772 6773 /** 6774 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 6775 * 6776 * @param data the String or other CharSequence to hash 6777 * @param start the start of the section to hash (inclusive) 6778 * @param end the end of the section to hash (exclusive) 6779 * @return a 64-bit hash code for the requested section of data 6780 */ 6781 public int hash(final CharSequence data, final int start, final int end) { 6782 if (data == null || start >= end) return 0; 6783 final int len = Math.min(end, data.length()); 6784 6785 long result = seed ^ (len - start) * 0x9E3779B97F4A7C15L; 6786 int i = start; 6787 for (; i + 7 < len; i += 8) { 6788 result = 0xEBEDEED9D803C815L * result 6789 + 0xD96EB1A810CAAF5FL * data.charAt(i) 6790 + 0xC862B36DAF790DD5L * data.charAt(i + 1) 6791 + 0xB8ACD90C142FE10BL * data.charAt(i + 2) 6792 + 0xAA324F90DED86B69L * data.charAt(i + 3) 6793 + 0x9CDA5E693FEA10AFL * data.charAt(i + 4) 6794 + 0x908E3D2C82567A73L * data.charAt(i + 5) 6795 + 0x8538ECB5BD456EA3L * data.charAt(i + 6) 6796 + 0xD1B54A32D192ED03L * data.charAt(i + 7) 6797 ; 6798 } 6799 for (; i < len; i++) { 6800 result = 0x9E3779B97F4A7C15L * result + data.charAt(i); 6801 } 6802 result *= 0x94D049BB133111EBL; 6803 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6804 result *= 0x369DEA0F31A53F85L; 6805 result ^= result >>> 31; 6806 result *= 0xDB4F0B9175AE2165L; 6807 return (int)(result ^ result >>> 28); 6808 } 6809 6810 6811 public int hash(final char[][] data) { 6812 if (data == null) return 0; 6813 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6814 int i = 0; 6815 for (; i + 7 < data.length; i += 8) { 6816 result = 0xEBEDEED9D803C815L * result 6817 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6818 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6819 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6820 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6821 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6822 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6823 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6824 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6825 ; 6826 } 6827 for (; i < data.length; i++) { 6828 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6829 } 6830 result *= 0x94D049BB133111EBL; 6831 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6832 result *= 0x369DEA0F31A53F85L; 6833 result ^= result >>> 31; 6834 result *= 0xDB4F0B9175AE2165L; 6835 return (int)(result ^ result >>> 28); 6836 } 6837 6838 public int hash(final int[][] data) { 6839 if (data == null) return 0; 6840 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6841 int i = 0; 6842 for (; i + 7 < data.length; i += 8) { 6843 result = 0xEBEDEED9D803C815L * result 6844 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6845 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6846 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6847 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6848 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6849 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6850 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6851 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6852 ; 6853 } 6854 for (; i < data.length; i++) { 6855 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6856 } 6857 result *= 0x94D049BB133111EBL; 6858 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6859 result *= 0x369DEA0F31A53F85L; 6860 result ^= result >>> 31; 6861 result *= 0xDB4F0B9175AE2165L; 6862 return (int)(result ^ result >>> 28); 6863 } 6864 6865 public int hash(final long[][] data) { 6866 if (data == null) return 0; 6867 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6868 int i = 0; 6869 for (; i + 7 < data.length; i += 8) { 6870 result = 0xEBEDEED9D803C815L * result 6871 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6872 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6873 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6874 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6875 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6876 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6877 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6878 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6879 ; 6880 } 6881 for (; i < data.length; i++) { 6882 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6883 } 6884 result *= 0x94D049BB133111EBL; 6885 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6886 result *= 0x369DEA0F31A53F85L; 6887 result ^= result >>> 31; 6888 result *= 0xDB4F0B9175AE2165L; 6889 return (int)(result ^ result >>> 28); 6890 } 6891 6892 public int hash(final CharSequence[] data) { 6893 if (data == null) return 0; 6894 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6895 int i = 0; 6896 for (; i + 7 < data.length; i += 8) { 6897 result = 0xEBEDEED9D803C815L * result 6898 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6899 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6900 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6901 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6902 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6903 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6904 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6905 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6906 ; 6907 } 6908 for (; i < data.length; i++) { 6909 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6910 } 6911 result *= 0x94D049BB133111EBL; 6912 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6913 result *= 0x369DEA0F31A53F85L; 6914 result ^= result >>> 31; 6915 result *= 0xDB4F0B9175AE2165L; 6916 return (int)(result ^ result >>> 28); 6917 } 6918 6919 public int hash(final CharSequence[]... data) { 6920 if (data == null) return 0; 6921 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6922 int i = 0; 6923 for (; i + 7 < data.length; i += 8) { 6924 result = 0xEBEDEED9D803C815L * result 6925 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6926 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6927 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6928 + 0xAA324F90DED86B69L * hash(data[i + 3]) 6929 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 6930 + 0x908E3D2C82567A73L * hash(data[i + 5]) 6931 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 6932 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 6933 ; 6934 } 6935 for (; i < data.length; i++) { 6936 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 6937 } 6938 result *= 0x94D049BB133111EBL; 6939 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6940 result *= 0x369DEA0F31A53F85L; 6941 result ^= result >>> 31; 6942 result *= 0xDB4F0B9175AE2165L; 6943 return (int)(result ^ result >>> 28); 6944 } 6945 6946 public int hash(final Iterable<? extends CharSequence> data) { 6947 if (data == null) return 0; 6948 long seed = this.seed; 6949 final Iterator<? extends CharSequence> it = data.iterator(); 6950 int len = 0; 6951 while (it.hasNext()) 6952 { 6953 ++len; 6954 seed = mum( 6955 mum(hash(it.next()) ^ b1, (it.hasNext() ? hash(it.next()) ^ b2 ^ ++len : b2)) + seed, 6956 mum((it.hasNext() ? hash(it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(it.next()) ^ b4 ^ ++len : b4))); 6957 } 6958 return (int) mum(seed ^ seed << 16, len ^ b0); 6959 } 6960 6961 public int hash(final List<? extends CharSequence> data) { 6962 if (data == null) return 0; 6963 final int len = data.size(); 6964 long result = seed ^ len * 0x9E3779B97F4A7C15L; 6965 int i = 0; 6966 for (; i + 7 < len; i += 8) { 6967 result = 0xEBEDEED9D803C815L * result 6968 + 0xD96EB1A810CAAF5FL * hash(data.get(i)) 6969 + 0xC862B36DAF790DD5L * hash(data.get(i + 1)) 6970 + 0xB8ACD90C142FE10BL * hash(data.get(i + 2)) 6971 + 0xAA324F90DED86B69L * hash(data.get(i + 3)) 6972 + 0x9CDA5E693FEA10AFL * hash(data.get(i + 4)) 6973 + 0x908E3D2C82567A73L * hash(data.get(i + 5)) 6974 + 0x8538ECB5BD456EA3L * hash(data.get(i + 6)) 6975 + 0xD1B54A32D192ED03L * hash(data.get(i + 7)) 6976 ; 6977 } 6978 for (; i < len; i++) { 6979 result = 0x9E3779B97F4A7C15L * result + hash(data.get(i)); 6980 } 6981 result *= 0x94D049BB133111EBL; 6982 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 6983 result *= 0x369DEA0F31A53F85L; 6984 result ^= result >>> 31; 6985 result *= 0xDB4F0B9175AE2165L; 6986 return (int)(result ^ result >>> 28); 6987 6988 } 6989 6990 public int hash(final Object[] data) { 6991 if (data == null) return 0; 6992 long result = seed ^ data.length * 0x9E3779B97F4A7C15L; 6993 int i = 0; 6994 for (; i + 7 < data.length; i += 8) { 6995 result = 0xEBEDEED9D803C815L * result 6996 + 0xD96EB1A810CAAF5FL * hash(data[i]) 6997 + 0xC862B36DAF790DD5L * hash(data[i + 1]) 6998 + 0xB8ACD90C142FE10BL * hash(data[i + 2]) 6999 + 0xAA324F90DED86B69L * hash(data[i + 3]) 7000 + 0x9CDA5E693FEA10AFL * hash(data[i + 4]) 7001 + 0x908E3D2C82567A73L * hash(data[i + 5]) 7002 + 0x8538ECB5BD456EA3L * hash(data[i + 6]) 7003 + 0xD1B54A32D192ED03L * hash(data[i + 7]) 7004 ; 7005 } 7006 for (; i < data.length; i++) { 7007 result = 0x9E3779B97F4A7C15L * result + hash(data[i]); 7008 } 7009 result *= 0x94D049BB133111EBL; 7010 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7011 result *= 0x369DEA0F31A53F85L; 7012 result ^= result >>> 31; 7013 result *= 0xDB4F0B9175AE2165L; 7014 return (int)(result ^ result >>> 28); 7015 } 7016 7017 public int hash(final Object data) { 7018 if (data == null) return 0; 7019 return (int)((data.hashCode() + seed) * 0x9E3779B97F4A7C15L >>> 32); 7020 } 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 public static long hash64(final long seed, final boolean[] data) { 7055 if (data == null) return 0; 7056 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7057 int i = 0; 7058 for (; i + 7 < data.length; i += 8) { 7059 result = result * 0xEBEDEED9D803C815L 7060 + (data[i] ? 0xD96EB1A810CAAF5FL : 0xCAAF5FD96EB1A810L) 7061 + (data[i + 1] ? 0xC862B36DAF790DD5L : 0x790DD5C862B36DAFL) 7062 + (data[i + 2] ? 0xB8ACD90C142FE10BL : 0x2FE10BB8ACD90C14L) 7063 + (data[i + 3] ? 0xAA324F90DED86B69L : 0xD86B69AA324F90DEL) 7064 + (data[i + 4] ? 0x9CDA5E693FEA10AFL : 0xEA10AF9CDA5E693FL) 7065 + (data[i + 5] ? 0x908E3D2C82567A73L : 0x567A73908E3D2C82L) 7066 + (data[i + 6] ? 0x8538ECB5BD456EA3L : 0x456EA38538ECB5BDL) 7067 + (data[i + 7] ? 0xD1B54A32D192ED03L : 0x92ED03D1B54A32D1L) 7068 ; 7069 } 7070 for (; i < data.length; i++) { 7071 result = 0x9E3779B97F4A7C15L * result + (data[i] ? 0xEBEDEED9D803C815L : 0xD9D803C815EBEDEEL); 7072 } 7073 result *= 0x94D049BB133111EBL; 7074 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7075 result *= 0x369DEA0F31A53F85L; 7076 result ^= result >>> 31; 7077 result *= 0xDB4F0B9175AE2165L; 7078 return (result ^ result >>> 28); 7079 } 7080 public static long hash64(final long seed, final byte[] data) { 7081 if (data == null) return 0; 7082 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7083 int i = 0; 7084 for (; i + 7 < data.length; i += 8) { 7085 result = 0xEBEDEED9D803C815L * result 7086 + 0xD96EB1A810CAAF5FL * data[i] 7087 + 0xC862B36DAF790DD5L * data[i + 1] 7088 + 0xB8ACD90C142FE10BL * data[i + 2] 7089 + 0xAA324F90DED86B69L * data[i + 3] 7090 + 0x9CDA5E693FEA10AFL * data[i + 4] 7091 + 0x908E3D2C82567A73L * data[i + 5] 7092 + 0x8538ECB5BD456EA3L * data[i + 6] 7093 + 0xD1B54A32D192ED03L * data[i + 7] 7094 ; 7095 } 7096 for (; i < data.length; i++) { 7097 result = 0x9E3779B97F4A7C15L * result + data[i]; 7098 } 7099 result *= 0x94D049BB133111EBL; 7100 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7101 result *= 0x369DEA0F31A53F85L; 7102 result ^= result >>> 31; 7103 result *= 0xDB4F0B9175AE2165L; 7104 return (result ^ result >>> 28); 7105 } 7106 7107 public static long hash64(final long seed, final short[] data) { 7108 if (data == null) return 0; 7109 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7110 int i = 0; 7111 for (; i + 7 < data.length; i += 8) { 7112 result = 0xEBEDEED9D803C815L * result 7113 + 0xD96EB1A810CAAF5FL * data[i] 7114 + 0xC862B36DAF790DD5L * data[i + 1] 7115 + 0xB8ACD90C142FE10BL * data[i + 2] 7116 + 0xAA324F90DED86B69L * data[i + 3] 7117 + 0x9CDA5E693FEA10AFL * data[i + 4] 7118 + 0x908E3D2C82567A73L * data[i + 5] 7119 + 0x8538ECB5BD456EA3L * data[i + 6] 7120 + 0xD1B54A32D192ED03L * data[i + 7] 7121 ; 7122 } 7123 for (; i < data.length; i++) { 7124 result = 0x9E3779B97F4A7C15L * result + data[i]; 7125 } 7126 result *= 0x94D049BB133111EBL; 7127 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7128 result *= 0x369DEA0F31A53F85L; 7129 result ^= result >>> 31; 7130 result *= 0xDB4F0B9175AE2165L; 7131 return (result ^ result >>> 28); 7132 } 7133 7134 public static long hash64(final long seed, final char[] data) { 7135 if (data == null) return 0; 7136 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7137 int i = 0; 7138 for (; i + 7 < data.length; i += 8) { 7139 result = 0xEBEDEED9D803C815L * result 7140 + 0xD96EB1A810CAAF5FL * data[i] 7141 + 0xC862B36DAF790DD5L * data[i + 1] 7142 + 0xB8ACD90C142FE10BL * data[i + 2] 7143 + 0xAA324F90DED86B69L * data[i + 3] 7144 + 0x9CDA5E693FEA10AFL * data[i + 4] 7145 + 0x908E3D2C82567A73L * data[i + 5] 7146 + 0x8538ECB5BD456EA3L * data[i + 6] 7147 + 0xD1B54A32D192ED03L * data[i + 7] 7148 ; 7149 } 7150 for (; i < data.length; i++) { 7151 result = 0x9E3779B97F4A7C15L * result + data[i]; 7152 } 7153 result *= 0x94D049BB133111EBL; 7154 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7155 result *= 0x369DEA0F31A53F85L; 7156 result ^= result >>> 31; 7157 result *= 0xDB4F0B9175AE2165L; 7158 return (result ^ result >>> 28); 7159 } 7160 7161 public static long hash64(final long seed, final CharSequence data) { 7162 if (data == null) return 0; 7163 final int length = data.length(); 7164 long result = randomize(seed) ^ length * 0x9E3779B97F4A7C15L; 7165 int i = 0; 7166 for (; i + 7 < length; i += 8) { 7167 result = 0xEBEDEED9D803C815L * result 7168 + 0xD96EB1A810CAAF5FL * data.charAt(i) 7169 + 0xC862B36DAF790DD5L * data.charAt(i + 1) 7170 + 0xB8ACD90C142FE10BL * data.charAt(i + 2) 7171 + 0xAA324F90DED86B69L * data.charAt(i + 3) 7172 + 0x9CDA5E693FEA10AFL * data.charAt(i + 4) 7173 + 0x908E3D2C82567A73L * data.charAt(i + 5) 7174 + 0x8538ECB5BD456EA3L * data.charAt(i + 6) 7175 + 0xD1B54A32D192ED03L * data.charAt(i + 7) 7176 ; 7177 } 7178 for (; i < length; i++) { 7179 result = 0x9E3779B97F4A7C15L * result + data.charAt(i); 7180 } 7181 result *= 0x94D049BB133111EBL; 7182 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7183 result *= 0x369DEA0F31A53F85L; 7184 result ^= result >>> 31; 7185 result *= 0xDB4F0B9175AE2165L; 7186 return (result ^ result >>> 28); 7187 } 7188 7189 public static long hash64(final long seed, final int[] data) { 7190 if (data == null) return 0; 7191 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7192 int i = 0; 7193 for (; i + 7 < data.length; i += 8) { 7194 result = 0xEBEDEED9D803C815L * result 7195 + 0xD96EB1A810CAAF5FL * data[i] 7196 + 0xC862B36DAF790DD5L * data[i + 1] 7197 + 0xB8ACD90C142FE10BL * data[i + 2] 7198 + 0xAA324F90DED86B69L * data[i + 3] 7199 + 0x9CDA5E693FEA10AFL * data[i + 4] 7200 + 0x908E3D2C82567A73L * data[i + 5] 7201 + 0x8538ECB5BD456EA3L * data[i + 6] 7202 + 0xD1B54A32D192ED03L * data[i + 7] 7203 ; 7204 } 7205 for (; i < data.length; i++) { 7206 result = 0x9E3779B97F4A7C15L * result + data[i]; 7207 } 7208 result *= 0x94D049BB133111EBL; 7209 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7210 result *= 0x369DEA0F31A53F85L; 7211 result ^= result >>> 31; 7212 result *= 0xDB4F0B9175AE2165L; 7213 return (result ^ result >>> 28); 7214 } 7215 7216 public static long hash64(final long seed, final int[] data, final int length) { 7217 if (data == null) return 0; 7218 final int len = Math.min(length, data.length); 7219 long result = randomize(seed) ^ len * 0x9E3779B97F4A7C15L; 7220 int i = 0; 7221 for (; i + 7 < len; i += 8) { 7222 result = 0xEBEDEED9D803C815L * result 7223 + 0xD96EB1A810CAAF5FL * data[i] 7224 + 0xC862B36DAF790DD5L * data[i + 1] 7225 + 0xB8ACD90C142FE10BL * data[i + 2] 7226 + 0xAA324F90DED86B69L * data[i + 3] 7227 + 0x9CDA5E693FEA10AFL * data[i + 4] 7228 + 0x908E3D2C82567A73L * data[i + 5] 7229 + 0x8538ECB5BD456EA3L * data[i + 6] 7230 + 0xD1B54A32D192ED03L * data[i + 7] 7231 ; 7232 } 7233 for (; i < len; i++) { 7234 result = 0x9E3779B97F4A7C15L * result + data[i]; 7235 } 7236 result *= 0x94D049BB133111EBL; 7237 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7238 result *= 0x369DEA0F31A53F85L; 7239 result ^= result >>> 31; 7240 result *= 0xDB4F0B9175AE2165L; 7241 return (result ^ result >>> 28); 7242 } 7243 7244 public static long hash64(final long seed, final long[] data) { 7245 if (data == null) return 0; 7246 long s = randomize(seed), a = s + b4, b = s + b3, c = s + b2, d = s + b1; 7247 final int len = data.length; 7248 for (int i = 3; i < len; i+=4) { 7249 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 7250 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 7251 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 7252 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 7253 s += a + b + c + d; 7254 } 7255 s += b5; 7256 switch (len & 3) { 7257 case 1: s = wow(s, b1 ^ data[len-1]); break; 7258 case 2: s = wow(s + data[len-2], b2 + data[len-1]); break; 7259 case 3: s = wow(s + data[len-3], b2 + data[len-2]) ^ wow(s + data[len-1], s ^ b3); break; 7260 } 7261 s = (s ^ s << 16) * (len ^ b0 ^ s >>> 32); 7262 return s - (s >>> 31) + (s << 33); 7263 } 7264 public static long hash64(final long seed, final float[] data) { 7265 if (data == null) return 0; 7266 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7267 int i = 0; 7268 for (; i + 7 < data.length; i += 8) { 7269 result = 0xEBEDEED9D803C815L * result 7270 + 0xD96EB1A810CAAF5FL * floatToIntBits(data[i]) 7271 + 0xC862B36DAF790DD5L * floatToIntBits(data[i + 1]) 7272 + 0xB8ACD90C142FE10BL * floatToIntBits(data[i + 2]) 7273 + 0xAA324F90DED86B69L * floatToIntBits(data[i + 3]) 7274 + 0x9CDA5E693FEA10AFL * floatToIntBits(data[i + 4]) 7275 + 0x908E3D2C82567A73L * floatToIntBits(data[i + 5]) 7276 + 0x8538ECB5BD456EA3L * floatToIntBits(data[i + 6]) 7277 + 0xD1B54A32D192ED03L * floatToIntBits(data[i + 7]) 7278 ; 7279 } 7280 for (; i < data.length; i++) { 7281 result = 0x9E3779B97F4A7C15L * result + floatToIntBits(data[i]); 7282 } 7283 result *= 0x94D049BB133111EBL; 7284 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7285 result *= 0x369DEA0F31A53F85L; 7286 result ^= result >>> 31; 7287 result *= 0xDB4F0B9175AE2165L; 7288 return (result ^ result >>> 28); 7289 } 7290 public static long hash64(final long seed, final double[] data) { 7291 if (data == null) return 0; 7292 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7293 int i = 0; 7294 for (; i + 7 < data.length; i += 8) { 7295 result = 0xEBEDEED9D803C815L * result 7296 + 0xD96EB1A810CAAF5FL * doubleToMixedIntBits(data[i]) 7297 + 0xC862B36DAF790DD5L * doubleToMixedIntBits(data[i + 1]) 7298 + 0xB8ACD90C142FE10BL * doubleToMixedIntBits(data[i + 2]) 7299 + 0xAA324F90DED86B69L * doubleToMixedIntBits(data[i + 3]) 7300 + 0x9CDA5E693FEA10AFL * doubleToMixedIntBits(data[i + 4]) 7301 + 0x908E3D2C82567A73L * doubleToMixedIntBits(data[i + 5]) 7302 + 0x8538ECB5BD456EA3L * doubleToMixedIntBits(data[i + 6]) 7303 + 0xD1B54A32D192ED03L * doubleToMixedIntBits(data[i + 7]) 7304 ; 7305 } 7306 for (; i < data.length; i++) { 7307 result = 0x9E3779B97F4A7C15L * result + doubleToMixedIntBits(data[i]); 7308 } 7309 result *= 0x94D049BB133111EBL; 7310 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7311 result *= 0x369DEA0F31A53F85L; 7312 result ^= result >>> 31; 7313 result *= 0xDB4F0B9175AE2165L; 7314 return (result ^ result >>> 28); 7315 } 7316 7317 /** 7318 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 7319 * 7320 * @param data the char array to hash 7321 * @param start the start of the section to hash (inclusive) 7322 * @param end the end of the section to hash (exclusive) 7323 * @return a 64-bit hash code for the requested section of data 7324 */ 7325 public static long hash64(final long seed, final char[] data, final int start, final int end) { 7326 if (data == null || start >= end) return 0; 7327 final int len = Math.min(end, data.length); 7328 7329 long result = randomize(seed) ^ (len - start) * 0x9E3779B97F4A7C15L; 7330 int i = start; 7331 for (; i + 7 < len; i += 8) { 7332 result = 0xEBEDEED9D803C815L * result 7333 + 0xD96EB1A810CAAF5FL * data[i] 7334 + 0xC862B36DAF790DD5L * data[i + 1] 7335 + 0xB8ACD90C142FE10BL * data[i + 2] 7336 + 0xAA324F90DED86B69L * data[i + 3] 7337 + 0x9CDA5E693FEA10AFL * data[i + 4] 7338 + 0x908E3D2C82567A73L * data[i + 5] 7339 + 0x8538ECB5BD456EA3L * data[i + 6] 7340 + 0xD1B54A32D192ED03L * data[i + 7] 7341 ; 7342 } 7343 for (; i < len; i++) { 7344 result = 0x9E3779B97F4A7C15L * result + data[i]; 7345 } 7346 result *= 0x94D049BB133111EBL; 7347 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7348 result *= 0x369DEA0F31A53F85L; 7349 result ^= result >>> 31; 7350 result *= 0xDB4F0B9175AE2165L; 7351 return (result ^ result >>> 28); 7352 } 7353 7354 /** 7355 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 7356 * 7357 * @param data the String or other CharSequence to hash 7358 * @param start the start of the section to hash (inclusive) 7359 * @param end the end of the section to hash (exclusive) 7360 * @return a 64-bit hash code for the requested section of data 7361 */ 7362 public static long hash64(final long seed, final CharSequence data, final int start, final int end) { 7363 if (data == null || start >= end) return 0; 7364 final int len = Math.min(end, data.length()); 7365 7366 long result = randomize(seed) ^ (len - start) * 0x9E3779B97F4A7C15L; 7367 int i = start; 7368 for (; i + 7 < len; i += 8) { 7369 result = 0xEBEDEED9D803C815L * result 7370 + 0xD96EB1A810CAAF5FL * data.charAt(i) 7371 + 0xC862B36DAF790DD5L * data.charAt(i + 1) 7372 + 0xB8ACD90C142FE10BL * data.charAt(i + 2) 7373 + 0xAA324F90DED86B69L * data.charAt(i + 3) 7374 + 0x9CDA5E693FEA10AFL * data.charAt(i + 4) 7375 + 0x908E3D2C82567A73L * data.charAt(i + 5) 7376 + 0x8538ECB5BD456EA3L * data.charAt(i + 6) 7377 + 0xD1B54A32D192ED03L * data.charAt(i + 7) 7378 ; 7379 } 7380 for (; i < len; i++) { 7381 result = 0x9E3779B97F4A7C15L * result + data.charAt(i); 7382 } 7383 result *= 0x94D049BB133111EBL; 7384 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7385 result *= 0x369DEA0F31A53F85L; 7386 result ^= result >>> 31; 7387 result *= 0xDB4F0B9175AE2165L; 7388 return (result ^ result >>> 28); 7389 } 7390 7391 7392 public static long hash64(final long seed, final char[][] data) { 7393 if (data == null) return 0; 7394 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7395 int i = 0; 7396 for (; i + 7 < data.length; i += 8) { 7397 result = 0xEBEDEED9D803C815L * result 7398 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 7399 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 7400 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 7401 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 7402 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 7403 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 7404 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 7405 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 7406 ; 7407 } 7408 for (; i < data.length; i++) { 7409 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 7410 } 7411 result *= 0x94D049BB133111EBL; 7412 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7413 result *= 0x369DEA0F31A53F85L; 7414 result ^= result >>> 31; 7415 result *= 0xDB4F0B9175AE2165L; 7416 return (result ^ result >>> 28); 7417 } 7418 7419 public static long hash64(final long seed, final int[][] data) { 7420 if (data == null) return 0; 7421 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7422 int i = 0; 7423 for (; i + 7 < data.length; i += 8) { 7424 result = 0xEBEDEED9D803C815L * result 7425 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 7426 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 7427 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 7428 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 7429 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 7430 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 7431 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 7432 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 7433 ; 7434 } 7435 for (; i < data.length; i++) { 7436 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 7437 } 7438 result *= 0x94D049BB133111EBL; 7439 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7440 result *= 0x369DEA0F31A53F85L; 7441 result ^= result >>> 31; 7442 result *= 0xDB4F0B9175AE2165L; 7443 return (result ^ result >>> 28); 7444 } 7445 7446 public static long hash64(final long seed, final long[][] data) { 7447 if (data == null) return 0; 7448 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7449 int i = 0; 7450 for (; i + 7 < data.length; i += 8) { 7451 result = 0xEBEDEED9D803C815L * result 7452 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 7453 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 7454 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 7455 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 7456 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 7457 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 7458 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 7459 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 7460 ; 7461 } 7462 for (; i < data.length; i++) { 7463 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 7464 } 7465 result *= 0x94D049BB133111EBL; 7466 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7467 result *= 0x369DEA0F31A53F85L; 7468 result ^= result >>> 31; 7469 result *= 0xDB4F0B9175AE2165L; 7470 return (result ^ result >>> 28); 7471 } 7472 7473 public static long hash64(final long seed, final CharSequence[] data) { 7474 if (data == null) return 0; 7475 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7476 int i = 0; 7477 for (; i + 7 < data.length; i += 8) { 7478 result = 0xEBEDEED9D803C815L * result 7479 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 7480 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 7481 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 7482 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 7483 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 7484 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 7485 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 7486 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 7487 ; 7488 } 7489 for (; i < data.length; i++) { 7490 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 7491 } 7492 result *= 0x94D049BB133111EBL; 7493 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7494 result *= 0x369DEA0F31A53F85L; 7495 result ^= result >>> 31; 7496 result *= 0xDB4F0B9175AE2165L; 7497 return (result ^ result >>> 28); 7498 } 7499 7500 public static long hash64(final long seed, final CharSequence[]... data) { 7501 if (data == null) return 0; 7502 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7503 int i = 0; 7504 for (; i + 7 < data.length; i += 8) { 7505 result = 0xEBEDEED9D803C815L * result 7506 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 7507 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 7508 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 7509 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 7510 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 7511 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 7512 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 7513 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 7514 ; 7515 } 7516 for (; i < data.length; i++) { 7517 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 7518 } 7519 result *= 0x94D049BB133111EBL; 7520 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7521 result *= 0x369DEA0F31A53F85L; 7522 result ^= result >>> 31; 7523 result *= 0xDB4F0B9175AE2165L; 7524 return (result ^ result >>> 28); 7525 } 7526 7527 public static long hash64(final long seed, final Iterable<? extends CharSequence> data) { 7528 if (data == null) return 0; 7529 long s = randomize(seed); 7530 final Iterator<? extends CharSequence> it = data.iterator(); 7531 int len = 0; 7532 while (it.hasNext()) 7533 { 7534 ++len; 7535 s = mum( 7536 mum(hash(seed, it.next()) ^ b1, (it.hasNext() ? hash(seed, it.next()) ^ b2 ^ ++len : b2)) + s, 7537 mum((it.hasNext() ? hash(seed, it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(seed, it.next()) ^ b4 ^ ++len : b4))); 7538 } 7539 s = (s ^ s << 16) * (len ^ b0); 7540 return s - (s >>> 31) + (s << 33); 7541 } 7542 7543 public static long hash64(final long seed, final List<? extends CharSequence> data) { 7544 if (data == null) return 0; 7545 final int len = data.size(); 7546 long result = randomize(seed) ^ len * 0x9E3779B97F4A7C15L; 7547 int i = 0; 7548 for (; i + 7 < len; i += 8) { 7549 result = 0xEBEDEED9D803C815L * result 7550 + 0xD96EB1A810CAAF5FL * hash(seed, data.get(i)) 7551 + 0xC862B36DAF790DD5L * hash(seed, data.get(i + 1)) 7552 + 0xB8ACD90C142FE10BL * hash(seed, data.get(i + 2)) 7553 + 0xAA324F90DED86B69L * hash(seed, data.get(i + 3)) 7554 + 0x9CDA5E693FEA10AFL * hash(seed, data.get(i + 4)) 7555 + 0x908E3D2C82567A73L * hash(seed, data.get(i + 5)) 7556 + 0x8538ECB5BD456EA3L * hash(seed, data.get(i + 6)) 7557 + 0xD1B54A32D192ED03L * hash(seed, data.get(i + 7)) 7558 ; 7559 } 7560 for (; i < len; i++) { 7561 result = 0x9E3779B97F4A7C15L * result + hash(seed, data.get(i)); 7562 } 7563 result *= 0x94D049BB133111EBL; 7564 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7565 result *= 0x369DEA0F31A53F85L; 7566 result ^= result >>> 31; 7567 result *= 0xDB4F0B9175AE2165L; 7568 return (result ^ result >>> 28); 7569 7570 } 7571 7572 public static long hash64(final long seed, final Object[] data) { 7573 if (data == null) return 0; 7574 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7575 int i = 0; 7576 for (; i + 7 < data.length; i += 8) { 7577 result = 0xEBEDEED9D803C815L * result 7578 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 7579 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 7580 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 7581 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 7582 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 7583 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 7584 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 7585 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 7586 ; 7587 } 7588 for (; i < data.length; i++) { 7589 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 7590 } 7591 result *= 0x94D049BB133111EBL; 7592 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7593 result *= 0x369DEA0F31A53F85L; 7594 result ^= result >>> 31; 7595 result *= 0xDB4F0B9175AE2165L; 7596 return (result ^ result >>> 28); 7597 } 7598 7599 public static long hash64(final long seed, final Object data) { 7600 if (data == null) 7601 return 0; 7602 final long h = (data.hashCode() + randomize(seed)) * 0x9E3779B97F4A7C15L; 7603 return h - (h >>> 31) + (h << 33); 7604 } 7605 7606 public static int hash(final long seed, final boolean[] data) { 7607 if (data == null) return 0; 7608 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7609 int i = 0; 7610 for (; i + 7 < data.length; i += 8) { 7611 result = result * 0xEBEDEED9D803C815L 7612 + (data[i] ? 0xD96EB1A810CAAF5FL : 0xCAAF5FD96EB1A810L) 7613 + (data[i + 1] ? 0xC862B36DAF790DD5L : 0x790DD5C862B36DAFL) 7614 + (data[i + 2] ? 0xB8ACD90C142FE10BL : 0x2FE10BB8ACD90C14L) 7615 + (data[i + 3] ? 0xAA324F90DED86B69L : 0xD86B69AA324F90DEL) 7616 + (data[i + 4] ? 0x9CDA5E693FEA10AFL : 0xEA10AF9CDA5E693FL) 7617 + (data[i + 5] ? 0x908E3D2C82567A73L : 0x567A73908E3D2C82L) 7618 + (data[i + 6] ? 0x8538ECB5BD456EA3L : 0x456EA38538ECB5BDL) 7619 + (data[i + 7] ? 0xD1B54A32D192ED03L : 0x92ED03D1B54A32D1L) 7620 ; 7621 } 7622 for (; i < data.length; i++) { 7623 result = 0x9E3779B97F4A7C15L * result + (data[i] ? 0xEBEDEED9D803C815L : 0xD9D803C815EBEDEEL); 7624 } 7625 result *= 0x94D049BB133111EBL; 7626 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7627 result *= 0x369DEA0F31A53F85L; 7628 result ^= result >>> 31; 7629 result *= 0xDB4F0B9175AE2165L; 7630 return (int)(result ^ result >>> 28); 7631 } 7632 public static int hash(final long seed, final byte[] data) { 7633 if (data == null) return 0; 7634 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7635 int i = 0; 7636 for (; i + 7 < data.length; i += 8) { 7637 result = 0xEBEDEED9D803C815L * result 7638 + 0xD96EB1A810CAAF5FL * data[i] 7639 + 0xC862B36DAF790DD5L * data[i + 1] 7640 + 0xB8ACD90C142FE10BL * data[i + 2] 7641 + 0xAA324F90DED86B69L * data[i + 3] 7642 + 0x9CDA5E693FEA10AFL * data[i + 4] 7643 + 0x908E3D2C82567A73L * data[i + 5] 7644 + 0x8538ECB5BD456EA3L * data[i + 6] 7645 + 0xD1B54A32D192ED03L * data[i + 7] 7646 ; 7647 } 7648 for (; i < data.length; i++) { 7649 result = 0x9E3779B97F4A7C15L * result + data[i]; 7650 } 7651 result *= 0x94D049BB133111EBL; 7652 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7653 result *= 0x369DEA0F31A53F85L; 7654 result ^= result >>> 31; 7655 result *= 0xDB4F0B9175AE2165L; 7656 return (int)(result ^ result >>> 28); 7657 } 7658 7659 public static int hash(final long seed, final short[] data) { 7660 if (data == null) return 0; 7661 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7662 int i = 0; 7663 for (; i + 7 < data.length; i += 8) { 7664 result = 0xEBEDEED9D803C815L * result 7665 + 0xD96EB1A810CAAF5FL * data[i] 7666 + 0xC862B36DAF790DD5L * data[i + 1] 7667 + 0xB8ACD90C142FE10BL * data[i + 2] 7668 + 0xAA324F90DED86B69L * data[i + 3] 7669 + 0x9CDA5E693FEA10AFL * data[i + 4] 7670 + 0x908E3D2C82567A73L * data[i + 5] 7671 + 0x8538ECB5BD456EA3L * data[i + 6] 7672 + 0xD1B54A32D192ED03L * data[i + 7] 7673 ; 7674 } 7675 for (; i < data.length; i++) { 7676 result = 0x9E3779B97F4A7C15L * result + data[i]; 7677 } 7678 result *= 0x94D049BB133111EBL; 7679 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7680 result *= 0x369DEA0F31A53F85L; 7681 result ^= result >>> 31; 7682 result *= 0xDB4F0B9175AE2165L; 7683 return (int)(result ^ result >>> 28); 7684 } 7685 7686 public static int hash(final long seed, final char[] data) { 7687 if (data == null) return 0; 7688 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7689 int i = 0; 7690 for (; i + 7 < data.length; i += 8) { 7691 result = 0xEBEDEED9D803C815L * result 7692 + 0xD96EB1A810CAAF5FL * data[i] 7693 + 0xC862B36DAF790DD5L * data[i + 1] 7694 + 0xB8ACD90C142FE10BL * data[i + 2] 7695 + 0xAA324F90DED86B69L * data[i + 3] 7696 + 0x9CDA5E693FEA10AFL * data[i + 4] 7697 + 0x908E3D2C82567A73L * data[i + 5] 7698 + 0x8538ECB5BD456EA3L * data[i + 6] 7699 + 0xD1B54A32D192ED03L * data[i + 7] 7700 ; 7701 } 7702 for (; i < data.length; i++) { 7703 result = 0x9E3779B97F4A7C15L * result + data[i]; 7704 } 7705 result *= 0x94D049BB133111EBL; 7706 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7707 result *= 0x369DEA0F31A53F85L; 7708 result ^= result >>> 31; 7709 result *= 0xDB4F0B9175AE2165L; 7710 return (int)(result ^ result >>> 28); 7711 } 7712 7713 public static int hash(final long seed, final CharSequence data) { 7714 if (data == null) return 0; 7715 final int length = data.length(); 7716 long result = randomize(seed) ^ length * 0x9E3779B97F4A7C15L; 7717 int i = 0; 7718 for (; i + 7 < length; i += 8) { 7719 result = 0xEBEDEED9D803C815L * result 7720 + 0xD96EB1A810CAAF5FL * data.charAt(i) 7721 + 0xC862B36DAF790DD5L * data.charAt(i + 1) 7722 + 0xB8ACD90C142FE10BL * data.charAt(i + 2) 7723 + 0xAA324F90DED86B69L * data.charAt(i + 3) 7724 + 0x9CDA5E693FEA10AFL * data.charAt(i + 4) 7725 + 0x908E3D2C82567A73L * data.charAt(i + 5) 7726 + 0x8538ECB5BD456EA3L * data.charAt(i + 6) 7727 + 0xD1B54A32D192ED03L * data.charAt(i + 7) 7728 ; 7729 } 7730 for (; i < length; i++) { 7731 result = 0x9E3779B97F4A7C15L * result + data.charAt(i); 7732 } 7733 result *= 0x94D049BB133111EBL; 7734 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7735 result *= 0x369DEA0F31A53F85L; 7736 result ^= result >>> 31; 7737 result *= 0xDB4F0B9175AE2165L; 7738 return (int)(result ^ result >>> 28); 7739 } 7740 7741 public static int hash(final long seed, final int[] data) { 7742 if (data == null) return 0; 7743 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7744 int i = 0; 7745 for (; i + 7 < data.length; i += 8) { 7746 result = 0xEBEDEED9D803C815L * result 7747 + 0xD96EB1A810CAAF5FL * data[i] 7748 + 0xC862B36DAF790DD5L * data[i + 1] 7749 + 0xB8ACD90C142FE10BL * data[i + 2] 7750 + 0xAA324F90DED86B69L * data[i + 3] 7751 + 0x9CDA5E693FEA10AFL * data[i + 4] 7752 + 0x908E3D2C82567A73L * data[i + 5] 7753 + 0x8538ECB5BD456EA3L * data[i + 6] 7754 + 0xD1B54A32D192ED03L * data[i + 7] 7755 ; 7756 } 7757 for (; i < data.length; i++) { 7758 result = 0x9E3779B97F4A7C15L * result + data[i]; 7759 } 7760 result *= 0x94D049BB133111EBL; 7761 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7762 result *= 0x369DEA0F31A53F85L; 7763 result ^= result >>> 31; 7764 result *= 0xDB4F0B9175AE2165L; 7765 return (int)(result ^ result >>> 28); 7766 } 7767 7768 public static int hash(final long seed, final int[] data, final int length) { 7769 if (data == null) return 0; 7770 final int len = Math.min(length, data.length); 7771 long result = randomize(seed) ^ len * 0x9E3779B97F4A7C15L; 7772 int i = 0; 7773 for (; i + 7 < len; i += 8) { 7774 result = 0xEBEDEED9D803C815L * result 7775 + 0xD96EB1A810CAAF5FL * data[i] 7776 + 0xC862B36DAF790DD5L * data[i + 1] 7777 + 0xB8ACD90C142FE10BL * data[i + 2] 7778 + 0xAA324F90DED86B69L * data[i + 3] 7779 + 0x9CDA5E693FEA10AFL * data[i + 4] 7780 + 0x908E3D2C82567A73L * data[i + 5] 7781 + 0x8538ECB5BD456EA3L * data[i + 6] 7782 + 0xD1B54A32D192ED03L * data[i + 7] 7783 ; 7784 } 7785 for (; i < len; i++) { 7786 result = 0x9E3779B97F4A7C15L * result + data[i]; 7787 } 7788 result *= 0x94D049BB133111EBL; 7789 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7790 result *= 0x369DEA0F31A53F85L; 7791 result ^= result >>> 31; 7792 result *= 0xDB4F0B9175AE2165L; 7793 return (int)(result ^ result >>> 28); 7794 } 7795 7796 public static int hash(final long seed, final long[] data) { 7797 if (data == null) return 0; 7798 long s = randomize(seed), a = s + b4, b = s + b3, c = s + b2, d = s + b1; 7799 final int len = data.length; 7800 for (int i = 3; i < len; i+=4) { 7801 a ^= data[i-3] * b1; a = (a << 23 | a >>> 41) * b3; 7802 b ^= data[i-2] * b2; b = (b << 25 | b >>> 39) * b4; 7803 c ^= data[i-1] * b3; c = (c << 29 | c >>> 35) * b5; 7804 d ^= data[i ] * b4; d = (d << 31 | d >>> 33) * b1; 7805 s += a + b + c + d; 7806 } 7807 s += b5; 7808 switch (len & 3) { 7809 case 1: s = wow(s, b1 ^ data[len-1]); break; 7810 case 2: s = wow(s + data[len-2], b2 + data[len-1]); break; 7811 case 3: s = wow(s + data[len-3], b2 + data[len-2]) ^ wow(s + data[len-1], s ^ b3); break; 7812 } 7813 s = (s ^ s << 16) * (len ^ b0 ^ s >>> 32); 7814 return (int)(s - (s >>> 32)); 7815 } 7816 7817 public static int hash(final long seed, final float[] data) { 7818 if (data == null) return 0; 7819 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7820 int i = 0; 7821 for (; i + 7 < data.length; i += 8) { 7822 result = 0xEBEDEED9D803C815L * result 7823 + 0xD96EB1A810CAAF5FL * floatToIntBits(data[i]) 7824 + 0xC862B36DAF790DD5L * floatToIntBits(data[i + 1]) 7825 + 0xB8ACD90C142FE10BL * floatToIntBits(data[i + 2]) 7826 + 0xAA324F90DED86B69L * floatToIntBits(data[i + 3]) 7827 + 0x9CDA5E693FEA10AFL * floatToIntBits(data[i + 4]) 7828 + 0x908E3D2C82567A73L * floatToIntBits(data[i + 5]) 7829 + 0x8538ECB5BD456EA3L * floatToIntBits(data[i + 6]) 7830 + 0xD1B54A32D192ED03L * floatToIntBits(data[i + 7]) 7831 ; 7832 } 7833 for (; i < data.length; i++) { 7834 result = 0x9E3779B97F4A7C15L * result + floatToIntBits(data[i]); 7835 } 7836 result *= 0x94D049BB133111EBL; 7837 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7838 result *= 0x369DEA0F31A53F85L; 7839 result ^= result >>> 31; 7840 result *= 0xDB4F0B9175AE2165L; 7841 return (int)(result ^ result >>> 28); 7842 } 7843 public static int hash(final long seed, final double[] data) { 7844 if (data == null) return 0; 7845 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7846 int i = 0; 7847 for (; i + 7 < data.length; i += 8) { 7848 result = 0xEBEDEED9D803C815L * result 7849 + 0xD96EB1A810CAAF5FL * doubleToMixedIntBits(data[i]) 7850 + 0xC862B36DAF790DD5L * doubleToMixedIntBits(data[i + 1]) 7851 + 0xB8ACD90C142FE10BL * doubleToMixedIntBits(data[i + 2]) 7852 + 0xAA324F90DED86B69L * doubleToMixedIntBits(data[i + 3]) 7853 + 0x9CDA5E693FEA10AFL * doubleToMixedIntBits(data[i + 4]) 7854 + 0x908E3D2C82567A73L * doubleToMixedIntBits(data[i + 5]) 7855 + 0x8538ECB5BD456EA3L * doubleToMixedIntBits(data[i + 6]) 7856 + 0xD1B54A32D192ED03L * doubleToMixedIntBits(data[i + 7]) 7857 ; 7858 } 7859 for (; i < data.length; i++) { 7860 result = 0x9E3779B97F4A7C15L * result + doubleToMixedIntBits(data[i]); 7861 } 7862 result *= 0x94D049BB133111EBL; 7863 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7864 result *= 0x369DEA0F31A53F85L; 7865 result ^= result >>> 31; 7866 result *= 0xDB4F0B9175AE2165L; 7867 return (int)(result ^ result >>> 28); 7868 } 7869 7870 /** 7871 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 7872 * 7873 * @param data the char array to hash 7874 * @param start the start of the section to hash (inclusive) 7875 * @param end the end of the section to hash (exclusive) 7876 * @return a 64-bit hash code for the requested section of data 7877 */ 7878 public static int hash(final long seed, final char[] data, final int start, final int end) { 7879 if (data == null || start >= end) return 0; 7880 final int len = Math.min(end, data.length); 7881 7882 long result = randomize(seed) ^ (len - start) * 0x9E3779B97F4A7C15L; 7883 int i = start; 7884 for (; i + 7 < len; i += 8) { 7885 result = 0xEBEDEED9D803C815L * result 7886 + 0xD96EB1A810CAAF5FL * data[i] 7887 + 0xC862B36DAF790DD5L * data[i + 1] 7888 + 0xB8ACD90C142FE10BL * data[i + 2] 7889 + 0xAA324F90DED86B69L * data[i + 3] 7890 + 0x9CDA5E693FEA10AFL * data[i + 4] 7891 + 0x908E3D2C82567A73L * data[i + 5] 7892 + 0x8538ECB5BD456EA3L * data[i + 6] 7893 + 0xD1B54A32D192ED03L * data[i + 7] 7894 ; 7895 } 7896 for (; i < len; i++) { 7897 result = 0x9E3779B97F4A7C15L * result + data[i]; 7898 } 7899 result *= 0x94D049BB133111EBL; 7900 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7901 result *= 0x369DEA0F31A53F85L; 7902 result ^= result >>> 31; 7903 result *= 0xDB4F0B9175AE2165L; 7904 return (int)(result ^ result >>> 28); 7905 } 7906 7907 /** 7908 * Hashes only a subsection of the given data, starting at start (inclusive) and ending before end (exclusive). 7909 * 7910 * @param data the String or other CharSequence to hash 7911 * @param start the start of the section to hash (inclusive) 7912 * @param end the end of the section to hash (exclusive) 7913 * @return a 64-bit hash code for the requested section of data 7914 */ 7915 public static int hash(final long seed, final CharSequence data, final int start, final int end) { 7916 if (data == null || start >= end) return 0; 7917 final int len = Math.min(end, data.length()); 7918 7919 long result = randomize(seed) ^ (len - start) * 0x9E3779B97F4A7C15L; 7920 int i = start; 7921 for (; i + 7 < len; i += 8) { 7922 result = 0xEBEDEED9D803C815L * result 7923 + 0xD96EB1A810CAAF5FL * data.charAt(i) 7924 + 0xC862B36DAF790DD5L * data.charAt(i + 1) 7925 + 0xB8ACD90C142FE10BL * data.charAt(i + 2) 7926 + 0xAA324F90DED86B69L * data.charAt(i + 3) 7927 + 0x9CDA5E693FEA10AFL * data.charAt(i + 4) 7928 + 0x908E3D2C82567A73L * data.charAt(i + 5) 7929 + 0x8538ECB5BD456EA3L * data.charAt(i + 6) 7930 + 0xD1B54A32D192ED03L * data.charAt(i + 7) 7931 ; 7932 } 7933 for (; i < len; i++) { 7934 result = 0x9E3779B97F4A7C15L * result + data.charAt(i); 7935 } 7936 result *= 0x94D049BB133111EBL; 7937 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7938 result *= 0x369DEA0F31A53F85L; 7939 result ^= result >>> 31; 7940 result *= 0xDB4F0B9175AE2165L; 7941 return (int)(result ^ result >>> 28); 7942 } 7943 7944 7945 public static int hash(final long seed, final char[][] data) { 7946 if (data == null) return 0; 7947 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7948 int i = 0; 7949 for (; i + 7 < data.length; i += 8) { 7950 result = 0xEBEDEED9D803C815L * result 7951 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 7952 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 7953 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 7954 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 7955 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 7956 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 7957 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 7958 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 7959 ; 7960 } 7961 for (; i < data.length; i++) { 7962 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 7963 } 7964 result *= 0x94D049BB133111EBL; 7965 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7966 result *= 0x369DEA0F31A53F85L; 7967 result ^= result >>> 31; 7968 result *= 0xDB4F0B9175AE2165L; 7969 return (int)(result ^ result >>> 28); 7970 } 7971 7972 public static int hash(final long seed, final int[][] data) { 7973 if (data == null) return 0; 7974 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 7975 int i = 0; 7976 for (; i + 7 < data.length; i += 8) { 7977 result = 0xEBEDEED9D803C815L * result 7978 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 7979 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 7980 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 7981 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 7982 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 7983 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 7984 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 7985 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 7986 ; 7987 } 7988 for (; i < data.length; i++) { 7989 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 7990 } 7991 result *= 0x94D049BB133111EBL; 7992 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 7993 result *= 0x369DEA0F31A53F85L; 7994 result ^= result >>> 31; 7995 result *= 0xDB4F0B9175AE2165L; 7996 return (int)(result ^ result >>> 28); 7997 } 7998 7999 public static int hash(final long seed, final long[][] data) { 8000 if (data == null) return 0; 8001 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 8002 int i = 0; 8003 for (; i + 7 < data.length; i += 8) { 8004 result = 0xEBEDEED9D803C815L * result 8005 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 8006 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 8007 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 8008 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 8009 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 8010 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 8011 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 8012 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 8013 ; 8014 } 8015 for (; i < data.length; i++) { 8016 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 8017 } 8018 result *= 0x94D049BB133111EBL; 8019 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 8020 result *= 0x369DEA0F31A53F85L; 8021 result ^= result >>> 31; 8022 result *= 0xDB4F0B9175AE2165L; 8023 return (int)(result ^ result >>> 28); 8024 } 8025 8026 public static int hash(final long seed, final CharSequence[] data) { 8027 if (data == null) return 0; 8028 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 8029 int i = 0; 8030 for (; i + 7 < data.length; i += 8) { 8031 result = 0xEBEDEED9D803C815L * result 8032 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 8033 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 8034 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 8035 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 8036 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 8037 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 8038 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 8039 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 8040 ; 8041 } 8042 for (; i < data.length; i++) { 8043 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 8044 } 8045 result *= 0x94D049BB133111EBL; 8046 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 8047 result *= 0x369DEA0F31A53F85L; 8048 result ^= result >>> 31; 8049 result *= 0xDB4F0B9175AE2165L; 8050 return (int)(result ^ result >>> 28); 8051 } 8052 8053 public static int hash(final long seed, final CharSequence[]... data) { 8054 if (data == null) return 0; 8055 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 8056 int i = 0; 8057 for (; i + 7 < data.length; i += 8) { 8058 result = 0xEBEDEED9D803C815L * result 8059 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 8060 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 8061 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 8062 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 8063 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 8064 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 8065 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 8066 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 8067 ; 8068 } 8069 for (; i < data.length; i++) { 8070 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 8071 } 8072 result *= 0x94D049BB133111EBL; 8073 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 8074 result *= 0x369DEA0F31A53F85L; 8075 result ^= result >>> 31; 8076 result *= 0xDB4F0B9175AE2165L; 8077 return (int)(result ^ result >>> 28); 8078 } 8079 8080 public static int hash(final long seed, final Iterable<? extends CharSequence> data) { 8081 if (data == null) return 0; 8082 long s = randomize(seed); 8083 final Iterator<? extends CharSequence> it = data.iterator(); 8084 int len = 0; 8085 while (it.hasNext()) 8086 { 8087 ++len; 8088 s = mum( 8089 mum(hash(seed, it.next()) ^ b1, (it.hasNext() ? hash(seed, it.next()) ^ b2 ^ ++len : b2)) + s, 8090 mum((it.hasNext() ? hash(seed, it.next()) ^ b3 ^ ++len : b3), (it.hasNext() ? hash(seed, it.next()) ^ b4 ^ ++len : b4))); 8091 } 8092 return (int) mum(s ^ s << 16, len ^ b0); 8093 } 8094 8095 public static int hash(final long seed, final List<? extends CharSequence> data) { 8096 if (data == null) return 0; 8097 final int len = data.size(); 8098 long result = randomize(seed) ^ len * 0x9E3779B97F4A7C15L; 8099 int i = 0; 8100 for (; i + 7 < len; i += 8) { 8101 result = 0xEBEDEED9D803C815L * result 8102 + 0xD96EB1A810CAAF5FL * hash(seed, data.get(i)) 8103 + 0xC862B36DAF790DD5L * hash(seed, data.get(i + 1)) 8104 + 0xB8ACD90C142FE10BL * hash(seed, data.get(i + 2)) 8105 + 0xAA324F90DED86B69L * hash(seed, data.get(i + 3)) 8106 + 0x9CDA5E693FEA10AFL * hash(seed, data.get(i + 4)) 8107 + 0x908E3D2C82567A73L * hash(seed, data.get(i + 5)) 8108 + 0x8538ECB5BD456EA3L * hash(seed, data.get(i + 6)) 8109 + 0xD1B54A32D192ED03L * hash(seed, data.get(i + 7)) 8110 ; 8111 } 8112 for (; i < len; i++) { 8113 result = 0x9E3779B97F4A7C15L * result + hash(seed, data.get(i)); 8114 } 8115 result *= 0x94D049BB133111EBL; 8116 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 8117 result *= 0x369DEA0F31A53F85L; 8118 result ^= result >>> 31; 8119 result *= 0xDB4F0B9175AE2165L; 8120 return (int)(result ^ result >>> 28); 8121 8122 } 8123 8124 public static int hash(final long seed, final Object[] data) { 8125 if (data == null) return 0; 8126 long result = randomize(seed) ^ data.length * 0x9E3779B97F4A7C15L; 8127 int i = 0; 8128 for (; i + 7 < data.length; i += 8) { 8129 result = 0xEBEDEED9D803C815L * result 8130 + 0xD96EB1A810CAAF5FL * hash(seed, data[i]) 8131 + 0xC862B36DAF790DD5L * hash(seed, data[i + 1]) 8132 + 0xB8ACD90C142FE10BL * hash(seed, data[i + 2]) 8133 + 0xAA324F90DED86B69L * hash(seed, data[i + 3]) 8134 + 0x9CDA5E693FEA10AFL * hash(seed, data[i + 4]) 8135 + 0x908E3D2C82567A73L * hash(seed, data[i + 5]) 8136 + 0x8538ECB5BD456EA3L * hash(seed, data[i + 6]) 8137 + 0xD1B54A32D192ED03L * hash(seed, data[i + 7]) 8138 ; 8139 } 8140 for (; i < data.length; i++) { 8141 result = 0x9E3779B97F4A7C15L * result + hash(seed, data[i]); 8142 } 8143 result *= 0x94D049BB133111EBL; 8144 result ^= (result << 41 | result >>> 23) ^ (result << 17 | result >>> 47); 8145 result *= 0x369DEA0F31A53F85L; 8146 result ^= result >>> 31; 8147 result *= 0xDB4F0B9175AE2165L; 8148 return (int)(result ^ result >>> 28); 8149 } 8150 8151 public static int hash(final long seed, final Object data) { 8152 if (data == null) return 0; 8153 return (int)((data.hashCode() + randomize(seed)) * 0x9E3779B97F4A7C15L >>> 32); 8154 } 8155 8156 } 8157}