7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package sun.misc;
26
27 import java.util.Random;
28
29 /**
30 * Hashing utilities.
31 *
32 * Little endian implementations of Murmur3 hashing.
33 */
34 public class Hashing {
35
36 /**
37 * Static utility methods only.
38 */
39 private Hashing() {
40 throw new Error("No instances");
41 }
42
43 public static int murmur3_32(byte[] data) {
44 return murmur3_32(0, data, 0, data.length);
45 }
46
47 public static int murmur3_32(int seed, byte[] data) {
196
197 h1 ^= len * (Integer.SIZE / Byte.SIZE);
198
199 // finalization mix force all bits of a hash block to avalanche
200 h1 ^= h1 >>> 16;
201 h1 *= 0x85ebca6b;
202 h1 ^= h1 >>> 13;
203 h1 *= 0xc2b2ae35;
204 h1 ^= h1 >>> 16;
205
206 return h1;
207 }
208
209 /**
210 * Holds references to things that can't be initialized until after VM
211 * is fully booted.
212 */
213 private static class Holder {
214
215 /**
216 * Used for generating per-instance hash seeds.
217 *
218 * We try to improve upon the default seeding.
219 */
220 static final Random SEED_MAKER = new Random(
221 Double.doubleToRawLongBits(Math.random())
222 ^ System.identityHashCode(Hashing.class)
223 ^ System.currentTimeMillis()
224 ^ System.nanoTime()
225 ^ Runtime.getRuntime().freeMemory());
226
227 /**
228 * Access to {@code String.hash32()}
229 */
230 static final JavaLangAccess LANG_ACCESS;
231
232 static {
233 LANG_ACCESS = SharedSecrets.getJavaLangAccess();
234 if (null == LANG_ACCESS) {
235 throw new Error("Shared secrets not initialized");
236 }
237 }
238 }
239
240 /**
241 * Return a 32 bit hash value for the specified string. The algorithm is
242 * unspecified but will be consistent within a VM instance.
243 *
244 * @param string String to be hashed.
245 * @return hash value of the string.
246 */
247 public static int stringHash32(String string) {
248 return Holder.LANG_ACCESS.getStringHash32(string);
249 }
250
251 public static int randomHashSeed(Object instance) {
252 int seed;
253 if (sun.misc.VM.isBooted()) {
254 seed = Holder.SEED_MAKER.nextInt();
255 } else {
256 // lower quality "random" seed value--still better than zero and not
257 // not practically reversible.
258 int hashing_seed[] = {
259 System.identityHashCode(Hashing.class),
260 System.identityHashCode(instance),
261 System.identityHashCode(Thread.currentThread()),
262 (int) Thread.currentThread().getId(),
263 (int) (System.currentTimeMillis() >>> 2), // resolution is poor
264 (int) (System.nanoTime() >>> 5), // resolution is poor
265 (int) (Runtime.getRuntime().freeMemory() >>> 4) // alloc min
266 };
267
268 seed = murmur3_32(hashing_seed);
269 }
270
271 // force to non-zero.
272 return (0 != seed) ? seed : 1;
273 }
274 }
|
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package sun.misc;
26
27 import java.util.concurrent.ThreadLocalRandom;
28
29 /**
30 * Hashing utilities.
31 *
32 * Little endian implementations of Murmur3 hashing.
33 */
34 public class Hashing {
35
36 /**
37 * Static utility methods only.
38 */
39 private Hashing() {
40 throw new Error("No instances");
41 }
42
43 public static int murmur3_32(byte[] data) {
44 return murmur3_32(0, data, 0, data.length);
45 }
46
47 public static int murmur3_32(int seed, byte[] data) {
196
197 h1 ^= len * (Integer.SIZE / Byte.SIZE);
198
199 // finalization mix force all bits of a hash block to avalanche
200 h1 ^= h1 >>> 16;
201 h1 *= 0x85ebca6b;
202 h1 ^= h1 >>> 13;
203 h1 *= 0xc2b2ae35;
204 h1 ^= h1 >>> 16;
205
206 return h1;
207 }
208
209 /**
210 * Holds references to things that can't be initialized until after VM
211 * is fully booted.
212 */
213 private static class Holder {
214
215 /**
216 * Access to {@code String.hash32()}
217 */
218 static final JavaLangAccess LANG_ACCESS;
219
220 static {
221 LANG_ACCESS = SharedSecrets.getJavaLangAccess();
222 if (null == LANG_ACCESS) {
223 throw new Error("Shared secrets not initialized");
224 }
225 }
226 }
227
228 /**
229 * Return a 32 bit hash value for the specified string. The algorithm is
230 * unspecified but will be consistent within a VM instance.
231 *
232 * @param string String to be hashed.
233 * @return hash value of the string.
234 */
235 public static int stringHash32(String string) {
236 return Holder.LANG_ACCESS.getStringHash32(string);
237 }
238
239 /**
240 * Return a non-zero 32-bit pseudo random value. The {@code instance} object
241 * may be used as part of the value.
242 *
243 * @param instance an object to use if desired in choosing value.
244 * @return a non-zero 32-bit pseudo random value.
245 */
246 public static int randomHashSeed(Object instance) {
247 int seed;
248 if (sun.misc.VM.isBooted()) {
249 seed = ThreadLocalRandom.current().nextInt();
250 } else {
251 // lower quality "random" seed value--still better than zero and not
252 // not practically reversible.
253 int hashing_seed[] = {
254 System.identityHashCode(Hashing.class),
255 System.identityHashCode(instance),
256 System.identityHashCode(Thread.currentThread()),
257 (int) Thread.currentThread().getId(),
258 (int) (System.currentTimeMillis() >>> 2), // resolution is poor
259 (int) (System.nanoTime() >>> 5), // resolution is poor
260 (int) (Runtime.getRuntime().freeMemory() >>> 4) // alloc min
261 };
262
263 seed = murmur3_32(hashing_seed);
264 }
265
266 // force to non-zero.
267 return (0 != seed) ? seed : 1;
268 }
269 }
|