blob: 60a17ad43c81fda082fb9445a24a2df4d3a07070 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.cache.query.internal.index;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.CacheExistsException;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.query.Index;
import org.apache.geode.cache.query.IndexStatistics;
import org.apache.geode.cache.query.data.Portfolio;
import org.apache.geode.cache.query.data.Position;
import org.apache.geode.cache.query.internal.index.AbstractIndex.RegionEntryToValuesMap;
import org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry;
import org.apache.geode.cache.query.internal.index.MemoryIndexStore.MemoryIndexStoreEntry;
import org.apache.geode.cache.query.partitioned.PRQueryDUnitHelper;
import org.apache.geode.cache30.CacheSerializableRunnable;
import org.apache.geode.cache30.CacheTestCase;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.cache.CachedDeserializable;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.LocalRegion;
import org.apache.geode.internal.cache.PartitionedRegion;
import org.apache.geode.internal.cache.RegionEntry;
import org.apache.geode.internal.cache.Token;
import org.apache.geode.internal.cache.persistence.query.CloseableIterator;
import org.apache.geode.test.dunit.Assert;
import org.apache.geode.test.dunit.AsyncInvocation;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.Invoke;
import org.apache.geode.test.dunit.LogWriterUtils;
import org.apache.geode.test.dunit.SerializableRunnableIF;
import org.apache.geode.test.dunit.ThreadUtils;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
import org.apache.geode.test.junit.categories.OQLIndexTest;
/**
* During validation all region operations are paused for a while. Validation happens multiple time
* during one test run on a fixed time interval.
*/
@Category({OQLIndexTest.class})
public class ConcurrentIndexUpdateWithoutWLDUnitTest extends JUnit4DistributedTestCase {
PRQueryDUnitHelper helper = new PRQueryDUnitHelper();
private static String regionName = "Portfolios";
private int redundancy = 1;
// CompactRangeIndex
private String indexName = "idIndex";
private String indexedExpression = "ID";
private String fromClause = "/" + regionName;
private String alias = "p";
private String rindexName = "secidIndex";
private String rindexedExpression = "pos.secId";
private String rfromClause = "/" + regionName + " p, p.positions.values pos";
private String ralias = "pos";
int stepSize = 10;
private int totalDataSize = 50;
public void setCacheInVMs(VM... vms) {
for (VM vm : vms) {
vm.invoke(() -> getAvailableCacheElseCreateCache());
}
}
private final void getAvailableCacheElseCreateCache() {
synchronized (ConcurrentIndexUpdateWithInplaceObjectModFalseDUnitTest.class) {
try {
Cache newCache = GemFireCacheImpl.getInstance();
if (null == newCache) {
System.setProperty(
DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE", "true");
newCache = CacheFactory.create(getSystem());
}
PRQueryDUnitHelper.setCache(newCache);
} catch (CacheExistsException e) {
Assert.fail("the cache already exists", e); // TODO: remove error handling
} catch (RuntimeException ex) {
throw ex;
} catch (Exception ex) {
Assert.fail("Checked exception while initializing cache??", ex);
} finally {
System.clearProperty(
DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE");
}
}
}
/**
* Tear down a PartitionedRegionTestCase by cleaning up the existing cache (mainly because we want
* to destroy any existing PartitionedRegions)
*/
@Override
public final void preTearDown() throws Exception {
Invoke.invokeInEveryVM(() -> ConcurrentIndexUpdateWithoutWLDUnitTest.destroyRegions());
Invoke.invokeInEveryVM(() -> CacheTestCase.closeCache());
}
public static synchronized void destroyRegions() {
Cache cache = GemFireCacheImpl.getInstance();
if (cache != null) {
Region region = cache.getRegion(regionName);
if (region != null)
region.destroyRegion();
}
}
// Tests on Local/Replicated Region
@Test
public void testCompactRangeIndex() {
// Create a Local Region.
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
setCacheInVMs(vm0);
vm0.invoke(helper.getCacheSerializableRunnableForReplicatedRegionCreation(regionName));
vm0.invoke(helper.getCacheSerializableRunnableForPRIndexCreate(regionName, indexName,
indexedExpression, fromClause, alias));
AsyncInvocation[] asyncInvs = new AsyncInvocation[2];
asyncInvs[0] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[1] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
for (AsyncInvocation inv : asyncInvs) {
ThreadUtils.join(inv, 30 * 000);
}
for (AsyncInvocation inv : asyncInvs) {
if (inv.exceptionOccurred()) {
Assert.fail("Random region operation failed on VM_" + inv.getId(), inv.getException());
}
}
vm0.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
}
@Test
public void testMultiIndexCreation() {
// Create a Local Region.
Host host = Host.getHost(0);
VM vm0 = host.getVM(1);
setCacheInVMs(vm0);
vm0.invoke(helper.getCacheSerializableRunnableForReplicatedRegionCreation(regionName));
ArrayList<String> names = new ArrayList<String>();
names.add(indexName);
names.add(rindexName);
ArrayList<String> exps = new ArrayList<String>();
exps.add(indexedExpression);
exps.add(rindexedExpression);
ArrayList<String> fromClauses = new ArrayList<String>();
fromClauses.add(fromClause);
fromClauses.add(rfromClause);
vm0.invoke(
helper.getCacheSerializableRunnableForDefineIndex(regionName, names, exps, fromClauses));
AsyncInvocation[] asyncInvs = new AsyncInvocation[2];
asyncInvs[0] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[1] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
for (AsyncInvocation inv : asyncInvs) {
ThreadUtils.join(inv, 30 * 000);
}
for (AsyncInvocation inv : asyncInvs) {
if (inv.exceptionOccurred()) {
Assert.fail("Random region operation failed on VM_" + inv.getId(), inv.getException());
}
}
vm0.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
}
private SerializableRunnableIF getCacheSerializableRunnableForIndexValidation(
final String regionName, final String indexName) {
return new CacheSerializableRunnable("Index Validate") {
@Override
public void run2() throws CacheException {
Cache cache = helper.getCache();
Region region = cache.getRegion(regionName);
IndexValidator validator = new IndexValidator();
validator.validate(region);
}
};
}
@Test
public void testRangeIndex() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
setCacheInVMs(vm0);
vm0.invoke(helper.getCacheSerializableRunnableForReplicatedRegionCreation(regionName));
vm0.invoke(helper.getCacheSerializableRunnableForPRIndexCreate(regionName, rindexName,
rindexedExpression, rfromClause, ralias));
AsyncInvocation[] asyncInvs = new AsyncInvocation[2];
asyncInvs[0] = vm0.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, totalDataSize));
asyncInvs[1] = vm0.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, totalDataSize));
for (AsyncInvocation inv : asyncInvs) {
ThreadUtils.join(inv, 30 * 000);
}
for (AsyncInvocation inv : asyncInvs) {
if (inv.exceptionOccurred()) {
Assert.fail("Random region operation failed on VM_" + inv.getId(), inv.getException());
}
}
vm0.invoke(getCacheSerializableRunnableForIndexValidation(regionName, rindexName));
}
// Tests on Partition Region
@Test
public void testCompactRangeIndexOnPR() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
VM vm2 = host.getVM(2);
VM vm3 = host.getVM(3);
setCacheInVMs(vm0, vm1, vm2, vm3);
vm0.invoke(helper.getCacheSerializableRunnableForPRAccessorCreate(regionName, redundancy,
Portfolio.class));
vm1.invoke(
helper.getCacheSerializableRunnableForPRCreate(regionName, redundancy, Portfolio.class));
vm2.invoke(
helper.getCacheSerializableRunnableForPRCreate(regionName, redundancy, Portfolio.class));
vm3.invoke(
helper.getCacheSerializableRunnableForPRCreate(regionName, redundancy, Portfolio.class));
vm0.invoke(helper.getCacheSerializableRunnableForPRIndexCreate(regionName, indexName,
indexedExpression, fromClause, alias));
AsyncInvocation[] asyncInvs = new AsyncInvocation[12];
asyncInvs[0] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[1] = vm1.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, stepSize, (2 * stepSize)));
asyncInvs[2] = vm2.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(2 * stepSize), (3 * stepSize)));
asyncInvs[3] = vm3.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(3 * (stepSize)), totalDataSize));
asyncInvs[4] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[5] = vm1.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, stepSize, (2 * stepSize)));
asyncInvs[6] = vm2.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(2 * stepSize), (3 * stepSize)));
asyncInvs[7] = vm3.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(3 * (stepSize)), totalDataSize));
asyncInvs[8] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[9] = vm1.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, stepSize, (2 * stepSize)));
asyncInvs[10] = vm2.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(2 * stepSize), (3 * stepSize)));
asyncInvs[11] = vm3.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(3 * (stepSize)), totalDataSize));
for (AsyncInvocation inv : asyncInvs) {
ThreadUtils.join(inv, 60 * 000);
}
for (AsyncInvocation inv : asyncInvs) {
if (inv.exceptionOccurred()) {
Assert.fail("Random region operation failed on VM_" + inv.getId(), inv.getException());
}
}
vm0.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
vm1.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
vm2.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
vm3.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
}
@Test
public void testRangeIndexOnPR() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
VM vm2 = host.getVM(2);
VM vm3 = host.getVM(3);
setCacheInVMs(vm0, vm1, vm2, vm3);
vm0.invoke(helper.getCacheSerializableRunnableForPRAccessorCreate(regionName, redundancy,
Portfolio.class));
vm1.invoke(
helper.getCacheSerializableRunnableForPRCreate(regionName, redundancy, Portfolio.class));
vm2.invoke(
helper.getCacheSerializableRunnableForPRCreate(regionName, redundancy, Portfolio.class));
vm3.invoke(
helper.getCacheSerializableRunnableForPRCreate(regionName, redundancy, Portfolio.class));
vm0.invoke(helper.getCacheSerializableRunnableForPRIndexCreate(regionName, rindexName,
rindexedExpression, rfromClause, ralias));
AsyncInvocation[] asyncInvs = new AsyncInvocation[12];
asyncInvs[0] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[1] = vm1.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, stepSize, (2 * stepSize)));
asyncInvs[2] = vm2.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(2 * stepSize), (3 * stepSize)));
asyncInvs[3] = vm3.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(3 * (stepSize)), totalDataSize));
asyncInvs[4] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[5] = vm1.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, stepSize, (2 * stepSize)));
asyncInvs[6] = vm2.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(2 * stepSize), (3 * stepSize)));
asyncInvs[7] = vm3.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(3 * (stepSize)), totalDataSize));
asyncInvs[8] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[9] = vm1.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, stepSize, (2 * stepSize)));
asyncInvs[10] = vm2.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(2 * stepSize), (3 * stepSize)));
asyncInvs[11] = vm3.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(3 * (stepSize)), totalDataSize));
for (AsyncInvocation inv : asyncInvs) {
ThreadUtils.join(inv, 60 * 000);
}
for (AsyncInvocation inv : asyncInvs) {
if (inv.exceptionOccurred()) {
Assert.fail("Random region operation failed on VM_" + inv.getId(), inv.getException());
}
}
vm0.invoke(getCacheSerializableRunnableForIndexValidation(regionName, rindexName));
vm1.invoke(getCacheSerializableRunnableForIndexValidation(regionName, rindexName));
vm2.invoke(getCacheSerializableRunnableForIndexValidation(regionName, rindexName));
vm3.invoke(getCacheSerializableRunnableForIndexValidation(regionName, rindexName));
}
@Test
public void testMultiIndexOnPR() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
VM vm2 = host.getVM(2);
VM vm3 = host.getVM(3);
setCacheInVMs(vm0, vm1, vm2, vm3);
vm0.invoke(helper.getCacheSerializableRunnableForPRAccessorCreate(regionName, redundancy,
Portfolio.class));
vm1.invoke(
helper.getCacheSerializableRunnableForPRCreate(regionName, redundancy, Portfolio.class));
vm2.invoke(
helper.getCacheSerializableRunnableForPRCreate(regionName, redundancy, Portfolio.class));
vm3.invoke(
helper.getCacheSerializableRunnableForPRCreate(regionName, redundancy, Portfolio.class));
ArrayList<String> names = new ArrayList<String>();
names.add(indexName);
names.add(rindexName);
ArrayList<String> exps = new ArrayList<String>();
exps.add(indexedExpression);
exps.add(rindexedExpression);
ArrayList<String> fromClauses = new ArrayList<String>();
fromClauses.add(fromClause);
fromClauses.add(rfromClause);
vm0.invoke(
helper.getCacheSerializableRunnableForDefineIndex(regionName, names, exps, fromClauses));
AsyncInvocation[] asyncInvs = new AsyncInvocation[12];
asyncInvs[0] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[1] = vm1.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, stepSize, (2 * stepSize)));
asyncInvs[2] = vm2.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(2 * stepSize), (3 * stepSize)));
asyncInvs[3] = vm3.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(3 * (stepSize)), totalDataSize));
asyncInvs[4] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[5] = vm1.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, stepSize, (2 * stepSize)));
asyncInvs[6] = vm2.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(2 * stepSize), (3 * stepSize)));
asyncInvs[7] = vm3.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(3 * (stepSize)), totalDataSize));
asyncInvs[8] =
vm0.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName, 0, stepSize));
asyncInvs[9] = vm1.invokeAsync(
helper.getCacheSerializableRunnableForPRRandomOps(regionName, stepSize, (2 * stepSize)));
asyncInvs[10] = vm2.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(2 * stepSize), (3 * stepSize)));
asyncInvs[11] = vm3.invokeAsync(helper.getCacheSerializableRunnableForPRRandomOps(regionName,
(3 * (stepSize)), totalDataSize));
for (AsyncInvocation inv : asyncInvs) {
ThreadUtils.join(inv, 60 * 000);
}
for (AsyncInvocation inv : asyncInvs) {
if (inv.exceptionOccurred()) {
Assert.fail("Random region operation failed on VM_" + inv.getId(), inv.getException());
}
}
vm0.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
vm1.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
vm2.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
vm3.invoke(getCacheSerializableRunnableForIndexValidation(regionName, indexName));
}
/**
* This validator will iterate over RegionEntries and verify their corresponding index key and
* entry presence in index valuesToEntriesMap.
*/
private static class IndexValidator {
public IndexValidator() {}
private boolean isValidationInProgress;
/**
* Validation is done in the end of test on all indexes of a region by verifying last on a
* region key and verifying state of index based on the last operation.
*
* @param region being validated for all of its indexes.
*/
public void validate(Region region) {
// Get List of All indexes.
Collection<Index> indexes = ((LocalRegion) region).getIndexManager().getIndexes();
// validate each index one by one
for (Index index : indexes) {
if (region instanceof PartitionedRegion) {
validateOnPR((PartitionedRegion) region, (PartitionedIndex) index);
} else {
validate(region, index);
}
}
}
private void validate(Region region, Index index) {
// Get index expression
String indexExpr = index.getIndexedExpression();
int expectedIndexSize = 0;
int expectedNullEntries = 0;
int expectedUndefinedEntries = 0;
// Lets check if it contains a '.'
if (indexExpr.indexOf(".") != -1) {
indexExpr = indexExpr.substring(indexExpr.indexOf(".") + 1);
}
// do a get<indexExpr>() on each region value and verify if the
// evaluated index key is part of index and has RE as a reference to it
Collection<RegionEntry> entries = ((LocalRegion) region).entries.regionEntries();
for (RegionEntry internalEntry : entries) {
Object value = internalEntry.getValueInVM((LocalRegion) region);
if (value instanceof CachedDeserializable) {
value = ((CachedDeserializable) value).getDeserializedValue(region, internalEntry);
}
if (indexExpr.equals("ID")) {
// Compact Range Index
if (index instanceof CompactRangeIndex) {
// Ignore invalid values.
if (value != Token.INVALID && value != Token.TOMBSTONE) {
LogWriterUtils.getLogWriter().info("Portfolio: " + ((Portfolio) value));
Integer ID = ((Portfolio) value).getID();
assertTrue(
"Did not find index key for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName(),
((CompactRangeIndex) index).getIndexStorage().get(ID) == null ? false : true);
// Get Index value for the evaluated index key.
CloseableIterator<IndexStoreEntry> valuesForKeyIterator = null;
try {
valuesForKeyIterator = ((CompactRangeIndex) index).getIndexStorage().get(ID);
// Check if RegionEntry is present in Index for the key
// evaluated from
// region value.
while (valuesForKeyIterator.hasNext()) {
assertTrue(
"Did not find index value for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName()
+ " For index key: " + ID,
(((MemoryIndexStoreEntry) valuesForKeyIterator.next())
.getRegionEntry() == internalEntry));
}
} finally {
if (valuesForKeyIterator != null) {
valuesForKeyIterator.close();
}
}
if (ID != IndexManager.NULL) {
expectedIndexSize++;
} else {
expectedNullEntries++;
}
} else {
LogWriterUtils.getLogWriter().info(internalEntry.getKey() + "");
expectedUndefinedEntries++;
}
}
} else if (indexExpr.equals("secId")) {
if (index instanceof RangeIndex) {
// Ignore invalid values.
if (value != Token.INVALID && value != Token.TOMBSTONE) {
Collection<Position> positions = ((Portfolio) value).positions.values();
for (Position pos : positions) {
if (pos != null) {
LogWriterUtils.getLogWriter()
.info("Portfolio: " + ((Portfolio) value) + "Position: " + pos);
String secId = pos.secId;
assertTrue(
"Did not find index key for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName(),
((RangeIndex) index).valueToEntriesMap.containsKey(secId));
// Get Index value for the evaluated index key.
Object valuesForKey = ((RangeIndex) index).valueToEntriesMap.get(secId);
// Check if RegionEntry is present in Index for the key evaluated from
// region value.
if (!(valuesForKey instanceof RegionEntryToValuesMap)) {
assertTrue(
"Did not find index value for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName()
+ " For index key: " + secId,
((RegionEntry) valuesForKey == internalEntry));
} else {
assertTrue(
"Did not find index value for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName()
+ " For index key: " + secId,
(((RegionEntryToValuesMap) valuesForKey).containsEntry(internalEntry)));
}
if (secId != null) {
expectedIndexSize++;
} else {
expectedNullEntries++;
}
} else {
expectedUndefinedEntries++;
}
}
}
}
}
}
// Validate sizes for index map, null and undefined maps.
int actualSize = 0;
if (index instanceof CompactRangeIndex) {
CloseableIterator<IndexStoreEntry> iter = null;
try {
iter = ((CompactRangeIndex) index).getIndexStorage().iterator(null);
while (iter.hasNext()) {
Object value = iter.next();
// getLogWriter().info(
// "Index Values : " + value);
actualSize++;
}
} finally {
if (iter != null) {
iter.close();
}
}
}
if (index instanceof RangeIndex) {
for (Object value : ((RangeIndex) index).valueToEntriesMap.values()) {
if (value instanceof RegionEntry) {
actualSize++;
} else {
// for (Object obj: ((RegionEntryToValuesMap)value).map.values()) {
// getLogWriter().info("Index Values : "+ obj.toString());
// }
actualSize += ((RegionEntryToValuesMap) value).getNumValues();
}
}
}
IndexStatistics stats = index.getStatistics();
if (index instanceof CompactRangeIndex) {
LogWriterUtils.getLogWriter().info(" Actual Size of Index is: " + actualSize);
/*
* getLogWriter().info( " Actual Size of Index is: " + actualSize + " Undefined size is: " +
* ((CompactRangeIndex) index).undefinedMappedEntries.size() + " And NULL size is: " +
* ((CompactRangeIndex) index).nullMappedEntries.size()); for (Object obj :
* ((CompactRangeIndex) index).undefinedMappedEntries .toArray()) {
* getLogWriter().info(((RegionEntry) obj).getKey() + ""); }
*/
LogWriterUtils.getLogWriter()
.info(" Expected Size of Index is: " + expectedIndexSize + " Undefined size is: "
+ expectedUndefinedEntries + " And NULL size is: " + expectedNullEntries);
assertEquals(
"No of index keys NOT equals the no shown in statistics for index:" + index.getName(),
((CompactRangeIndex) index).getIndexStorage().size(), stats.getNumberOfKeys());
} else {
LogWriterUtils.getLogWriter()
.info(" Actual Size of Index is: " + actualSize + " Undefined size is: "
+ ((RangeIndex) index).undefinedMappedEntries.getNumEntries()
+ " And NULL size is: " + ((RangeIndex) index).nullMappedEntries.getNumEntries());
for (Object obj : ((RangeIndex) index).undefinedMappedEntries.map.keySet()) {
LogWriterUtils.getLogWriter().info(((RegionEntry) obj).getKey() + "");
}
LogWriterUtils.getLogWriter()
.info(" Expected Size of Index is: " + expectedIndexSize + " Undefined size is: "
+ expectedUndefinedEntries + " And NULL size is: " + expectedNullEntries);
assertEquals(
"No of index keys NOT equals the no shown in statistics for index:" + index.getName(),
((RangeIndex) index).valueToEntriesMap.keySet().size(), stats.getNumberOfKeys());
}
assertEquals(
"No of index entries NOT equal the No of RegionEntries Basec on statistics for index:"
+ index.getName(),
(expectedIndexSize + expectedNullEntries), stats.getNumberOfValues());
assertEquals(
"No of index entries NOT equals the No of RegionEntries for index:" + index.getName(),
expectedIndexSize, actualSize);
GemFireCacheImpl.getInstance().getLogger().fine("Finishing the validation for region: "
+ region.getFullPath() + " and Index: " + index.getName());
}
private void validateOnPR(PartitionedRegion pr, PartitionedIndex ind) {
// Get index expression
String indexExpr = ind.getIndexedExpression();
int expectedIndexSize = 0;
int expectedNullEntries = 0;
int expectedUndefinedEntries = 0;
// Lets check if it contains a '.'
if (indexExpr.indexOf(".") != -1) {
indexExpr = indexExpr.substring(indexExpr.indexOf(".") + 1);
}
int actualValueSize = 0;
int actualKeySize = 0;
for (Object idx : ind.getBucketIndexes()) {
Index index = (Index) idx;
assertTrue("Bucket stats are different than PR stats for bucket: " + index.getRegion(),
index.getStatistics() == ind.getStatistics());
Region region = index.getRegion();
// do a get<indexExpr>() on each region value and verify if the
// evaluated index key is part of index and has RE as a reference to it
Collection<RegionEntry> entries = ((LocalRegion) region).entries.regionEntries();
for (RegionEntry internalEntry : entries) {
Object value = internalEntry.getValueInVM((LocalRegion) region);
if (value instanceof CachedDeserializable) {
value = ((CachedDeserializable) value).getDeserializedValue(region, internalEntry);
}
if (indexExpr.equals("ID")) {
// Compact Range Index
if (index instanceof CompactRangeIndex) {
// Ignore invalid values.
if (value != Token.INVALID && value != Token.TOMBSTONE) {
LogWriterUtils.getLogWriter().info("Portfolio: " + ((Portfolio) value));
Integer ID = ((Portfolio) value).getID();
assertTrue(
"Did not find index key for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName(),
((CompactRangeIndex) index).getIndexStorage().get(ID) == null ? false : true);
// Get Index value for the evaluated index key.
CloseableIterator<IndexStoreEntry> valuesForKeyIterator = null;
try {
valuesForKeyIterator = ((CompactRangeIndex) index).getIndexStorage().get(ID);
// Check if RegionEntry is present in Index for the key
// evaluated from
// region value.
while (valuesForKeyIterator.hasNext()) {
assertTrue(
"Did not find index value for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName()
+ " For index key: " + ID,
(((MemoryIndexStoreEntry) valuesForKeyIterator.next())
.getRegionEntry() == internalEntry));
}
} finally {
if (valuesForKeyIterator != null) {
valuesForKeyIterator.close();
}
}
if (ID != IndexManager.NULL) {
expectedIndexSize++;
} else {
expectedNullEntries++;
}
} else {
expectedUndefinedEntries++;
}
}
} else if (indexExpr.equals("secId")) {
if (index instanceof RangeIndex) {
// Ignore invalid values.
if (value != Token.INVALID && value != Token.TOMBSTONE) {
Collection<Position> positions = ((Portfolio) value).positions.values();
for (Position pos : positions) {
if (pos != null) {
LogWriterUtils.getLogWriter()
.info("Portfolio: " + ((Portfolio) value) + "Position: " + pos);
String secId = pos.secId;
assertTrue(
"Did not find index key for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName(),
((RangeIndex) index).valueToEntriesMap.containsKey(secId));
// Get Index value for the evaluated index key.
Object valuesForKey = ((RangeIndex) index).valueToEntriesMap.get(secId);
// Check if RegionEntry is present in Index for the key evaluated from
// region value.
if (!(valuesForKey instanceof RegionEntryToValuesMap)) {
assertTrue(
"Did not find index value for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName()
+ " For index key: " + secId,
((RegionEntry) valuesForKey == internalEntry));
} else {
assertTrue(
"Did not find index value for REgionEntry [key: " + internalEntry.getKey()
+ " , value: " + value + " ] in index: " + index.getName()
+ " For index key: " + secId,
(((RegionEntryToValuesMap) valuesForKey).containsEntry(internalEntry)));
}
if (secId != null) {
expectedIndexSize++;
} else {
expectedNullEntries++;
}
} else {
expectedUndefinedEntries++;
}
}
}
}
}
}
// Validate sizes for index map, null and undefined maps.
if (index instanceof CompactRangeIndex) {
CloseableIterator<IndexStoreEntry> iter = null;
try {
iter = ((CompactRangeIndex) index).getIndexStorage().iterator(null);
while (iter.hasNext()) {
LogWriterUtils.getLogWriter()
.info("Index Values : " + iter.next().getDeserializedValue());
actualValueSize++;
}
} finally {
if (iter != null) {
iter.close();
}
}
}
if (index instanceof RangeIndex) {
for (Object value : ((RangeIndex) index).valueToEntriesMap.values()) {
if (value instanceof RegionEntry) {
actualValueSize++;
} else {
actualValueSize += ((RegionEntryToValuesMap) value).getNumValues();
}
}
}
if (index instanceof CompactRangeIndex) {
actualKeySize += ((CompactRangeIndex) index).getIndexStorage().size();
} else {
actualKeySize += ((RangeIndex) index).valueToEntriesMap.keySet().size();
}
}
assertEquals(
"No of index entries NOT equals the No of RegionENtries NOT based on stats for index:"
+ ind.getName(),
expectedIndexSize, actualValueSize);
IndexStatistics stats = ind.getStatistics();
assertEquals(
"No of index entries NOT equals the No of RegionENtries based on statistics for index:"
+ ind.getName(),
(expectedIndexSize + expectedNullEntries), stats.getNumberOfValues());
GemFireCacheImpl.getInstance().getLogger().fine("Finishing the validation for region: "
+ pr.getFullPath() + " and Index: " + ind.getName());
}
}
}