Skip to content

Instantly share code, notes, and snippets.

@AFaust
Created June 20, 2019 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AFaust/e52ca1008a71b3e386a34f0fa63274be to your computer and use it in GitHub Desktop.
Save AFaust/e52ca1008a71b3e386a34f0fa63274be to your computer and use it in GitHub Desktop.
Unit test for using complex cache keys in Apache Ignite - sample for question on Ignite mailing list
import java.io.Serializable;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.eviction.lru.LruEvictionPolicyFactory;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.junit.Assert;
import org.junit.Test;
/**
* The tests in this class mostly exist to validate the known / expected behaviour of the default Ignite caches when it comes to handling
* custom, complex cache keys.
*
* @author Axel Faust
*/
public class ComplexCacheKeyTests
{
/**
* Instances of this cache key class use all members to calculate a hash code and have to equal in all fields to be considered
* identical.
*
* @author Axel Faust
*/
protected static class CacheKeyWithOnlyHashRelevantFields implements Serializable
{
private static final long serialVersionUID = -7547582421808635360L;
private final String hashRelevant1;
private final String hashRelevant2;
protected CacheKeyWithOnlyHashRelevantFields(final String hashRelevant, final String hashRelevant2)
{
this.hashRelevant1 = hashRelevant;
this.hashRelevant2 = hashRelevant2;
}
/**
* @return the hashRelevant1
*/
public String getHashRelevant1()
{
return this.hashRelevant1;
}
/**
* @return the hashRelevant2
*/
public String getHashRelevant2()
{
return this.hashRelevant2;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((this.hashRelevant1 == null) ? 0 : this.hashRelevant1.hashCode());
result = prime * result + ((this.hashRelevant2 == null) ? 0 : this.hashRelevant2.hashCode());
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(final Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (this.getClass() != obj.getClass())
{
return false;
}
final CacheKeyWithOnlyHashRelevantFields other = (CacheKeyWithOnlyHashRelevantFields) obj;
if (this.hashRelevant1 == null)
{
if (other.hashRelevant1 != null)
{
return false;
}
}
else if (!this.hashRelevant1.equals(other.hashRelevant1))
{
return false;
}
if (this.hashRelevant2 == null)
{
if (other.hashRelevant2 != null)
{
return false;
}
}
else if (!this.hashRelevant2.equals(other.hashRelevant2))
{
return false;
}
return true;
}
}
/**
* Instances of this cache key class use only one member to calculate a hash code and only have to equal in that field to be considered
* identical. Thus multiple instances with different values for the non-relevant member can map to the same value if used in maps etc.
*
* @author Axel Faust
*/
protected static class CacheKeyWithNonHashRelevantFields implements Serializable
{
private static final long serialVersionUID = -2814524389206953667L;
private final String hashRelevant;
private final String nonHashRelevant;
protected CacheKeyWithNonHashRelevantFields(final String hashRelevant, final String nonHashRelevant)
{
this.hashRelevant = hashRelevant;
this.nonHashRelevant = nonHashRelevant;
}
/**
* @return the hashRelevant
*/
public String getHashRelevant()
{
return this.hashRelevant;
}
/**
* @return the nonHashRelevant
*/
public String getNonHashRelevant()
{
return this.nonHashRelevant;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((this.hashRelevant == null) ? 0 : this.hashRelevant.hashCode());
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(final Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (this.getClass() != obj.getClass())
{
return false;
}
final CacheKeyWithNonHashRelevantFields other = (CacheKeyWithNonHashRelevantFields) obj;
if (this.hashRelevant == null)
{
if (other.hashRelevant != null)
{
return false;
}
}
else if (!this.hashRelevant.equals(other.hashRelevant))
{
return false;
}
return true;
}
}
@Test
public void simpleCacheKeysOnHeap()
{
// base line test for trivial cache keys
try
{
final IgniteConfiguration conf = new IgniteConfiguration();
conf.setIgniteInstanceName("simpleCacheKeysOnHeap");
final CacheConfiguration<String, String> cacheConfig = new CacheConfiguration<>();
cacheConfig.setName("testCache");
cacheConfig.setCacheMode(CacheMode.LOCAL);
final LruEvictionPolicyFactory<String, String> evictionPolicyFactory = new LruEvictionPolicyFactory<>(1000);
cacheConfig.setOnheapCacheEnabled(true);
cacheConfig.setEvictionPolicyFactory(evictionPolicyFactory);
final Ignite grid = Ignition.start(conf);
final IgniteCache<String, String> cache = grid.getOrCreateCache(cacheConfig);
final String baseKey = "key1";
final String baseValue = "value1";
cache.put(baseKey, baseValue);
String key = baseKey;
String value = cache.get(key);
Assert.assertEquals(baseValue, value);
// force new instance
key = new String(baseKey);
value = cache.get(key);
Assert.assertEquals(baseValue, value);
key = baseKey + "Suffix";
value = cache.get(key);
Assert.assertNotEquals(baseValue, value);
Assert.assertNull(value);
}
finally
{
Ignition.stopAll(true);
}
}
@Test
public void simpleCacheKeysOffHeap()
{
// base line test for trivial cache keys
try
{
final IgniteConfiguration conf = new IgniteConfiguration();
conf.setIgniteInstanceName("simpleCacheKeysOffHeap");
final CacheConfiguration<String, String> cacheConfig = new CacheConfiguration<>();
cacheConfig.setName("testCache");
cacheConfig.setCacheMode(CacheMode.LOCAL);
final Ignite grid = Ignition.start(conf);
final IgniteCache<String, String> cache = grid.getOrCreateCache(cacheConfig);
final String baseKey = "key1";
final String baseValue = "value1";
cache.put(baseKey, baseValue);
String key = baseKey;
String value = cache.get(key);
Assert.assertEquals(baseValue, value);
// force new instance
key = new String(baseKey);
value = cache.get(key);
Assert.assertEquals(baseValue, value);
key = baseKey + "Suffix";
value = cache.get(key);
Assert.assertNotEquals(baseValue, value);
Assert.assertNull(value);
}
finally
{
Ignition.stopAll(true);
}
}
@Test
public void complexKeyWithAllRelevantFieldsOnHeap()
{
try
{
final IgniteConfiguration conf = new IgniteConfiguration();
conf.setIgniteInstanceName("complexKeyWithAllRelevantFieldsOnHeap");
final CacheConfiguration<CacheKeyWithOnlyHashRelevantFields, String> cacheConfig = new CacheConfiguration<>();
cacheConfig.setName("testCache");
cacheConfig.setCacheMode(CacheMode.LOCAL);
final LruEvictionPolicyFactory<CacheKeyWithOnlyHashRelevantFields, String> evictionPolicyFactory = new LruEvictionPolicyFactory<>(
1000);
cacheConfig.setOnheapCacheEnabled(true);
cacheConfig.setEvictionPolicyFactory(evictionPolicyFactory);
final Ignite grid = Ignition.start(conf);
final IgniteCache<CacheKeyWithOnlyHashRelevantFields, String> cache = grid.getOrCreateCache(cacheConfig);
final CacheKeyWithOnlyHashRelevantFields baseKey = new CacheKeyWithOnlyHashRelevantFields("keyPart1", "keyPart2");
final String baseValue = "value1";
cache.put(baseKey, baseValue);
CacheKeyWithOnlyHashRelevantFields key = baseKey;
String value = cache.get(key);
Assert.assertEquals(baseValue, value);
key = new CacheKeyWithOnlyHashRelevantFields(baseKey.getHashRelevant1(), baseKey.getHashRelevant2());
value = cache.get(key);
Assert.assertEquals(baseValue, value);
key = new CacheKeyWithOnlyHashRelevantFields(baseKey.getHashRelevant1(), "keyPartX");
value = cache.get(key);
Assert.assertNotEquals(baseValue, value);
Assert.assertNull(value);
}
finally
{
Ignition.stopAll(true);
}
}
@Test
public void complexKeyWithAllRelevantFieldsOffHeap()
{
try
{
final IgniteConfiguration conf = new IgniteConfiguration();
conf.setIgniteInstanceName("complexKeyWithAllRelevantFieldsOffHeap");
final CacheConfiguration<CacheKeyWithOnlyHashRelevantFields, String> cacheConfig = new CacheConfiguration<>();
cacheConfig.setName("testCache");
cacheConfig.setCacheMode(CacheMode.LOCAL);
final Ignite grid = Ignition.start(conf);
final IgniteCache<CacheKeyWithOnlyHashRelevantFields, String> cache = grid.getOrCreateCache(cacheConfig);
final CacheKeyWithOnlyHashRelevantFields baseKey = new CacheKeyWithOnlyHashRelevantFields("keyPart1", "keyPart2");
final String baseValue = "value1";
cache.put(baseKey, baseValue);
CacheKeyWithOnlyHashRelevantFields key = baseKey;
String value = cache.get(key);
Assert.assertEquals(baseValue, value);
key = new CacheKeyWithOnlyHashRelevantFields(baseKey.getHashRelevant1(), baseKey.getHashRelevant2());
value = cache.get(key);
Assert.assertEquals(baseValue, value);
key = new CacheKeyWithOnlyHashRelevantFields(baseKey.getHashRelevant1(), "keyPartX");
value = cache.get(key);
Assert.assertNotEquals(baseValue, value);
Assert.assertNull(value);
}
finally
{
Ignition.stopAll(true);
}
}
@Test
public void complexKeyWithNonRelevantFieldsOnHeap()
{
try
{
final IgniteConfiguration conf = new IgniteConfiguration();
conf.setIgniteInstanceName("complexKeyWithNonRelevantFieldsOnHeap");
final CacheConfiguration<CacheKeyWithNonHashRelevantFields, String> cacheConfig = new CacheConfiguration<>();
cacheConfig.setName("testCache");
cacheConfig.setCacheMode(CacheMode.LOCAL);
final LruEvictionPolicyFactory<CacheKeyWithNonHashRelevantFields, String> evictionPolicyFactory = new LruEvictionPolicyFactory<>(
1000);
cacheConfig.setOnheapCacheEnabled(true);
cacheConfig.setEvictionPolicyFactory(evictionPolicyFactory);
final Ignite grid = Ignition.start(conf);
final IgniteCache<CacheKeyWithNonHashRelevantFields, String> cache = grid.getOrCreateCache(cacheConfig);
final CacheKeyWithNonHashRelevantFields baseKey = new CacheKeyWithNonHashRelevantFields("keyPart1", "keyPart2");
final String baseValue = "value1";
cache.put(baseKey, baseValue);
CacheKeyWithNonHashRelevantFields key = baseKey;
String value = cache.get(key);
Assert.assertEquals(baseValue, value);
// force new instance
key = new CacheKeyWithNonHashRelevantFields(baseKey.getHashRelevant(), baseKey.getNonHashRelevant());
value = cache.get(key);
Assert.assertEquals(baseValue, value);
// force new instance with different non-hash relevant component
key = new CacheKeyWithNonHashRelevantFields(baseKey.getHashRelevant(), "keyPartX");
value = cache.get(key);
Assert.assertEquals(baseValue, value);
// force new instance with non-hash relevant component set to no specific value
key = new CacheKeyWithNonHashRelevantFields(baseKey.getHashRelevant(), null);
value = cache.get(key);
Assert.assertEquals(baseValue, value);
key = new CacheKeyWithNonHashRelevantFields("keyPartX", baseKey.getNonHashRelevant());
value = cache.get(key);
Assert.assertNotEquals(baseValue, value);
Assert.assertNull(value);
}
finally
{
Ignition.stopAll(true);
}
}
@Test
public void complexKeyWithNonRelevantFieldsOffHeap()
{
try
{
final IgniteConfiguration conf = new IgniteConfiguration();
conf.setIgniteInstanceName("complexKeyWithNonRelevantFieldsOffHeap");
final CacheConfiguration<CacheKeyWithNonHashRelevantFields, String> cacheConfig = new CacheConfiguration<>();
cacheConfig.setName("testCache");
cacheConfig.setCacheMode(CacheMode.LOCAL);
final Ignite grid = Ignition.start(conf);
final IgniteCache<CacheKeyWithNonHashRelevantFields, String> cache = grid.getOrCreateCache(cacheConfig);
final CacheKeyWithNonHashRelevantFields baseKey = new CacheKeyWithNonHashRelevantFields("keyPart1", "keyPart2");
final String baseValue = "value1";
cache.put(baseKey, baseValue);
CacheKeyWithNonHashRelevantFields key = baseKey;
String value = cache.get(key);
Assert.assertEquals(baseValue, value);
// force new instance
key = new CacheKeyWithNonHashRelevantFields(baseKey.getHashRelevant(), baseKey.getNonHashRelevant());
value = cache.get(key);
Assert.assertEquals(baseValue, value);
// force new instance with different non-hash relevant component
key = new CacheKeyWithNonHashRelevantFields(baseKey.getHashRelevant(), "keyPartX");
value = cache.get(key);
Assert.assertEquals(baseValue, value);
// force new instance with non-hash relevant component set to no specific value
key = new CacheKeyWithNonHashRelevantFields(baseKey.getHashRelevant(), null);
value = cache.get(key);
Assert.assertEquals(baseValue, value);
key = new CacheKeyWithNonHashRelevantFields("keyPartX", baseKey.getNonHashRelevant());
value = cache.get(key);
Assert.assertNotEquals(baseValue, value);
Assert.assertNull(value);
}
finally
{
Ignition.stopAll(true);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment