use of java.util.concurrent.FutureTask in project geode by apache.
the class IndexManager method createIndex.
// @todo need more specific list of exceptions
/**
* Create an index that can be used when executing queries.
*
* @param indexName the name of this index, used for statistics collection
* @param indexType the type of index
* @param origIndexedExpression the expression to index on, a function dependent on region entries
* individually.
* @param origFromClause expression that evaluates to the collection(s) that will be queried over,
* must contain one and only one region path.
* @return the newly created Index
*/
public Index createIndex(String indexName, IndexType indexType, String origIndexedExpression, String origFromClause, String imports, ExecutionContext externalContext, PartitionedIndex prIndex, boolean loadEntries) throws IndexNameConflictException, IndexExistsException, IndexInvalidException {
if (QueryMonitor.isLowMemory()) {
throw new IndexInvalidException(LocalizedStrings.IndexCreationMsg_CANCELED_DUE_TO_LOW_MEMORY.toLocalizedString());
}
boolean oldReadSerialized = DefaultQuery.getPdxReadSerialized();
DefaultQuery.setPdxReadSerialized(this.region.getCache(), true);
TXStateProxy tx = null;
if (!((InternalCache) this.region.getCache()).isClient()) {
tx = ((TXManagerImpl) this.region.getCache().getCacheTransactionManager()).internalSuspend();
}
try {
// for now this is the only option
String projectionAttributes = "*";
if (getIndex(indexName) != null) {
throw new IndexNameConflictException(LocalizedStrings.IndexManager_INDEX_NAMED_0_ALREADY_EXISTS.toLocalizedString(indexName));
}
IndexCreationHelper helper = null;
boolean isCompactOrHash = false;
// to recalculate the index key for the entry for comparisons during query.
if (indexType == IndexType.HASH && isOverFlowRegion()) {
indexType = IndexType.FUNCTIONAL;
}
if (indexType != IndexType.PRIMARY_KEY) {
helper = new FunctionalIndexCreationHelper(origFromClause, origIndexedExpression, projectionAttributes, imports, (InternalCache) region.getCache(), externalContext, this);
// Asif: For now support Map index as non compact .expand later
// The limitation for compact range index also apply to hash index for now
isCompactOrHash = shouldCreateCompactIndex((FunctionalIndexCreationHelper) helper);
} else if (indexType == IndexType.PRIMARY_KEY) {
helper = new PrimaryKeyIndexCreationHelper(origFromClause, origIndexedExpression, projectionAttributes, (InternalCache) region.getCache(), externalContext, this);
} else {
throw new AssertionError("Don't know how to set helper for " + indexType);
}
if (!isCompactOrHash && indexType != IndexType.PRIMARY_KEY) {
if (indexType == IndexType.HASH) {
if (!isIndexMaintenanceTypeSynchronous()) {
throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_HASH_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_ASYNC_MAINTENANCE.toLocalizedString());
}
throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_HASH_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_MULTIPLE_ITERATORS.toLocalizedString());
}
// Overflow is not supported with range index.
if (isOverFlowRegion()) {
throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_REGIONS_WHICH_OVERFLOW_TO_DISK_THE_REGION_INVOLVED_IS_0.toLocalizedString(region.getFullPath()));
}
// OffHeap is not supported with range index.
if (isOffHeap()) {
if (!isIndexMaintenanceTypeSynchronous()) {
throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_OFF_HEAP_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_ASYNC_MAINTENANCE_THE_REGION_IS_0.toLocalizedString(region.getFullPath()));
}
throw new UnsupportedOperationException(LocalizedStrings.DefaultQueryService_OFF_HEAP_INDEX_CREATION_IS_NOT_SUPPORTED_FOR_MULTIPLE_ITERATORS_THE_REGION_IS_0.toLocalizedString(region.getFullPath()));
}
}
if (logger.isDebugEnabled()) {
logger.debug("Started creating index with indexName: {} On region: {}", indexName, region.getFullPath());
}
if (IndexManager.testHook != null) {
if (logger.isDebugEnabled()) {
logger.debug("IndexManager TestHook is set.");
}
if (((LocalRegion) this.region).isInitialized()) {
testHook.hook(1);
} else {
testHook.hook(0);
}
}
IndexTask indexTask = new IndexTask(indexName, indexType, origFromClause, origIndexedExpression, helper, isCompactOrHash, prIndex, loadEntries);
FutureTask<Index> indexFutureTask = new FutureTask<Index>(indexTask);
Object oldIndex = this.indexes.putIfAbsent(indexTask, indexFutureTask);
Index index = null;
boolean interrupted = false;
try {
if (oldIndex == null) {
// Initialize index.
indexFutureTask.run();
// Set the index.
index = (Index) indexFutureTask.get();
} else {
// Check if index creation is complete.
if (!(oldIndex instanceof Index)) {
// Some other thread is creating the same index.
// Wait for index to be initialized from other thread.
((Future) oldIndex).get();
}
// from this thread.
if (getIndex(indexName) != null) {
throw new IndexNameConflictException(LocalizedStrings.IndexManager_INDEX_NAMED_0_ALREADY_EXISTS.toLocalizedString(indexName));
} else {
throw new IndexExistsException(LocalizedStrings.IndexManager_SIMILAR_INDEX_EXISTS.toLocalizedString());
}
}
} catch (InterruptedException ignored) {
interrupted = true;
} catch (ExecutionException ee) {
Throwable c = ee.getCause();
if (c instanceof IndexNameConflictException) {
throw (IndexNameConflictException) c;
} else if (c instanceof IndexExistsException) {
throw (IndexExistsException) c;
} else if (c instanceof IMQException) {
throw new IndexInvalidException(c.getMessage());
}
throw new IndexInvalidException(ee);
} finally {
// the map.
if (oldIndex == null && index == null) {
Object ind = this.indexes.get(indexTask);
if (ind != null && !(ind instanceof Index)) {
this.indexes.remove(indexTask);
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
}
assert (index != null);
if (logger.isDebugEnabled()) {
logger.debug("Completed creating index with indexName: {} On region: {}", indexName, region.getFullPath());
}
return index;
} finally {
DefaultQuery.setPdxReadSerialized(this.region.getCache(), oldReadSerialized);
if (tx != null) {
((TXManagerImpl) this.region.getCache().getCacheTransactionManager()).internalResume(tx);
}
}
}
use of java.util.concurrent.FutureTask in project geode by apache.
the class IndexManager method recreateAllIndexesForRegion.
/**
* Recreates all indexes for this region. This operation blocks all updates on all indexes while
* recreate is in progress. This is required as recreate does NOT lock region entries before index
* update and hence might cause inconsistencies in index if concurrent region entry operations are
* going on.
*
*/
private void recreateAllIndexesForRegion() {
long start = 0;
waitBeforeUpdate();
try {
// opCode is ignored for this operation
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 (index.getType() == IndexType.FUNCTIONAL || index.getType() == IndexType.HASH) {
AbstractIndex aIndex = ((AbstractIndex) index);
start = ((AbstractIndex) index).updateIndexUpdateStats();
((AbstractIndex) index).recreateIndexData();
((AbstractIndex) index).updateIndexUpdateStats(start);
}
}
} catch (Exception e) {
throw new IndexInvalidException(e);
} finally {
notifyAfterUpdate();
}
}
use of java.util.concurrent.FutureTask in project geode by apache.
the class IndexManager method getBestMatchIndex.
/**
* Asif : Returns the best available Index based on the available iterators in the Group
*
* TODO: Asif :Check if synchronization is needed while obtaining Array of Indexes as similar to
* what we have used during index updates
*
* @param indexType Primary or Range Index
* @param definitions String array containing the canonicalized definitions of the Iterators of
* the Group
* @param indexedExpression Index Expression path(CompiledValue) on which index needs to be
* created
* @param context ExecutionContext object
* @return IndexData object
*/
public IndexData getBestMatchIndex(IndexType indexType, String[] definitions, CompiledValue indexedExpression, ExecutionContext context) throws AmbiguousNameException, TypeMismatchException, NameResolutionException {
Index bestIndex = null;
Index bestPRIndex = null;
int[] bestMapping = null;
int qItrSize = definitions.length;
int bestIndexMatchLevel = qItrSize;
Iterator iter = this.indexes.values().iterator();
StringBuilder sb = new StringBuilder();
indexedExpression.generateCanonicalizedExpression(sb, context);
String indexExprStr = sb.toString();
PartitionedIndex prIndex = null;
Index prevBestPRIndex = null;
Index prevBestIndex = null;
Index index;
while (iter.hasNext()) {
Object ind = iter.next();
// the index is in create phase.
if (ind instanceof FutureTask) {
continue;
}
// If the index is still empty
if (!((AbstractIndex) ind).isPopulated()) {
continue;
}
index = (Index) ind;
if (index instanceof PartitionedIndex) {
prIndex = (PartitionedIndex) index;
// Get one of the bucket index. This index will be
// available on all the buckets.
index = prIndex.getBucketIndex();
if (index == null) {
continue;
}
}
// Use simple strategy just pick first compatible index
if (((IndexProtocol) index).isMatchingWithIndexExpression(indexedExpression, indexExprStr, context) && index.getType() == indexType) {
// For PR the matched index needs to be available on all the query buckets.
if (prIndex != null) {
try {
// Protect the PartitionedIndex from being removed when it is being used.
if (!prIndex.acquireIndexReadLockForRemove()) {
continue;
}
prIndex.verifyAndCreateMissingIndex(context.getBucketList());
} catch (Exception ignored) {
// Index is not there on all buckets.
// ignore this index.
prIndex.releaseIndexReadLockForRemove();
prIndex = null;
continue;
}
} else {
// For index on replicated regions
if (!((AbstractIndex) index).acquireIndexReadLockForRemove()) {
continue;
}
}
/*
* Asif : A match level of zero means exact match. A match level greater than 0 means the
* query from clauses have extra iterators as compared to Index resultset ( This does not
* neccessarily mean that Index resultset is not having extra fields. It is just that the
* criteria for match level is the absence or presence of extra iterators. The order of
* preference will be 0 , <0 , > 0 for first cut.
*/
String[] indexDefinitions = ((IndexProtocol) index).getCanonicalizedIteratorDefinitions();
int[] mapping = new int[qItrSize];
int matchLevel = getMatchLevel(definitions, indexDefinitions, mapping);
if (matchLevel == 0) {
prevBestPRIndex = bestPRIndex;
bestPRIndex = prIndex;
prevBestIndex = bestIndex;
bestIndex = index;
bestIndexMatchLevel = matchLevel;
bestMapping = mapping;
// chosen as bestIndex.
if (prIndex != null && prevBestPRIndex != null && prevBestPRIndex instanceof PartitionedIndex) {
((PartitionedIndex) prevBestPRIndex).releaseIndexReadLockForRemove();
prevBestPRIndex = null;
} else if (prevBestIndex != null) {
((AbstractIndex) prevBestIndex).releaseIndexReadLockForRemove();
prevBestIndex = null;
}
break;
} else if ((bestIndexMatchLevel > 0 && matchLevel < bestIndexMatchLevel) || (bestIndexMatchLevel < 0 && matchLevel < 0 && matchLevel > bestIndexMatchLevel)) {
prevBestPRIndex = bestPRIndex;
bestPRIndex = prIndex;
prevBestIndex = bestIndex;
bestIndex = index;
bestIndexMatchLevel = matchLevel;
bestMapping = mapping;
}
// release the lock if this index is not chosen as bestIndex.
if (prIndex != null && bestPRIndex != prIndex) {
prIndex.releaseIndexReadLockForRemove();
prIndex = null;
} else if (bestIndex != index) {
((AbstractIndex) index).releaseIndexReadLockForRemove();
index = null;
}
// chosen as bestIndex.
if (prevBestPRIndex != null && prevBestPRIndex instanceof PartitionedIndex) {
((PartitionedIndex) prevBestPRIndex).releaseIndexReadLockForRemove();
prevBestPRIndex = null;
} else if (prevBestIndex != null) {
((AbstractIndex) prevBestIndex).releaseIndexReadLockForRemove();
prevBestIndex = null;
}
}
}
if (bestIndex != null) {
if (logger.isDebugEnabled()) {
logger.debug("The best index found for index expression: {} is: {} with Match-level: {} and mapping: {}", indexExprStr, bestIndex, bestIndexMatchLevel, Arrays.toString(bestMapping));
}
}
return bestIndex != null ? new IndexData((IndexProtocol) bestIndex, bestIndexMatchLevel, bestMapping) : null;
}
use of java.util.concurrent.FutureTask in project geode by apache.
the class PartitionedRegion method createIndex.
public Index createIndex(boolean remotelyOriginated, IndexType indexType, String indexName, String indexedExpression, String fromClause, String imports, boolean loadEntries, boolean sendMessage) throws ForceReattemptException, IndexCreationException, IndexNameConflictException, IndexExistsException {
// Check if its remote request and this vm is an accessor.
if (remotelyOriginated && dataStore == null) {
// data store where as it should have.
if (getLocalMaxMemory() != 0) {
throw new IndexCreationException(LocalizedStrings.PartitionedRegion_DATA_STORE_ON_THIS_VM_IS_NULL_AND_THE_LOCAL_MAX_MEMORY_IS_NOT_ZERO_THE_DATA_POLICY_IS_0_AND_THE_LOCALMAXMEMEORY_IS_1.toLocalizedString(getDataPolicy(), (long) getLocalMaxMemory()));
}
// Not have to do anything since the region is just an Accessor and
// does not store any data.
logger.info(LocalizedMessage.create(LocalizedStrings.PartitionedRegion_THIS_IS_AN_ACCESSOR_VM_AND_DOESNT_CONTAIN_DATA));
return null;
}
// Create indexManager.
if (this.indexManager == null) {
this.indexManager = IndexUtils.getIndexManager(this, true);
}
if (logger.isDebugEnabled()) {
logger.debug("Started creating index with Index Name :{} On PartitionedRegion {}, Indexfrom caluse={}, Remote Request: {}", indexName, this.getFullPath(), fromClause, remotelyOriginated);
}
IndexTask indexTask = new IndexTask(remotelyOriginated, indexType, indexName, indexedExpression, fromClause, imports, loadEntries);
FutureTask<Index> indexFutureTask = new FutureTask<Index>(indexTask);
// This will return either the Index FutureTask or Index itself, based
// on whether the index creation is in process or completed.
Object ind = this.indexes.putIfAbsent(indexTask, indexFutureTask);
// Check if its instance of Index, in that the case throw index exists exception.
if (ind instanceof Index) {
if (remotelyOriginated) {
return (Index) ind;
}
throw new IndexNameConflictException(LocalizedStrings.IndexManager_INDEX_NAMED_0_ALREADY_EXISTS.toLocalizedString(indexName));
}
FutureTask<Index> oldIndexFutureTask = (FutureTask<Index>) ind;
Index index = null;
boolean interrupted = false;
try {
if (oldIndexFutureTask == null) {
// Index doesn't exist, create index.
indexFutureTask.run();
index = indexFutureTask.get();
if (index != null) {
this.indexes.put(indexTask, index);
PartitionedIndex prIndex = (PartitionedIndex) index;
indexManager.addIndex(indexName, index);
// Send create request to other PR nodes.
if (!remotelyOriginated && sendMessage) {
logger.info(LocalizedMessage.create(LocalizedStrings.PartitionedRegion_CREATED_INDEX_LOCALLY_SENDING_INDEX_CREATION_MESSAGE_TO_ALL_MEMBERS_AND_WILL_BE_WAITING_FOR_RESPONSE_0, prIndex));
HashSet<IndexCreationData> singleIndexDefinition = new HashSet<IndexCreationData>();
IndexCreationData icd = new IndexCreationData(indexName);
icd.setIndexData(indexType, fromClause, indexedExpression, imports, loadEntries);
singleIndexDefinition.add(icd);
IndexCreationMsg.IndexCreationResponse response = null;
try {
response = (IndexCreationMsg.IndexCreationResponse) IndexCreationMsg.send(null, PartitionedRegion.this, singleIndexDefinition);
if (response != null) {
IndexCreationMsg.IndexCreationResult result = response.waitForResult();
Map<String, Integer> indexBucketsMap = result.getIndexBucketsMap();
if (indexBucketsMap != null && indexBucketsMap.size() > 0) {
prIndex.setRemoteBucketesIndexed(indexBucketsMap.values().iterator().next());
}
}
} catch (UnsupportedOperationException ignore) {
// if remote nodes are of older versions indexes will not be created there, so remove
// index on this node as well.
this.indexes.remove(index);
indexManager.removeIndex(index);
throw new IndexCreationException(LocalizedStrings.PartitionedRegion_INDEX_CREATION_FAILED_ROLLING_UPGRADE.toLocalizedString());
}
}
}
} else {
// Some other thread is trying to create the same index.
// Wait for index to be initialized from other thread.
index = oldIndexFutureTask.get();
if (remotelyOriginated) {
return index;
}
throw new IndexNameConflictException(LocalizedStrings.IndexManager_INDEX_NAMED_0_ALREADY_EXISTS.toLocalizedString(indexName));
}
} catch (InterruptedException ignore) {
interrupted = true;
} catch (ExecutionException ee) {
if (!remotelyOriginated) {
Throwable cause = ee.getCause();
if (cause instanceof IndexNameConflictException) {
throw (IndexNameConflictException) cause;
} else if (cause instanceof IndexExistsException) {
throw (IndexExistsException) cause;
}
throw new IndexInvalidException(ee);
}
} finally {
// If the index is not successfully created, remove IndexTask from the map.
if (index == null) {
ind = this.indexes.get(indexTask);
if (index != null && !(index instanceof Index)) {
this.indexes.remove(indexTask);
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
}
if (logger.isDebugEnabled()) {
logger.debug("Completed creating index with Index Name :{} On PartitionedRegion {}, Remote Request: {}", indexName, this.getFullPath(), remotelyOriginated);
}
return index;
}
use of java.util.concurrent.FutureTask in project jackrabbit-oak by apache.
the class SegmentReferenceLimitTestIT method corruption.
@Test
public void corruption() throws Exception {
FileStore fileStore = fileStoreBuilder(getFileStoreFolder()).withMaxFileSize(1).withSegmentCacheSize(0).withStringCacheSize(0).withTemplateCacheSize(0).withNodeDeduplicationCacheSize(1).withStringDeduplicationCacheSize(0).withTemplateDeduplicationCacheSize(0).withMemoryMapping(true).build();
SegmentNodeStore nodeStore = SegmentNodeStoreBuilders.builder(fileStore).build();
NodeBuilder root = nodeStore.getRoot().builder();
root.setChildNode("test");
nodeStore.merge(root, EmptyHook.INSTANCE, CommitInfo.EMPTY);
List<FutureTask<Void>> l = new ArrayList<FutureTask<Void>>();
for (int i = 0; i < 10; i++) {
l.add(run(new Worker(nodeStore, "w" + i)));
}
try {
for (FutureTask<Void> w : l) {
w.get();
}
} finally {
fileStore.close();
}
}
Aggregations