Search in sources :

Example 1 with IndexMaintenanceException

use of org.apache.geode.cache.query.IndexMaintenanceException in project geode by apache.

the class MapRangeIndexMaintenanceJUnitTest method testDuplicateKeysInRangeIndexOnLocalRegion.

/**
   * Test index object's comapreTo Function implementation correctness for indexes.
   * 
   * @throws Exception
   */
@Test
public void testDuplicateKeysInRangeIndexOnLocalRegion() throws Exception {
    IndexManager.TEST_RANGEINDEX_ONLY = true;
    // Create Partition Region
    AttributesFactory af = new AttributesFactory();
    af.setScope(Scope.LOCAL);
    Portfolio p = new Portfolio(1, 1);
    HashMap map1 = new HashMap();
    map1.put("SUN", new TestObject("SUN", 1));
    map1.put("IBM", new TestObject("IBM", 2));
    p.positions = map1;
    region = CacheUtils.createRegion("portfolio", af.create(), false);
    qs = CacheUtils.getQueryService();
    keyIndex1 = (IndexProtocol) qs.createIndex(INDEX_NAME, "positions[*]", "/portfolio");
    assertTrue(keyIndex1 instanceof MapRangeIndex);
    // Put duplicate TestObject with "IBM" name.
    region.put(Integer.toString(1), p);
    Portfolio p2 = new Portfolio(2, 2);
    HashMap map2 = new HashMap();
    map2.put("YHOO", new TestObject("YHOO", 3));
    map2.put("IBM", new TestObject("IBM", 2));
    p2.positions = map2;
    region.put(Integer.toString(2), p2);
    // Following destroy fails if fix for 44123 is not there.
    try {
        region.destroy(Integer.toString(1));
    } catch (NullPointerException e) {
        fail("Test Failed! region.destroy got NullPointerException!");
    } catch (Exception ex) {
        if (ex instanceof IndexMaintenanceException) {
            if (!ex.getCause().getMessage().contains("compareTo function is errorneous")) {
                fail("Test Failed! Did not get expected exception IMQException." + ex.getMessage());
            }
        } else {
            ex.printStackTrace();
            fail("Test Failed! Did not get expected exception IMQException.");
        }
    }
}
Also used : AttributesFactory(org.apache.geode.cache.AttributesFactory) HashMap(java.util.HashMap) Portfolio(org.apache.geode.cache.query.data.Portfolio) IndexMaintenanceException(org.apache.geode.cache.query.IndexMaintenanceException) IndexMaintenanceException(org.apache.geode.cache.query.IndexMaintenanceException) Test(org.junit.Test) IntegrationTest(org.apache.geode.test.junit.categories.IntegrationTest)

Example 2 with IndexMaintenanceException

use of org.apache.geode.cache.query.IndexMaintenanceException in project geode by apache.

the class MapRangeIndexMaintenanceJUnitTest method testDuplicateKeysInCompactRangeIndexOnLocalRegion.

/**
   * Test index object's comapreTo Function implementation correctness for indexes.
   * 
   * @throws Exception
   */
@Test
public void testDuplicateKeysInCompactRangeIndexOnLocalRegion() throws Exception {
    // Create Partition Region
    AttributesFactory af = new AttributesFactory();
    af.setScope(Scope.LOCAL);
    Portfolio p = new Portfolio(1, 1);
    HashMap map1 = new HashMap();
    map1.put("SUN", new TestObject("SUN", 1));
    map1.put("IBM", new TestObject("IBM", 2));
    p.positions = map1;
    region = CacheUtils.createRegion("portfolio", af.create(), false);
    qs = CacheUtils.getQueryService();
    keyIndex1 = (IndexProtocol) qs.createIndex(INDEX_NAME, "positions[*]", "/portfolio");
    assertTrue(keyIndex1 instanceof CompactMapRangeIndex);
    // Put duplicate TestObject with "IBM" name.
    region.put(Integer.toString(1), p);
    Portfolio p2 = new Portfolio(2, 2);
    HashMap map2 = new HashMap();
    map2.put("YHOO", new TestObject("YHOO", 3));
    map2.put("IBM", new TestObject("IBM", 2));
    p2.positions = map2;
    region.put(Integer.toString(2), p2);
    // Following destroy fails if fix for 44123 is not there.
    try {
        region.destroy(Integer.toString(1));
    } catch (NullPointerException e) {
        fail("Test Failed! region.destroy got NullPointerException!");
    } catch (Exception ex) {
        if (ex instanceof IndexMaintenanceException) {
            if (!ex.getCause().getMessage().contains("compareTo function is errorneous")) {
                fail("Test Failed! Did not get expected exception IMQException." + ex.getMessage());
            }
        } else {
            ex.printStackTrace();
            fail("Test Failed! Did not get expected exception IMQException.");
        }
    }
}
Also used : AttributesFactory(org.apache.geode.cache.AttributesFactory) HashMap(java.util.HashMap) Portfolio(org.apache.geode.cache.query.data.Portfolio) IndexMaintenanceException(org.apache.geode.cache.query.IndexMaintenanceException) IndexMaintenanceException(org.apache.geode.cache.query.IndexMaintenanceException) Test(org.junit.Test) IntegrationTest(org.apache.geode.test.junit.categories.IntegrationTest)

Example 3 with IndexMaintenanceException

use of org.apache.geode.cache.query.IndexMaintenanceException in project geode by apache.

the class MemoryIndexStore method updateMapping.

@Override
public void updateMapping(Object indexKey, Object oldKey, RegionEntry re, Object oldValue) throws IMQException {
    try {
        if (DefaultQuery.testHook != null) {
            DefaultQuery.testHook.doTestHook(3);
        }
        // Check if reverse-map is present.
        if (IndexManager.isObjectModificationInplace()) {
            // If reverse map get the old index key from reverse map.
            if (this.entryToValuesMap.containsKey(re)) {
                oldKey = this.entryToValuesMap.get(re);
            }
        } else {
            // forward map.
            if (oldValue != null && oldValue == getTargetObjectInVM(re)) {
                oldKey = getOldKey(indexKey, re);
            }
        }
        // No need to update the map if new and old index key are same.
        if (oldKey != null && oldKey.equals(TypeUtils.indexKeyFor(indexKey))) {
            return;
        }
        boolean retry = false;
        indexKey = TypeUtils.indexKeyFor(indexKey);
        if (indexKey.equals(QueryService.UNDEFINED)) {
            Object targetObject = getTargetObjectForUpdate(re);
            if (Token.isInvalidOrRemoved(targetObject)) {
                if (oldKey != null) {
                    basicRemoveMapping(oldKey, re, false);
                }
                return;
            }
        }
        do {
            retry = false;
            Object regionEntries = this.valueToEntriesMap.putIfAbsent(indexKey, re);
            if (regionEntries == TRANSITIONING_TOKEN) {
                retry = true;
                continue;
            } else if (regionEntries == null) {
                internalIndexStats.incNumKeys(1);
                numIndexKeys.incrementAndGet();
            } else if (regionEntries instanceof RegionEntry) {
                IndexElemArray elemArray = new IndexElemArray();
                if (DefaultQuery.testHook != null) {
                    DefaultQuery.testHook.doTestHook("BEGIN_TRANSITION_FROM_REGION_ENTRY_TO_ELEMARRAY");
                }
                elemArray.add(regionEntries);
                elemArray.add(re);
                if (!this.valueToEntriesMap.replace(indexKey, regionEntries, elemArray)) {
                    retry = true;
                }
                if (DefaultQuery.testHook != null) {
                    DefaultQuery.testHook.doTestHook("TRANSITIONED_FROM_REGION_ENTRY_TO_ELEMARRAY");
                }
                if (DefaultQuery.testHook != null) {
                    DefaultQuery.testHook.doTestHook("COMPLETE_TRANSITION_FROM_REGION_ENTRY_TO_ELEMARRAY");
                }
            } else if (regionEntries instanceof IndexConcurrentHashSet) {
                // basicRemoveMapping();
                synchronized (regionEntries) {
                    ((IndexConcurrentHashSet) regionEntries).add(re);
                }
                if (regionEntries != this.valueToEntriesMap.get(indexKey)) {
                    retry = true;
                }
            } else {
                IndexElemArray elemArray = (IndexElemArray) regionEntries;
                synchronized (elemArray) {
                    if (elemArray.size() >= IndexManager.INDEX_ELEMARRAY_THRESHOLD) {
                        IndexConcurrentHashSet set = new IndexConcurrentHashSet(IndexManager.INDEX_ELEMARRAY_THRESHOLD + 20, 0.75f, 1);
                        if (DefaultQuery.testHook != null) {
                            DefaultQuery.testHook.doTestHook("BEGIN_TRANSITION_FROM_ELEMARRAY_TO_CONCURRENT_HASH_SET");
                        }
                        // retry?
                        if (!this.valueToEntriesMap.replace(indexKey, regionEntries, TRANSITIONING_TOKEN)) {
                            retry = true;
                        } else {
                            if (DefaultQuery.testHook != null) {
                                DefaultQuery.testHook.doTestHook("TRANSITIONED_FROM_ELEMARRAY_TO_TOKEN");
                            }
                            set.add(re);
                            set.addAll(elemArray);
                            if (!this.valueToEntriesMap.replace(indexKey, TRANSITIONING_TOKEN, set)) {
                                // This should never happen. If we see this in the log, then something is wrong
                                // with the TRANSITIONING TOKEN and synchronization of changing collection types
                                // we should then just go from RE to CHS and completely remove the Elem Array.
                                region.getCache().getLogger().warning("Unable to transition from index elem to concurrent hash set.  Index needs to be recreated");
                                throw new IndexMaintenanceException("Unable to transition from index elem to concurrent hash set.  Index needs to be recreated");
                            }
                            if (DefaultQuery.testHook != null) {
                                DefaultQuery.testHook.doTestHook("COMPLETE_TRANSITION_FROM_ELEMARRAY_TO_CONCURRENT_HASH_SET");
                            }
                        }
                    } else {
                        elemArray.add(re);
                        if (regionEntries != this.valueToEntriesMap.get(indexKey)) {
                            retry = true;
                        }
                    }
                }
            }
            // Add to reverse Map with the new value.
            if (!retry) {
                // oldKey is not null only for an update
                if (oldKey != null) {
                    basicRemoveMapping(oldKey, re, false);
                }
                if (IndexManager.isObjectModificationInplace()) {
                    this.entryToValuesMap.put(re, indexKey);
                }
            }
        } while (retry);
    } catch (TypeMismatchException ex) {
        throw new IMQException("Could not add object of type " + indexKey.getClass().getName(), ex);
    }
    internalIndexStats.incNumValues(1);
}
Also used : TypeMismatchException(org.apache.geode.cache.query.TypeMismatchException) RegionEntry(org.apache.geode.internal.cache.RegionEntry) IndexMaintenanceException(org.apache.geode.cache.query.IndexMaintenanceException)

Example 4 with IndexMaintenanceException

use of org.apache.geode.cache.query.IndexMaintenanceException in project geode by apache.

the class IndexManager method processAction.

/**
   * @param opCode one of IndexProtocol.OTHER_OP, BEFORE_UPDATE_OP, AFTER_UPDATE_OP.
   */
private void processAction(RegionEntry entry, int action, int opCode) throws QueryException {
    final long startPA = getCachePerfStats().startIndexUpdate();
    DefaultQuery.setPdxReadSerialized(this.region.getCache(), true);
    TXStateProxy tx = null;
    if (!((InternalCache) this.region.getCache()).isClient()) {
        tx = ((TXManagerImpl) this.region.getCache().getCacheTransactionManager()).internalSuspend();
    }
    try {
        // creation thread
        if (IndexManager.testHook != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("IndexManager TestHook is set.");
            }
            // ConcurrentIndexInitOnOverflowRegionDUnitTest
            testHook.hook(6);
        }
        long start = 0;
        boolean indexLockAcquired = false;
        switch(action) {
            case ADD_ENTRY:
                {
                    if (IndexManager.testHook != null) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("IndexManager TestHook in ADD_ENTRY.");
                        }
                        testHook.hook(5);
                    }
                    // this action is only called after update
                    assert opCode == IndexProtocol.OTHER_OP;
                    // Asif The behaviour can arise if an index creation has already
                    // acted upon a newly added entry , but by the time callback
                    // occurs , the index is added to the map & thus
                    // the add operation will now have an effect of update.
                    // so we need to remove the mapping even if it is an Add action
                    // as otherwise the new results will get added into the
                    // old results instead of replacement
                    Iterator iter = this.indexes.values().iterator();
                    while (iter.hasNext()) {
                        Object ind = iter.next();
                        // the index is in create phase.
                        if (ind instanceof FutureTask) {
                            continue;
                        }
                        IndexProtocol index = (IndexProtocol) ind;
                        if (((AbstractIndex) index).isPopulated() && index.getType() != IndexType.PRIMARY_KEY) {
                            // apply IMQ on it
                            if (!index.containsEntry(entry)) {
                                if (logger.isDebugEnabled()) {
                                    logger.debug("Adding to index: {}{} value: {}", index.getName(), this.region.getFullPath(), entry.getKey());
                                }
                                start = ((AbstractIndex) index).updateIndexUpdateStats();
                                index.addIndexMapping(entry);
                                ((AbstractIndex) index).updateIndexUpdateStats(start);
                            }
                        }
                    }
                    break;
                }
            case UPDATE_ENTRY:
                {
                    if (IndexManager.testHook != null) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("IndexManager TestHook in UPDATE_ENTRY.");
                        }
                        testHook.hook(5);
                        // QueryDataInconsistencyDUnitTest
                        testHook.hook(9);
                    }
                    // this action is only called with opCode AFTER_UPDATE_OP
                    assert opCode == IndexProtocol.AFTER_UPDATE_OP;
                    Iterator iter = this.indexes.values().iterator();
                    while (iter.hasNext()) {
                        Object ind = iter.next();
                        // the index is in create phase.
                        if (ind instanceof FutureTask) {
                            continue;
                        }
                        IndexProtocol index = (IndexProtocol) ind;
                        if (((AbstractIndex) index).isPopulated() && index.getType() != IndexType.PRIMARY_KEY) {
                            if (logger.isDebugEnabled()) {
                                logger.debug("Updating index: {}{} value: {}", index.getName(), this.region.getFullPath(), entry.getKey());
                            }
                            start = ((AbstractIndex) index).updateIndexUpdateStats();
                            index.addIndexMapping(entry);
                            ((AbstractIndex) index).updateIndexUpdateStats(start);
                        }
                    }
                    break;
                }
            case REMOVE_ENTRY:
                {
                    if (IndexManager.testHook != null) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("IndexManager TestHook in REMOVE_ENTRY.");
                        }
                        testHook.hook(5);
                        testHook.hook(10);
                    }
                    Iterator iter = this.indexes.values().iterator();
                    while (iter.hasNext()) {
                        Object ind = iter.next();
                        // the index is in create phase.
                        if (ind instanceof FutureTask) {
                            continue;
                        }
                        IndexProtocol index = (IndexProtocol) ind;
                        if (((AbstractIndex) index).isPopulated() && index.getType() != IndexType.PRIMARY_KEY) {
                            AbstractIndex abstractIndex = (AbstractIndex) index;
                            if (logger.isDebugEnabled()) {
                                logger.debug("Removing from index: {}{} value: {}", index.getName(), this.region.getFullPath(), entry.getKey());
                            }
                            start = ((AbstractIndex) index).updateIndexUpdateStats();
                            index.removeIndexMapping(entry, opCode);
                            ((AbstractIndex) index).updateIndexUpdateStats(start);
                        }
                    }
                    break;
                }
            default:
                {
                    throw new IndexMaintenanceException(LocalizedStrings.IndexManager_INVALID_ACTION.toLocalizedString());
                }
        }
    } finally {
        DefaultQuery.setPdxReadSerialized(this.region.getCache(), false);
        if (tx != null) {
            ((TXManagerImpl) this.region.getCache().getCacheTransactionManager()).internalResume(tx);
        }
        getCachePerfStats().endIndexUpdate(startPA);
    }
}
Also used : TXManagerImpl(org.apache.geode.internal.cache.TXManagerImpl) FutureTask(java.util.concurrent.FutureTask) TXStateProxy(org.apache.geode.internal.cache.TXStateProxy) Iterator(java.util.Iterator) IndexMaintenanceException(org.apache.geode.cache.query.IndexMaintenanceException)

Example 5 with IndexMaintenanceException

use of org.apache.geode.cache.query.IndexMaintenanceException in project geode by apache.

the class AbstractRegionEntry method destroy.

/**
   * @throws EntryNotFoundException if expectedOldValue is not null and is not equal to current
   *         value
   */
@Override
@Released
public boolean destroy(LocalRegion region, EntryEventImpl event, boolean inTokenMode, boolean cacheWrite, @Unretained Object expectedOldValue, boolean forceDestroy, boolean removeRecoveredEntry) throws CacheWriterException, EntryNotFoundException, TimeoutException, RegionClearedException {
    // A design decision was made to not retrieve the old value from the disk
    // if the entry has been evicted to only have the CacheListener afterDestroy
    // method ignore it. We don't want to pay the performance penalty. The
    // getValueInVM method does not retrieve the value from disk if it has been
    // evicted. Instead, it uses the NotAvailable token.
    //
    // If the region is a WAN queue region, the old value is actually used by the
    // afterDestroy callback on a secondary. It is not needed on a primary.
    // Since the destroy that sets WAN_QUEUE_TOKEN always originates on the primary
    // we only pay attention to WAN_QUEUE_TOKEN if the event is originRemote.
    //
    // We also read old value from disk or buffer
    // in the case where there is a non-null expectedOldValue
    // see PartitionedRegion#remove(Object key, Object value)
    ReferenceCountHelper.skipRefCountTracking();
    @Retained @Released Object curValue = _getValueRetain(region, true);
    ReferenceCountHelper.unskipRefCountTracking();
    boolean proceed;
    try {
        if (curValue == null) {
            curValue = Token.NOT_AVAILABLE;
        }
        if (curValue == Token.NOT_AVAILABLE) {
            // the state of the transmitting cache's entry & should be used here
            if (event.getCallbackArgument() != null && event.getCallbackArgument().equals(RegionQueue.WAN_QUEUE_TOKEN) && event.isOriginRemote()) {
                // check originRemote for bug 40508
                // curValue = getValue(region); can cause deadlock if GII is occurring
                curValue = getValueOnDiskOrBuffer(region);
            } else {
                FilterProfile fp = region.getFilterProfile();
                if (fp != null && (fp.getCqCount() > 0 || expectedOldValue != null)) {
                    // curValue = getValue(region); can cause deadlock will fault in the value
                    // and will confuse LRU.
                    curValue = getValueOnDiskOrBuffer(region);
                }
            }
        }
        if (expectedOldValue != null) {
            if (!checkExpectedOldValue(expectedOldValue, curValue, region)) {
                throw new EntryNotFoundException(LocalizedStrings.AbstractRegionEntry_THE_CURRENT_VALUE_WAS_NOT_EQUAL_TO_EXPECTED_VALUE.toLocalizedString());
            }
        }
        if (inTokenMode && event.hasOldValue()) {
            proceed = true;
        } else {
            proceed = event.setOldValue(curValue, curValue instanceof GatewaySenderEventImpl) || removeRecoveredEntry || forceDestroy || region.getConcurrencyChecksEnabled() || (event.getOperation() == Operation.REMOVE && (curValue == null || curValue == Token.LOCAL_INVALID || curValue == Token.INVALID));
        }
    } finally {
        OffHeapHelper.releaseWithNoTracking(curValue);
    }
    if (proceed) {
        // after the entry not found exception above.
        if (!removeRecoveredEntry) {
            region.generateAndSetVersionTag(event, this);
        }
        if (cacheWrite) {
            region.cacheWriteBeforeDestroy(event, expectedOldValue);
            if (event.getRegion().getServerProxy() != null) {
                // server will return a version tag
                // update version information (may throw ConcurrentCacheModificationException)
                VersionStamp stamp = getVersionStamp();
                if (stamp != null) {
                    stamp.processVersionTag(event);
                }
            }
        }
        region.recordEvent(event);
        // RegionEntry (the old value) is invalid
        if (!region.isProxy() && !isInvalid()) {
            IndexManager indexManager = region.getIndexManager();
            if (indexManager != null) {
                try {
                    if (isValueNull()) {
                        @Released Object value = getValueOffHeapOrDiskWithoutFaultIn(region);
                        try {
                            Object preparedValue = prepareValueForCache(region, value, false);
                            _setValue(preparedValue);
                            releaseOffHeapRefIfRegionBeingClosedOrDestroyed(region, preparedValue);
                        } finally {
                            OffHeapHelper.release(value);
                        }
                    }
                    indexManager.updateIndexes(this, IndexManager.REMOVE_ENTRY, IndexProtocol.OTHER_OP);
                } catch (QueryException e) {
                    throw new IndexMaintenanceException(e);
                }
            }
        }
        boolean removeEntry = false;
        VersionTag v = event.getVersionTag();
        if (region.concurrencyChecksEnabled && !removeRecoveredEntry && !event.isFromRILocalDestroy()) {
            // Destroy will write a tombstone instead
            if (v == null || !v.hasValidVersion()) {
                // localDestroy and eviction and ops received with no version tag
                // should create a tombstone using the existing version stamp, as should
                // (bug #45245) responses from servers that do not have valid version information
                VersionStamp stamp = this.getVersionStamp();
                if (stamp != null) {
                    // proxy has no stamps
                    v = stamp.asVersionTag();
                    event.setVersionTag(v);
                }
            }
            removeEntry = v == null || !v.hasValidVersion();
        } else {
            removeEntry = true;
        }
        if (removeEntry) {
            boolean isThisTombstone = isTombstone();
            if (inTokenMode && !event.getOperation().isEviction()) {
                setValue(region, Token.DESTROYED);
            } else {
                removePhase1(region, false);
            }
            if (isThisTombstone) {
                region.unscheduleTombstone(this);
            }
        } else {
            makeTombstone(region, v);
        }
        return true;
    } else {
        return false;
    }
}
Also used : IndexManager(org.apache.geode.cache.query.internal.index.IndexManager) QueryException(org.apache.geode.cache.query.QueryException) Released(org.apache.geode.internal.offheap.annotations.Released) Retained(org.apache.geode.internal.offheap.annotations.Retained) EntryNotFoundException(org.apache.geode.cache.EntryNotFoundException) GatewaySenderEventImpl(org.apache.geode.internal.cache.wan.GatewaySenderEventImpl) VersionTag(org.apache.geode.internal.cache.versions.VersionTag) StoredObject(org.apache.geode.internal.offheap.StoredObject) VersionStamp(org.apache.geode.internal.cache.versions.VersionStamp) IndexMaintenanceException(org.apache.geode.cache.query.IndexMaintenanceException) Released(org.apache.geode.internal.offheap.annotations.Released)

Aggregations

IndexMaintenanceException (org.apache.geode.cache.query.IndexMaintenanceException)9 QueryException (org.apache.geode.cache.query.QueryException)5 StoredObject (org.apache.geode.internal.offheap.StoredObject)3 HashMap (java.util.HashMap)2 Iterator (java.util.Iterator)2 AttributesFactory (org.apache.geode.cache.AttributesFactory)2 Portfolio (org.apache.geode.cache.query.data.Portfolio)2 IndexManager (org.apache.geode.cache.query.internal.index.IndexManager)2 Retained (org.apache.geode.internal.offheap.annotations.Retained)2 IntegrationTest (org.apache.geode.test.junit.categories.IntegrationTest)2 Test (org.junit.Test)2 Collection (java.util.Collection)1 FutureTask (java.util.concurrent.FutureTask)1 CancelException (org.apache.geode.CancelException)1 EntryNotFoundException (org.apache.geode.cache.EntryNotFoundException)1 Operation (org.apache.geode.cache.Operation)1 RegionDestroyedException (org.apache.geode.cache.RegionDestroyedException)1 TypeMismatchException (org.apache.geode.cache.query.TypeMismatchException)1 InternalDistributedSystem (org.apache.geode.distributed.internal.InternalDistributedSystem)1 RegionEntry (org.apache.geode.internal.cache.RegionEntry)1