package com.carrotsearch.hppc;

import java.security.PrivilegedAction;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;

Factory methods to acquire the most common types of HashOrderMixingStrategy.
See Also:
/** * Factory methods to acquire the most common types of * {@link HashOrderMixingStrategy}. * * @see HashOrderMixingStrategy */
public final class HashOrderMixing { public static final String PROPERTY_BIT_MIXER = "hppc.bitmixer"; private static Strategy strategy; public enum Strategy implements Callable<HashOrderMixingStrategy> { RANDOM { @Override public HashOrderMixingStrategy call() { return randomized(); } }, DETERMINISTIC { @Override public HashOrderMixingStrategy call() { return deterministic(); } }, NONE { @Override public HashOrderMixingStrategy call() { return none(); } }; } private HashOrderMixing() {}
See Also:
  • deterministic()
/** * @see #deterministic() */
private static final HashOrderMixingStrategy DETERMINISTIC = new HashOrderMixingStrategy() { @Override public int newKeyMixer(int newContainerBufferSize) { return BitMixer.mix32(newContainerBufferSize); } @Override public HashOrderMixingStrategy clone() { return this; } };
Returns a randomized HashOrderMixingStrategy that issues unique per-container seed. This minimizes the chances of hash distribution conflicts.
/** * Returns a randomized {@link HashOrderMixingStrategy} that issues unique * per-container seed. This minimizes the chances of hash distribution conflicts. */
public static HashOrderMixingStrategy randomized() { return RandomizedHashOrderMixer.INSTANCE; }
A constant HashOrderMixingStrategy. This is useful if one needs to have deterministic key distribution but wishes to control it manually. Do not use the same constant for more than one container. Consider using scatter maps or sets instead of constant hash order mixer.
/** * A constant {@link HashOrderMixingStrategy}. This is useful if one needs to have * deterministic key distribution but wishes to control it manually. * * Do not use the same constant for more than one container. * * Consider using {@linkplain ObjectScatterSet scatter maps or sets} instead * of constant hash order mixer. */
public static HashOrderMixingStrategy constant(final long seed) { return new HashOrderMixingStrategy() { @Override public int newKeyMixer(int newContainerBufferSize) { return (int) BitMixer.mix64(newContainerBufferSize ^ seed); } @Override public HashOrderMixingStrategy clone() { return this; } }; }
Deterministic HashOrderMixingStrategy will reorder keys depending on the size of the container's buffer. This is inherently unsafe with hash containers using linear conflict addressing. The only use case when this can be useful is to count/ collect unique keys (for which scatter tables should be used).
Deprecated:Permanently deprecated as a warning signal.
/** * Deterministic {@link HashOrderMixingStrategy} will reorder keys depending * on the size of the container's buffer. * * This is inherently unsafe with hash containers using linear conflict * addressing. The only use case when this can be useful is to count/ collect * unique keys (for which scatter tables should be used). * * @deprecated Permanently deprecated as a warning signal. */
@Deprecated public static HashOrderMixingStrategy deterministic() { return DETERMINISTIC; }
This strategy does not change the hash order of keys at all. This is inherently unsafe with hash containers using linear conflict addressing. The only use case when this can be useful is to count/ collect unique keys (for which scatter tables should be used).
Deprecated:Permanently deprecated as a warning signal.
/** * This strategy does not change the hash order of keys at all. This * is inherently unsafe with hash containers using linear conflict * addressing. The only use case when this can be useful is to count/ collect * unique keys (for which scatter tables should be used). * * @deprecated Permanently deprecated as a warning signal. */
@Deprecated public static HashOrderMixingStrategy none() { return new HashOrderMixingStrategy() { @Override public int newKeyMixer(int newContainerBufferSize) { return 0; } @Override public HashOrderMixingStrategy clone() { return this; } }; }
Returns the currently configured default HashOrderMixingStrategy.
/** * Returns the currently configured default {@link HashOrderMixingStrategy}. */
public static HashOrderMixingStrategy defaultStrategy() { if (strategy == null) { try { String propValue = java.security.AccessController.doPrivileged(new PrivilegedAction<String>() { @Override public String run() { return System.getProperty(PROPERTY_BIT_MIXER); } }); if (propValue != null) { for (Strategy s : Strategy.values()) { if (s.name().equalsIgnoreCase(propValue)) { strategy = s; break; } } } } catch (SecurityException e) { // If failed on security exception, don't panic. Logger.getLogger(Containers.class.getName()) .log(Level.INFO, "Failed to read 'tests.seed' property for initial random seed.", e); } if (strategy == null) { strategy = Strategy.RANDOM; } } try { return strategy.call(); } catch (Exception e) { throw new RuntimeException(e); // Effectively unreachable. } } }