| /*========================================================================= |
| * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. |
| * This product is protected by U.S. and international copyright |
| * and intellectual property laws. Pivotal products are covered by |
| * one or more patents listed at http://www.pivotal.io/patents. |
| *========================================================================= |
| */ |
| package com.gemstone.gemfire.cache.query.internal.index; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.io.Serializable; |
| import java.text.ParseException; |
| import java.util.Collection; |
| import java.util.Iterator; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.experimental.categories.Category; |
| |
| import com.gemstone.gemfire.cache.AttributesFactory; |
| import com.gemstone.gemfire.cache.Cache; |
| import com.gemstone.gemfire.cache.DataPolicy; |
| import com.gemstone.gemfire.cache.EvictionAction; |
| import com.gemstone.gemfire.cache.EvictionAttributes; |
| import com.gemstone.gemfire.cache.PartitionAttributesFactory; |
| import com.gemstone.gemfire.cache.Region; |
| import com.gemstone.gemfire.cache.RegionAttributes; |
| import com.gemstone.gemfire.cache.RegionShortcut; |
| import com.gemstone.gemfire.cache.query.CacheUtils; |
| import com.gemstone.gemfire.cache.query.Index; |
| import com.gemstone.gemfire.cache.query.IndexInvalidException; |
| import com.gemstone.gemfire.cache.query.IndexStatistics; |
| import com.gemstone.gemfire.cache.query.QueryService; |
| import com.gemstone.gemfire.cache.query.SelectResults; |
| import com.gemstone.gemfire.cache.query.data.Portfolio; |
| import com.gemstone.gemfire.cache.query.internal.QueryObserverAdapter; |
| import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder; |
| import com.gemstone.gemfire.test.junit.categories.IntegrationTest; |
| |
| @Category(IntegrationTest.class) |
| public class HashIndexJUnitTest { |
| |
| private QueryService qs; |
| private Region region; |
| private Region joinRegion; |
| private MyQueryObserverAdapter observer; |
| private Index index; |
| |
| @Before |
| public void setUp() throws java.lang.Exception { |
| CacheUtils.startCache(); |
| qs = CacheUtils.getQueryService(); |
| observer = new MyQueryObserverAdapter(); |
| QueryObserverHolder.setInstance(observer); |
| |
| } |
| |
| @Test |
| public void testInvalidTokensForHash() throws Exception { |
| CacheUtils.getCache().createRegionFactory(RegionShortcut.REPLICATE).create("exampleRegion"); |
| region = CacheUtils.getCache().getRegion("/exampleRegion"); |
| region.put("0", new Portfolio(0)); |
| region.invalidate("0"); |
| index = qs.createHashIndex("compact range index", "p.status", "/exampleRegion p"); |
| SelectResults results = (SelectResults) qs.newQuery("Select * from /exampleRegion r where r.status='active'").execute(); |
| //the remove should have happened |
| assertEquals(0, results.size()); |
| |
| results = (SelectResults) qs.newQuery("Select * from /exampleRegion r where r.status!='inactive'").execute(); |
| assertEquals(0, results.size()); |
| |
| HashIndex cindex = (HashIndex)index; |
| Iterator iterator = cindex.entriesSet.iterator(); |
| int count = 0; |
| while (iterator.hasNext()) { |
| count++; |
| iterator.next(); |
| } |
| assertEquals("incorrect number of entries in collection", 0, count); |
| } |
| |
| private void createJoinTable(int numEntries) throws Exception { |
| joinRegion = CacheUtils.createRegion("portfolios2", Portfolio.class); |
| |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i); |
| joinRegion.put("" + i, p); |
| } |
| } |
| |
| @After |
| public void tearDown() throws java.lang.Exception { |
| qs.removeIndexes(); |
| if (joinRegion != null) { |
| joinRegion.close(); |
| joinRegion = null; |
| } |
| region.close(); |
| CacheUtils.closeCache(); |
| } |
| |
| /** |
| * Helper that tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| |
| private void helpTestHashIndexForQuery(String query)throws Exception { |
| helpTestHashIndexForQuery(query,"p.ID", "/portfolios p"); |
| } |
| |
| private void helpTestHashIndexForQuery(String query, String indexedExpression, String regionPath) throws Exception { |
| SelectResults nonIndexedResults = (SelectResults)qs.newQuery(query).execute(); |
| assertFalse(observer.indexUsed); |
| |
| index = (Index)qs.createHashIndex("idHash", indexedExpression, regionPath); |
| SelectResults indexedResults = (SelectResults)qs.newQuery(query).execute(); |
| assertEquals(nonIndexedResults.size(), indexedResults.size()); |
| assertTrue(observer.indexUsed); |
| assertTrue(indexedResults.size() > 0); |
| } |
| |
| private void helpTestHashIndexForQuery(String query, Object[] params, String indexedExpression, String regionPath) throws Exception { |
| SelectResults nonIndexedResults = (SelectResults)qs.newQuery(query).execute(params); |
| assertFalse(observer.indexUsed); |
| |
| index = (Index)qs.createHashIndex("idHash", indexedExpression, regionPath); |
| SelectResults indexedResults = (SelectResults)qs.newQuery(query).execute(params); |
| assertEquals(nonIndexedResults.size(), indexedResults.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| |
| /* |
| * helper method to test against a compact range index instead of hash index |
| * @param query |
| * @throws Exception |
| */ |
| private void helpTestCRIndexForQuery(String query, String indexedExpression, String regionPath) throws Exception { |
| SelectResults nonIndexedResults = (SelectResults)qs.newQuery(query).execute(); |
| assertFalse(observer.indexUsed); |
| |
| index = (Index)qs.createIndex("crIndex", indexedExpression, regionPath); |
| SelectResults indexedResults = (SelectResults)qs.newQuery(query).execute(); |
| assertEquals(nonIndexedResults.size(), indexedResults.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| /** |
| * Tests that hash index with And query for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexWithORQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios p WHERE p.ID = 1 OR p.ID = 2", "p.ID", "/portfolios p"); |
| } |
| |
| @Test |
| public void testHashIndexWithNullsForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| int id = i % numIds; |
| Portfolio p = new Portfolio(id); |
| if(id % 2 == 0) { |
| p.status = null; |
| } |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios p WHERE p.status = 'inactive'", "p.status", "/portfolios p"); |
| qs.removeIndexes(); |
| observer = new MyQueryObserverAdapter(); |
| QueryObserverHolder.setInstance(observer); |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios p WHERE p.status != 'inactive'", "p.status", "/portfolios p"); |
| qs.removeIndexes(); |
| observer = new MyQueryObserverAdapter(); |
| QueryObserverHolder.setInstance(observer); |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios p WHERE p.status = null", "p.status", "/portfolios p"); |
| qs.removeIndexes(); |
| observer = new MyQueryObserverAdapter(); |
| QueryObserverHolder.setInstance(observer); |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios p WHERE p.status != null", "p.status", "/portfolios p"); |
| } |
| |
| /** |
| * Tests that hash index with And query for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexWithNestedQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestCRIndexForQuery("SELECT * FROM (SELECT * FROM /portfolios p WHERE p.shortID = 1)", "p.shortID", "/portfolios p"); |
| } |
| |
| /** |
| * Tests that hash index with Short vs Integer comparison |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexWithNestedQueryWithShortVsIntegerCompareForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios p WHERE p.shortID in (SELECT p2.ID FROM /portfolios p2 WHERE p2.shortID = 1)", "p.shortID", "/portfolios p"); |
| } |
| |
| |
| /** |
| * Tests that hash index with comparison between float and integer |
| * @throws Exception |
| */ |
| // @Test |
| // public void testHashIndexQueryWithFloatVsIntegerCompareForLocalRegion() throws Exception { |
| // createLocalRegion("portfolios"); |
| // int numEntries = 1000; |
| // int numIds = 100; |
| // for (int i = 0; i < numEntries; i++) { |
| // Portfolio p = new Portfolio(i % (numIds)); |
| // p.shortID = (short)i; |
| // region.put("" + i, p); |
| // } |
| // helpTestHashIndexForQuery("SELECT * FROM /portfolios p WHERE p.ID = 1.0f", "p.ID", "/portfolios p"); |
| // } |
| |
| /** |
| * Tests that hash index with comparison between float and integer |
| * @throws Exception |
| */ |
| // @Test |
| // public void testHashIndexNotEqualsWithFloatVsIntegerLocalRegion() throws Exception { |
| // createLocalRegion("portfolios"); |
| // int numEntries = 1000; |
| // int numIds = 100; |
| // for (int i = 0; i < numEntries; i++) { |
| // Portfolio p = new Portfolio(i % (numIds)); |
| // p.shortID = (short)i; |
| // region.put("" + i, p); |
| // } |
| // helpTestCRIndexForQuery("SELECT * FROM /portfolios p WHERE p.ID != 1.0f", "p.ID", "/portfolios p"); |
| // } |
| |
| /** |
| * Tests that hash index with And query for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexWithAndQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios p WHERE p.ID = 1 AND p.shortID > 0", "p.ID", "/portfolios p"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexWithLimitQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios.entries p WHERE p.key = '1' limit 3", "p.key", "/portfolios.entries p"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexEntriesQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios.entries p WHERE p.key = '1'", "p.key", "/portfolios.entries p"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexValueQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios.values p WHERE p.ID = 1", "p.ID", "/portfolios.values p"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexKeySetQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("SELECT * FROM /portfolios.keySet p WHERE p = '1'", "p", "/portfolios.keySet p"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexEqualsForSingleResultOnLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID = 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result for replicated region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexEqualsForSingleResultOnReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID = 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result for partitioned region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexEqualsForSingleResultOnPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID = 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexAndEquiJoinForSingleResultQueryWithHashIndex() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 200); |
| createJoinTable(400); |
| Index index = (Index)qs.createHashIndex("index2","p2.ID", "/portfolios2 p2"); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p, /portfolios2 p2 where (p.ID = 1 or p.ID = 2 )and p.ID = p2.ID"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexAndEquiJoinForSingleResultQueryWithCompactRangeIndex() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 200); |
| createJoinTable(400); |
| Index index = (Index)qs.createIndex("index2","p2.ID", "/portfolios2 p2"); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p, /portfolios2 p2 where (p.ID = 1 or p.ID = 2 )and p.ID = p2.ID"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexAndEquiJoinForSingleResultQueryWithRangeIndex() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 200); |
| createJoinTable(400); |
| Index index = (Index)qs.createIndex("index2","p2.ID", "/portfolios2 p2, p2.positions.values v"); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p, /portfolios2 p2 where (p.ID = 1 or p.ID = 2 )and p.ID = p2.ID"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| // @Test |
| // public void testHashIndexAndEquiJoinForSingleResultQueryWithMapRangeIndex() throws Exception { |
| // createReplicatedRegion("portfolios"); |
| // createData(region, 1000); |
| // createJoinTable(2000); |
| // Index index = (Index)qs.createIndex("index2","p2.names[*]", "/portfolios2 p2"); |
| // helpTestHashIndexForQuery("Select * FROM /portfolios p, /portfolios2 p2 where (p.names['1'] or p.names['2'] ) and p.names = p2.names", "p.names[*]", "/portfolios p"); |
| // } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexAndEquiJoinForSingleResultQueryWithHashIndexLessEntries() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 400); |
| createJoinTable(200); |
| Index index = (Index)qs.createHashIndex("index2","p2.ID", "/portfolios2 p2"); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p, /portfolios2 p2 where (p.ID = 1 or p.ID = 2 )and p.ID = p2.ID"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexAndEquiJoinForSingleResultQueryWithCompactRangeIndexLessEntries() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 400); |
| createJoinTable(200); |
| Index index = (Index)qs.createIndex("index2","p2.ID", "/portfolios2 p2"); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p, /portfolios2 p2 where (p.ID = 1 or p.ID = 2 )and p.ID = p2.ID"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexAndEquiJoinForSingleResultQueryWithRangeIndexLessEntries() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 400); |
| createJoinTable(200); |
| Index index = (Index)qs.createIndex("index2","p2.ID", "/portfolios2 p2, p2.positions.values v"); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p, /portfolios2 p2 where (p.ID = 1 or p.ID = 2 )and p.ID = p2.ID"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| // @Test |
| // public void testHashIndexAndEquiJoinForSingleResultQueryWithMapRangeIndexLessEntries() throws Exception { |
| // createReplicatedRegion("portfolios"); |
| // createData(region, 1000); |
| // createJoinTable(500); |
| // Index index = (Index)qs.createIndex("index2","p2.positions[*]", "/portfolios2 p2"); |
| // helpTestHashIndexForQuery("Select * FROM /portfolios p, /portfolios2 p2 where p.positions['IBM'] and p.positions['IBM']=p2.positions['IBM']", "p.positions[*]", "/portfolios p"); |
| // } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct number of results |
| * on local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexEqualsForMultipleResultQueryOnLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| //Create the data |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID = 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct number of results |
| * on replicated region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexEqualsForMultipleResultQueryOnReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| //Create the data |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID = 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct number of results |
| * on partitioned region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexEqualsForMultipleResultQueryOnPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| //Create the data |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID = 1"); |
| } |
| |
| |
| /** |
| * Tests that hash index is used and that it returns the correct number of results |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexEquiJoinForMultipleResultQueryWithHashIndex() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createJoinTable(400); |
| index = (HashIndex) qs.createHashIndex("idHash", |
| "p.ID", "/portfolios p"); |
| Index index = (Index)qs.createHashIndex("index2","p2.ID", "/portfolios2 p2"); |
| |
| |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| SelectResults results = (SelectResults)qs.newQuery("Select * FROM /portfolios p, /portfolios2 p2 where p.ID = 1 and p.ID = p2.ID").execute(); |
| assertEquals(numEntries/numIds, results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| /** |
| * Tests that hash index is used and that the value is correctly removed from the index |
| * where only 1 value is using the key for partitioned regions |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexRemoveOnLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| helpTestHashIndexRemove(); |
| } |
| |
| /** |
| * Tests that hash index is used and that the value is correctly removed from the index |
| * where only 1 value is using the key for replicated regions |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexRemoveOnReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| helpTestHashIndexRemove(); |
| } |
| |
| @Test |
| public void testHashIndexRemoveOnPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| createData(region, 200); |
| region.destroy("1"); |
| SelectResults noIndexResults = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID = 1").execute(); |
| |
| region.destroyRegion(); |
| createPartitionedRegion("portfolios"); |
| createData(region, 200); |
| region.destroy("1"); |
| index = (Index)qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| SelectResults results = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID = 1").execute(); |
| assertEquals(noIndexResults.size(), results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| /** |
| * Tests that hash index is used and that the value is correctly removed from the index |
| * where only 1 value is using the key for partitioned regions |
| * @throws Exception |
| */ |
| private void helpTestHashIndexRemove() throws Exception { |
| createData(region, 200); |
| region.destroy("1"); |
| SelectResults noIndexResults = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID = 1").execute(); |
| |
| region.clear(); |
| createData(region, 200); |
| region.destroy("1"); |
| index = (Index)qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| SelectResults results = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID = 1").execute(); |
| assertEquals(noIndexResults.size(), results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| /** |
| * Tests that hash index is used and that the value is correctly removed from the index |
| * where multiple entries are using the key on localRegion |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexRemoveFromCommonKeyQueryOnLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| helpTestHashIndexRemoveFromCommonKeyQuery(); |
| } |
| |
| /** |
| * Tests that hash index is used and that the value is correctly removed from the index |
| * where multiple entries are using the key on replicated region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexRemoveFromCommonKeyQueryOnReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| helpTestHashIndexRemoveFromCommonKeyQuery(); |
| } |
| |
| /** |
| * Tests that hash index is used and that the value is correctly removed from the index |
| * where multiple entries are using the key on partitioned region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexRemoveFromCommonKeyQueryOnPartitionedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| helpTestHashIndexRemoveFromCommonKeyQuery(); |
| } |
| |
| private void helpTestHashIndexRemoveFromCommonKeyQuery() throws Exception { |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| Portfolio p2 = new Portfolio(10000); |
| region.put("2", p2); |
| p2.ID = 1000; |
| region.put("2", p2); |
| SelectResults noIndexResult = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID = 2").execute(); |
| |
| region.clear(); |
| index = (HashIndex) qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| p2 = new Portfolio(10000); |
| region.put("2", p2); |
| p2.ID = 1000; |
| region.put("2", p2); |
| |
| SelectResults results = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID = 2").execute(); |
| assertEquals(numEntries/numIds - 1, results.size()); |
| assertEquals(noIndexResult.size(), results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * on local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexNotEqualsQueryOnLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID != 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * on replicated region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexNotEqualsQueryOnReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID != 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * on partitioned region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexNotEqualsQueryOnPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID != 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct number of results |
| * for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexNotEqualsForMultipleResultQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID != 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct number of results |
| * for replicated region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexNotEqualsForMultipleResultQueryForReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID != 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct number of results |
| * for partitioned region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexNotEqualsForMultipleResultQueryForPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| int numEntries = 200; |
| int numIds = 100; |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i % (numIds)); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID != 1"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexInQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID in set (1)"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexInQueryForReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID in set (1)"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexInQueryForPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID in set (1)"); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexNotUsedInRangeQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexNotUsedInRangeQuery(); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * for replicated region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexNotUsedInRangeQueryForReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexNotUsedInRangeQuery(); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * for partitioned region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexNotUsedInRangeQueryForPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexNotUsedInRangeQuery(); |
| } |
| |
| /** |
| * Tests that hash index is used and that it returns the correct result |
| * @throws Exception |
| */ |
| private void helpTestHashIndexNotUsedInRangeQuery() throws Exception { |
| SelectResults results = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID < 2").execute(); |
| assertFalse(observer.indexUsed); |
| } |
| |
| /** |
| * Test order by asc query for local region using hash index |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexOrderByAscQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexOrderByAscQuery(); |
| } |
| |
| /** |
| * Test order by asc query for replicated region using hash index |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexOrderByAscQueryForReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexOrderByAscQuery(); |
| } |
| |
| /** |
| * Test order by asc query for partitioned region using hash index |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexOrderByAscQueryForPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexOrderByAscQuery(); |
| } |
| |
| private void helpTestHashIndexOrderByAscQuery() throws Exception { |
| index = (Index)qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| SelectResults results = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID != 0 order by ID asc ").execute(); |
| assertEquals(199, results.size()); |
| assertTrue(observer.indexUsed); |
| int countUp = 1; |
| for (Object o: results) { |
| Portfolio p = (Portfolio) o; |
| assertEquals(countUp++, p.getID()); |
| } |
| } |
| |
| /** |
| * Test order by desc query for local region using hash index |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexOrderByDescQueryForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexOrderByDescQuery(); |
| } |
| |
| /** |
| * Test order by desc query for replicated region using hash index |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexOrderByDescQueryForReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexOrderByDescQuery(); |
| } |
| |
| /** |
| * Test order by desc query for partitioned region using hash index |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexOrderByDescQueryForPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| createData(region, 200); |
| helpTestHashIndexOrderByDescQuery(); |
| } |
| |
| /** |
| * Tests that hash index on non sequential hashes |
| * for local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexOnNonSequentialHashForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| for (int i = 0; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| for (int i = 200; i < 300; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| for (int i = 500; i < 600; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID != 1"); |
| } |
| |
| /** |
| * Tests that hash index on non sequential hashes |
| * for replicated region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexOnNonSequentialHashForReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| for (int i = 0; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| for (int i = 200; i < 300; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| for (int i = 500; i < 600; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID != 1"); |
| } |
| |
| /** |
| * Tests that hash index on non sequential hashes |
| * for partitioned region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexOnNonSequentialHashForPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| for (int i = 0; i < 100; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| for (int i = 200; i < 300; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| for (int i = 500; i < 600; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| helpTestHashIndexForQuery("Select * FROM /portfolios p where p.ID != 1"); |
| } |
| |
| private void helpTestHashIndexOrderByDescQuery() throws Exception { |
| index = (Index)qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| SelectResults results = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID != 0 order by ID desc ").execute(); |
| assertEquals(199, results.size()); |
| assertTrue(observer.indexUsed); |
| int countDown = 199; |
| for (Object o: results) { |
| Portfolio p = (Portfolio) o; |
| assertEquals(countDown--, p.getID()); |
| } |
| } |
| |
| /** |
| * test async exception for hash index using partitioned region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexAsyncMaintenanceExceptionForPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios_async", false); |
| helpTestAsyncMaintenance(); |
| } |
| |
| private void helpTestAsyncMaintenance() throws Exception { |
| boolean expected = false; |
| try { |
| index = qs.createHashIndex("idHash", "p.ID", "/portfolios_async p"); |
| } |
| catch ( UnsupportedOperationException e) { |
| expected = true; |
| } |
| catch (IndexInvalidException e) { |
| //for partition region execption; |
| expected = true; |
| } |
| |
| assertTrue(expected); |
| } |
| |
| /** |
| * test multiple iterators exception for hash index using local region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexMultipleIteratorsExceptionForLocalRegion() throws Exception { |
| createLocalRegion("portfolios"); |
| helpTestMultipleIteratorsException(); |
| } |
| |
| /** |
| * test multiple iterators exception for hash index using replicated region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexMultipleIteratorsExceptionForReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| helpTestMultipleIteratorsException(); |
| } |
| |
| /** |
| * test multiple iterators exception for hash index using partiioned region |
| * @throws Exception |
| */ |
| @Test |
| public void testHashIndexMultipleIteratorsExceptionForPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| helpTestMultipleIteratorsException(); |
| } |
| |
| private void helpTestMultipleIteratorsException() throws Exception { |
| boolean expected = false; |
| try { |
| index = qs.createHashIndex("idHash", |
| "p.ID", "/portfolios p, p.positions.values p"); |
| } |
| catch ( UnsupportedOperationException e) { |
| expected = true; |
| } |
| assertTrue(expected); |
| } |
| |
| /** |
| * test remove and not equals Query |
| * @throws Exception |
| */ |
| @Test |
| public void testRemoveAndNotEqualsQuery() throws Exception { |
| createReplicatedRegion("portfolios"); |
| helpTestRemoveAndNotEqualsQuery(); |
| } |
| |
| private void helpTestRemoveAndNotEqualsQuery() throws Exception { |
| int numEntries = 200; |
| index = (HashIndex) qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i); |
| p.shortID = (short)i; |
| region.put("" + i, p); |
| } |
| |
| region.destroy("1"); |
| |
| SelectResults results = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID != 1").execute(); |
| assertEquals(numEntries - 1, results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| @Test |
| public void testHashCollisionAndProbe() throws Exception { |
| createReplicatedRegion("relationships"); |
| int numEntries = 40000; |
| int numIds = 200; |
| for (int i = 0; i < numEntries; i++) { |
| int ki = i % numIds; |
| Object key = new RelationshipKey(ki, i); |
| Object value = new Schema(new Relationship(new RelationshipKey(ki, i))); |
| region.put(key, value); |
| } |
| Object[] params = new Object[2]; |
| params[0] = new Identifier("Customer" +1); |
| params[1] = new Identifier("Customer" + 1); |
| String query = "select * from /relationships.keySet k where k.leftKey = $1 OR k.rightKey = $2"; |
| // String query = "select * from /relationships r where r.relationship.key IN (select * from /relationships.keySet k where k.leftKey = $1 OR k.rightKey = $2)"; |
| SelectResults nonIndexedResults = (SelectResults)qs.newQuery(query).execute(params); |
| assertFalse(observer.indexUsed); |
| |
| index = (Index)qs.createHashIndex("leftKey", "k.leftKey", "/relationships.keySet k"); |
| Index index2 = (Index)qs.createHashIndex("rightKey", "k.rightKey", "/relationships.keySet k"); |
| Index index3 = (Index)qs.createKeyIndex("keyIndex", "r.key", "/relationships r"); |
| SelectResults indexedResults = (SelectResults)qs.newQuery(query).execute(params); |
| assertEquals(nonIndexedResults.size(), indexedResults.size()); |
| assertEquals(nonIndexedResults.size(), numEntries/numIds); |
| assertTrue(observer.indexUsed); |
| } |
| |
| @Test |
| public void testHashIndexRecreateOnReplicatedRegion() throws Exception { |
| createReplicatedRegion("portfolios"); |
| helpTestHashIndexRecreate(); |
| } |
| |
| @Test |
| public void testHashIndexRecreateOnPartitionedRegion() throws Exception { |
| createPartitionedRegion("portfolios"); |
| helpTestHashIndexRecreate(); |
| } |
| |
| private void helpTestHashIndexRecreate() throws Exception { |
| index = (Index)qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| createData(region, 200); |
| |
| SelectResults noIndexResults = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID = 1").execute(); |
| |
| IndexStatistics ist = index.getStatistics(); |
| assertEquals(200, ist.getNumberOfValues()); |
| assertEquals(200, ist.getNumUpdates()); |
| assertEquals(1, ist.getTotalUses()); |
| |
| region.clear(); |
| |
| ist = index.getStatistics(); |
| assertEquals(0, ist.getNumberOfValues()); |
| assertEquals(1, ist.getTotalUses()); |
| assertEquals(400, ist.getNumUpdates()); |
| |
| createData(region, 200); |
| |
| SelectResults results = (SelectResults)qs.newQuery("Select * FROM /portfolios p where p.ID = 1").execute(); |
| |
| ist = index.getStatistics(); |
| assertEquals(200, ist.getNumberOfValues()); |
| assertEquals(2, ist.getTotalUses()); |
| assertEquals(600, ist.getNumUpdates()); |
| |
| assertEquals(noIndexResults.size(), results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| @Test |
| public void testUpdatesOnKeyWithSameHash() throws Exception { |
| createReplicatedRegion("portfolios"); |
| helpTestUpdatesOnKeyWithSameHash(); |
| } |
| |
| private void helpTestUpdatesOnKeyWithSameHash() throws Exception { |
| int numEntries = 10; |
| for (int i = 0; i < numEntries; i++) { |
| SameHashObject p = new SameHashObject(5, i); |
| region.put("" + i, p); |
| } |
| region.put("0", new SameHashObject(100, 100)); |
| SelectResults noIndexResults = (SelectResults) qs.newQuery( |
| "Select * FROM /portfolios p where p.ID = 5").execute(); |
| region.clear(); |
| |
| HashIndex index = (HashIndex) qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| for (int i = 0; i < numEntries; i++) { |
| SameHashObject p = new SameHashObject(5, i); |
| region.put("" + i, p); |
| } |
| region.put("0", new SameHashObject(index.entriesSet._set.length + 5, 100)); |
| |
| SelectResults results = (SelectResults) qs.newQuery( |
| "Select * FROM /portfolios p where p.ID = 5").execute(); |
| |
| assertTrue(results.size() > 0); |
| assertEquals(noIndexResults.size(), results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| @Test |
| public void testInPlaceModification() throws Exception { |
| createReplicatedRegion("portfolios"); |
| int numEntries = 10; |
| HashIndex index = (HashIndex) qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| for (int i = 0; i < numEntries; i++) { |
| SameHashObject p = new SameHashObject(5, i); |
| region.put("" + i, p); |
| } |
| SameHashObject object = (SameHashObject)region.get("0"); |
| object.ID = 200; |
| region.put("0", object); |
| |
| SelectResults results = (SelectResults) qs.newQuery( |
| "Select * FROM /portfolios p where p.ID = 5").execute(); |
| assertEquals(10, index.getStatistics().getNumberOfValues()); |
| assertEquals(9, results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| @Test |
| public void testInPlaceModificationToSameKey() throws Exception { |
| createReplicatedRegion("portfolios"); |
| int numEntries = 10; |
| HashIndex index = (HashIndex) qs.createHashIndex("idHash", "p.ID", "/portfolios p"); |
| for (int i = 0; i < numEntries; i++) { |
| SameHashObject p = new SameHashObject(5, i); |
| region.put("" + i, p); |
| } |
| SameHashObject object = (SameHashObject)region.get("0"); |
| object.ID = 5; |
| region.put("0", object); |
| |
| SelectResults results = (SelectResults) qs.newQuery( |
| "Select * FROM /portfolios p where p.ID = 5").execute(); |
| assertEquals(10, index.getStatistics().getNumberOfValues()); |
| assertEquals(10, results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| @Test |
| public void testInPlaceModificationWithUndefinedKeys() throws Exception { |
| createReplicatedRegion("portfolios"); |
| int numEntries = 10; |
| Index index = qs.createIndex("idHash", "p.IDS", "/portfolios p"); |
| for (int i = 0; i < numEntries; i++) { |
| SameHashObject p = new SameHashObject(5, i); |
| region.put("" + i, p); |
| } |
| SameHashObject object = (SameHashObject)region.get("0"); |
| object.ID = 5; |
| region.put("0", object); |
| |
| SelectResults results = (SelectResults) qs.newQuery( |
| "Select * FROM /portfolios p where p.IDS = 5").execute(); |
| assertEquals(10, index.getStatistics().getNumberOfValues()); |
| assertEquals(0, results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| @Test |
| public void testInPlaceModificationWithNullKeys() throws Exception { |
| createReplicatedRegion("portfolios"); |
| int numEntries = 10; |
| Index index = qs.createHashIndex("idHash", "p.stringValue", "/portfolios p"); |
| for (int i = 0; i < numEntries; i++) { |
| SameHashObject p = new SameHashObject(5, i, null); |
| region.put("" + i, p); |
| } |
| SameHashObject object = (SameHashObject)region.get("0"); |
| object.stringValue = "wow"; |
| region.put("0", object); |
| |
| SelectResults results = (SelectResults) qs.newQuery( |
| "Select * FROM /portfolios p where p.stringValue = 'wow'").execute(); |
| assertEquals(10, index.getStatistics().getNumberOfValues()); |
| assertEquals(1, results.size()); |
| assertTrue(observer.indexUsed); |
| } |
| |
| @Test |
| public void testOverflowWithRehash() throws Exception { |
| try { |
| final boolean[] threadCompleted = new boolean[3]; |
| createReplicatedRegionWithOverflow("portfolios"); |
| HashIndexSet.TEST_ALWAYS_REHASH = true; |
| Index index = qs.createHashIndex("idHash", "p", "/portfolios p"); |
| |
| Thread puts = new Thread(new Runnable() { |
| public void run() { |
| for (int j = 0; j < 20; j++) { |
| for (int i = 0; i < 2; i++) { |
| region.put("" + i, "SOME STRING OBJECT" + i); |
| } |
| } |
| threadCompleted[0] = true; |
| } |
| }); |
| |
| Thread morePuts = new Thread(new Runnable() { |
| public void run() { |
| for (int j = 0; j < 20; j++) { |
| for (int i = 0; i < 1; i++) { |
| region.put("" + (i + 100), "SOME OTHER STRING OBJECT" + (i+100)); |
| } |
| } |
| threadCompleted[1] = true; |
| } |
| }); |
| |
| Thread evenMorePuts = new Thread(new Runnable() { |
| public void run() { |
| for (int j = 0; j < 20; j++) { |
| for (int i = 0; i < 1; i++) { |
| region.put("" + (i + 200), "ANOTHER STRING OBJECT" + (i + 200)); |
| } |
| } |
| threadCompleted[2] = true; |
| } |
| }); |
| |
| evenMorePuts.start(); |
| morePuts.start(); |
| puts.start(); |
| |
| puts.join(30000); |
| morePuts.join(30000); |
| evenMorePuts.join(30000); |
| assertTrue("Thread possibly deadlocked, thread did not complete", threadCompleted[0]); |
| assertTrue("Thread possibly deadlocked, thread did not complete", threadCompleted[1]); |
| assertTrue("Thread possibly deadlocked, thread did not complete", threadCompleted[2]); |
| |
| SelectResults results = (SelectResults) qs.newQuery( |
| "Select * FROM /portfolios p").execute(); |
| assertEquals(4, results.size()); |
| } |
| finally { |
| HashIndexSet.TEST_ALWAYS_REHASH = false; |
| } |
| } |
| |
| private void printIndex(Index index) { |
| if (index instanceof PartitionedIndex) { |
| Iterator it = ((PartitionedIndex)index).getBucketIndexes().iterator(); |
| while (it.hasNext()) { |
| ((HashIndex)it.next()).printAll(); |
| } |
| } |
| else { |
| System.out.println(((HashIndex)index).printAll()); |
| } |
| } |
| |
| |
| private class RelationshipKey implements Comparable { |
| public Identifier leftKey; |
| public Identifier rightKey; |
| |
| public RelationshipKey(int leftKeyId, int rightKeyId) { |
| this.leftKey = new Identifier("Customer" + leftKeyId); |
| this.rightKey = new Identifier("Customer" + rightKeyId); |
| } |
| |
| public Identifier getLeftKey() { |
| return leftKey; |
| } |
| public Identifier getRightKey() { |
| return rightKey; |
| } |
| |
| public int compareTo(Object o) { |
| if (o instanceof RelationshipKey) { |
| return leftKey.compareTo(((RelationshipKey)o).leftKey); |
| } |
| throw new ClassCastException("Unable to cast " + o + " to Identifier"); |
| } |
| |
| public boolean equals(Object o) { |
| if (o instanceof RelationshipKey) { |
| return leftKey.equals(((RelationshipKey)o).leftKey) && rightKey.equals(((RelationshipKey)o).rightKey); |
| } |
| return false; |
| } |
| |
| @Override |
| public int hashCode() { |
| return leftKey.hashCode(); |
| } |
| } |
| |
| private class Schema { |
| public Relationship relationship; |
| |
| public Schema(Relationship relationship) { |
| this.relationship = relationship; |
| } |
| |
| public Relationship getRelationship() { |
| return relationship; |
| } |
| } |
| |
| private class Relationship { |
| public RelationshipKey key; |
| public Relationship(RelationshipKey key) { |
| this.key = key; |
| } |
| |
| public RelationshipKey getKey() { |
| return key; |
| } |
| } |
| |
| public class Identifier implements Comparable { |
| private int hashCode = 0; |
| public String id; |
| |
| public Identifier(String id) { |
| this.id = id; |
| } |
| |
| @Override |
| public int compareTo(Object o) { |
| if (o instanceof Identifier) { |
| String otherId = ((Identifier)o).id; |
| return id.compareTo(otherId); |
| } |
| throw new ClassCastException("Unable to cast " + o + " to Identifier"); |
| } |
| |
| public boolean equals(Object o) { |
| if (o instanceof Identifier) { |
| return id.equals(((Identifier)o).id); |
| } |
| return false; |
| } |
| |
| @Override |
| public int hashCode() { |
| if (this.hashCode == 0) { |
| this.hashCode = id.hashCode(); |
| this.hashCode += 7 * "something".hashCode(); |
| } |
| |
| return this.hashCode; |
| } |
| } |
| |
| public class SameHashObject implements Serializable { |
| |
| public int ID = 0; |
| public String stringValue; |
| private int uniqueId = 0; |
| |
| public SameHashObject(int i, int uniqueId, String stringValue) { |
| ID = i; |
| this.uniqueId = uniqueId; |
| this.stringValue = stringValue; |
| } |
| |
| public SameHashObject(int i, int uniqueId) { |
| this(i, uniqueId, "" + i); |
| } |
| |
| public boolean equals(Object o) { |
| if (o instanceof SameHashObject) { |
| return ID == ((SameHashObject)o).ID; |
| } |
| return false; |
| } |
| public int hashCode() { |
| return 99; |
| } |
| |
| public String toString() { |
| return "SameHashObject:" + ID + ":" + uniqueId + " :" + stringValue; |
| } |
| } |
| |
| |
| private void createLocalRegion(String regionName) throws ParseException { |
| createLocalRegion(regionName, true); |
| } |
| |
| private void createLocalRegion(String regionName, boolean synchMaintenance) throws ParseException { |
| Cache cache = CacheUtils.getCache(); |
| AttributesFactory attributesFactory = new AttributesFactory(); |
| attributesFactory.setDataPolicy(DataPolicy.NORMAL); |
| attributesFactory.setIndexMaintenanceSynchronous(synchMaintenance); |
| RegionAttributes regionAttributes = attributesFactory.create(); |
| region = cache.createRegion(regionName, regionAttributes); |
| } |
| |
| private void createReplicatedRegion(String regionName) throws ParseException { |
| createReplicatedRegion(regionName, true); |
| } |
| |
| private void createReplicatedRegion(String regionName, boolean synchMaintenance) throws ParseException { |
| Cache cache = CacheUtils.getCache(); |
| AttributesFactory attributesFactory = new AttributesFactory(); |
| attributesFactory.setDataPolicy(DataPolicy.REPLICATE); |
| attributesFactory.setIndexMaintenanceSynchronous(synchMaintenance); |
| RegionAttributes regionAttributes = attributesFactory.create(); |
| region = cache.createRegion(regionName, regionAttributes); |
| } |
| |
| private void createReplicatedRegionWithOverflow(String regionName) throws ParseException { |
| Cache cache = CacheUtils.getCache(); |
| AttributesFactory attributesFactory = new AttributesFactory(); |
| attributesFactory.setDataPolicy(DataPolicy.REPLICATE); |
| attributesFactory.setEvictionAttributes(EvictionAttributes.createLRUEntryAttributes(1, EvictionAction.OVERFLOW_TO_DISK)); |
| RegionAttributes regionAttributes = attributesFactory.create(); |
| region = cache.createRegion(regionName, regionAttributes); |
| } |
| |
| private void createPartitionedRegion(String regionName) throws ParseException { |
| createLocalRegion(regionName, true); |
| } |
| |
| private void createPartitionedRegion(String regionName, boolean synchMaintenance) throws ParseException { |
| Cache cache = CacheUtils.getCache(); |
| PartitionAttributesFactory prAttFactory = new PartitionAttributesFactory(); |
| AttributesFactory attributesFactory = new AttributesFactory(); |
| attributesFactory.setPartitionAttributes(prAttFactory.create()); |
| attributesFactory.setIndexMaintenanceSynchronous(synchMaintenance); |
| RegionAttributes regionAttributes = attributesFactory.create(); |
| region = cache.createRegion(regionName, regionAttributes); |
| } |
| |
| private void createData(Region region, int numEntries) { |
| for (int i = 0; i < numEntries; i++) { |
| Portfolio p = new Portfolio(i); |
| region.put("" + i, p); |
| } |
| } |
| |
| |
| class MyQueryObserverAdapter extends QueryObserverAdapter { |
| public boolean indexUsed = false; |
| |
| public void afterIndexLookup(Collection results){ |
| super.afterIndexLookup(results); |
| indexUsed = true; |
| } |
| }; |
| |
| |
| } |