use of org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry in project geode by apache.
the class CompactRangeIndex method addToResultsFromEntries.
/*
*
* @param lowerBoundKey the index key to match on for a lower bound on a ranged query, otherwise
* the key to match on
*
* @param upperBoundKey the index key to match on for an upper bound on a ranged query, otherwise
* null
*
* @param lowerBoundOperator the operator to use to determine a match against the lower bound
*
* @param upperBoundOperator the operator to use to determine a match against the upper bound
*/
private void addToResultsFromEntries(Object lowerBoundKey, Object upperBoundKey, int lowerBoundOperator, int upperBoundOperator, CloseableIterator<IndexStoreEntry> entriesIter, Collection result, CompiledValue iterOps, RuntimeIterator runtimeItr, ExecutionContext context, List projAttrib, SelectResults intermediateResults, boolean isIntersection, int limit) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
QueryObserver observer = QueryObserverHolder.getInstance();
boolean limitApplied = false;
if (entriesIter == null || (limitApplied = verifyLimit(result, limit))) {
if (limitApplied) {
if (observer != null) {
observer.limitAppliedAtIndexLevel(this, limit, result);
}
}
return;
}
Set seenKey = null;
if (IndexManager.IS_TEST_EXPANSION) {
seenKey = new HashSet();
}
while (entriesIter.hasNext()) {
try {
// Check if query execution on this thread is canceled.
QueryMonitor.isQueryExecutionCanceled();
if (IndexManager.testHook != null) {
if (this.region.getCache().getLogger().fineEnabled()) {
this.region.getCache().getLogger().fine("IndexManager TestHook is set in addToResultsFromEntries.");
}
IndexManager.testHook.hook(11);
}
IndexStoreEntry indexEntry = null;
try {
indexEntry = entriesIter.next();
} catch (NoSuchElementException ignore) {
// Continue from while.
continue;
}
Object value = indexEntry.getDeserializedValue();
if (IndexManager.IS_TEST_EXPANSION) {
Object rk = indexEntry.getDeserializedRegionKey();
if (seenKey.contains(rk)) {
continue;
}
seenKey.add(rk);
List expandedResults = expandValue(context, lowerBoundKey, upperBoundKey, lowerBoundOperator, upperBoundOperator, value);
Iterator iterator = ((Collection) expandedResults).iterator();
while (iterator.hasNext()) {
value = iterator.next();
if (value != null) {
boolean ok = true;
if (runtimeItr != null) {
runtimeItr.setCurrent(value);
}
if (ok && runtimeItr != null && iterOps != null) {
ok = QueryUtils.applyCondition(iterOps, context);
}
if (ok) {
if (context != null && context.isCqQueryContext()) {
result.add(new CqEntry(indexEntry.getDeserializedRegionKey(), value));
} else {
applyProjection(projAttrib, context, result, value, intermediateResults, isIntersection);
}
if (verifyLimit(result, limit)) {
observer.limitAppliedAtIndexLevel(this, limit, result);
return;
}
}
}
}
} else {
if (value != null) {
boolean ok = true;
if (indexEntry.isUpdateInProgress() || TEST_ALWAYS_UPDATE_IN_PROGRESS) {
IndexInfo indexInfo = (IndexInfo) context.cacheGet(CompiledValue.INDEX_INFO);
if (runtimeItr == null) {
runtimeItr = getRuntimeIteratorForThisIndex(context, indexInfo);
if (runtimeItr == null) {
// could not match index with iterator
throw new QueryInvocationTargetException("Query alias's must be used consistently");
}
}
runtimeItr.setCurrent(value);
// Verify index key in region entry value.
ok = evaluateEntry((IndexInfo) indexInfo, context, null);
}
if (runtimeItr != null) {
runtimeItr.setCurrent(value);
}
if (ok && runtimeItr != null && iterOps != null) {
ok = QueryUtils.applyCondition(iterOps, context);
}
if (ok) {
if (context != null && context.isCqQueryContext()) {
result.add(new CqEntry(indexEntry.getDeserializedRegionKey(), value));
} else {
if (IndexManager.testHook != null) {
IndexManager.testHook.hook(200);
}
applyProjection(projAttrib, context, result, value, intermediateResults, isIntersection);
}
if (verifyLimit(result, limit)) {
observer.limitAppliedAtIndexLevel(this, limit, result);
return;
}
}
}
}
} catch (ClassCastException | EntryDestroyedException ignore) {
// ignore it
}
}
}
use of org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry in project geode by apache.
the class AbstractIndex method populateListForEquiJoin.
/**
* This will populate resultSet from both type of indexes, {@link CompactRangeIndex} and
* {@link RangeIndex}.
*/
void populateListForEquiJoin(List list, Object outerEntries, Object innerEntries, ExecutionContext context, Object key) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
Assert.assertTrue(outerEntries != null && innerEntries != null, "OuterEntries or InnerEntries must not be null");
Object[][] values = new Object[2][];
Iterator itr = null;
int j = 0;
while (j < 2) {
boolean isRangeIndex = false;
if (j == 0) {
if (outerEntries instanceof RegionEntryToValuesMap) {
itr = ((RegionEntryToValuesMap) outerEntries).map.entrySet().iterator();
isRangeIndex = true;
} else if (outerEntries instanceof CloseableIterator) {
itr = (Iterator) outerEntries;
}
} else {
if (innerEntries instanceof RegionEntryToValuesMap) {
itr = ((RegionEntryToValuesMap) innerEntries).map.entrySet().iterator();
isRangeIndex = true;
} else if (innerEntries instanceof CloseableIterator) {
itr = (Iterator) innerEntries;
}
}
// extract the values from the RegionEntries
List dummy = new ArrayList();
RegionEntry re = null;
IndexStoreEntry ie = null;
Object val = null;
Object entryVal = null;
IndexInfo[] indexInfo = (IndexInfo[]) context.cacheGet(CompiledValue.INDEX_INFO);
IndexInfo indInfo = indexInfo[j];
while (itr.hasNext()) {
if (isRangeIndex) {
Map.Entry entry = (Map.Entry) itr.next();
val = entry.getValue();
if (val instanceof Collection) {
entryVal = ((Iterable) val).iterator().next();
} else {
entryVal = val;
}
re = (RegionEntry) entry.getKey();
} else {
ie = (IndexStoreEntry) itr.next();
}
// Bug#41010: We need to verify if Inner and Outer Entries
// are consistent with index key values.
boolean ok = true;
if (isRangeIndex) {
if (re.isUpdateInProgress()) {
ok = ((RangeIndex) indInfo._getIndex()).verifyEntryAndIndexValue(re, entryVal, context);
}
} else if (ie.isUpdateInProgress()) {
ok = ((CompactRangeIndex) indInfo._getIndex()).verifyInnerAndOuterEntryValues(ie, context, indInfo, key);
}
if (ok) {
if (isRangeIndex) {
if (val instanceof Collection) {
dummy.addAll((Collection) val);
} else {
dummy.add(val);
}
} else {
if (IndexManager.IS_TEST_EXPANSION) {
dummy.addAll(((CompactRangeIndex) indInfo._getIndex()).expandValue(context, key, null, OQLLexerTokenTypes.TOK_EQ, -1, ie.getDeserializedValue()));
} else {
dummy.add(ie.getDeserializedValue());
}
}
}
}
Object[] newValues = new Object[dummy.size()];
dummy.toArray(newValues);
values[j++] = newValues;
}
list.add(values);
}
use of org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry in project geode by apache.
the class CompactRangeIndex method evaluate.
private void evaluate(Object key, int operator, Collection results, CompiledValue iterOps, RuntimeIterator runtimeItr, ExecutionContext context, Set keysToRemove, List projAttrib, SelectResults intermediateResults, boolean isIntersection, int limit, boolean applyOrderBy, List orderByAttribs) throws TypeMismatchException, FunctionDomainException, NameResolutionException, QueryInvocationTargetException {
boolean multiColOrderBy = false;
if (keysToRemove == null) {
keysToRemove = new HashSet(0);
}
key = TypeUtils.indexKeyFor(key);
if (key == null) {
key = IndexManager.NULL;
}
boolean asc = true;
if (applyOrderBy) {
CompiledSortCriterion csc = (CompiledSortCriterion) orderByAttribs.get(0);
asc = !csc.getCriterion();
multiColOrderBy = orderByAttribs.size() > 1;
}
CloseableIterator<IndexStoreEntry> iterator = null;
try {
switch(operator) {
case OQLLexerTokenTypes.TOK_EQ:
assert keysToRemove.isEmpty();
iterator = indexStore.get(key);
addToResultsFromEntries(key, operator, iterator, results, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, multiColOrderBy ? -1 : limit);
break;
case OQLLexerTokenTypes.TOK_LT:
{
if (asc) {
iterator = indexStore.iterator(null, true, key, false, keysToRemove);
} else {
iterator = indexStore.descendingIterator(null, true, key, false, keysToRemove);
}
addToResultsFromEntries(key, operator, iterator, results, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, multiColOrderBy ? -1 : limit);
}
break;
case OQLLexerTokenTypes.TOK_LE:
{
if (asc) {
iterator = indexStore.iterator(null, true, key, true, keysToRemove);
} else {
iterator = indexStore.descendingIterator(null, true, key, true, keysToRemove);
}
addToResultsFromEntries(key, operator, iterator, results, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, multiColOrderBy ? -1 : limit);
}
break;
case OQLLexerTokenTypes.TOK_GT:
{
if (asc) {
iterator = indexStore.iterator(key, false, keysToRemove);
} else {
iterator = indexStore.descendingIterator(key, false, keysToRemove);
}
addToResultsFromEntries(key, operator, iterator, results, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, multiColOrderBy ? -1 : limit);
}
break;
case OQLLexerTokenTypes.TOK_GE:
{
if (asc) {
iterator = indexStore.iterator(key, true, keysToRemove);
} else {
iterator = indexStore.descendingIterator(key, true, keysToRemove);
}
addToResultsFromEntries(key, operator, iterator, results, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, multiColOrderBy ? -1 : limit);
}
break;
case OQLLexerTokenTypes.TOK_NE_ALT:
case OQLLexerTokenTypes.TOK_NE:
{
keysToRemove.add(key);
if (asc) {
iterator = indexStore.iterator(keysToRemove);
} else {
iterator = indexStore.descendingIterator(keysToRemove);
}
addToResultsFromEntries(key, operator, iterator, results, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, multiColOrderBy ? -1 : limit);
// If the key is not null, then add the nulls to the results as this is a not equals query
if (!IndexManager.NULL.equals(key)) {
// we pass in the operator TOK_EQ because we want to add results where the key is equal
// to NULL
addToResultsFromEntries(IndexManager.NULL, OQLLexerTokenTypes.TOK_EQ, indexStore.get(IndexManager.NULL), results, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, multiColOrderBy ? -1 : limit);
}
// equals query
if (!QueryService.UNDEFINED.equals(key)) {
// we pass in the operator TOK_EQ because we want to add results where the key is equal
// to UNDEFINED
addToResultsFromEntries(QueryService.UNDEFINED, OQLLexerTokenTypes.TOK_EQ, indexStore.get(QueryService.UNDEFINED), results, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, multiColOrderBy ? -1 : limit);
}
}
break;
default:
throw new AssertionError("Operator = " + operator);
}
// end switch
} catch (ClassCastException ex) {
if (operator == OQLLexerTokenTypes.TOK_EQ) {
// result is empty set
return;
} else if (operator == OQLLexerTokenTypes.TOK_NE || operator == OQLLexerTokenTypes.TOK_NE_ALT) {
// put all in result
keysToRemove.add(key);
try {
if (asc) {
iterator = indexStore.iterator(keysToRemove);
} else {
iterator = indexStore.descendingIterator(keysToRemove);
}
addToResultsFromEntries(key, OQLLexerTokenTypes.TOK_NE, iterator, results, iterOps, runtimeItr, context, projAttrib, intermediateResults, isIntersection, multiColOrderBy ? -1 : limit);
} finally {
if (iterator != null) {
iterator.close();
}
}
} else {
// otherwise throw exception
throw new TypeMismatchException("", ex);
}
} finally {
if (iterator != null) {
iterator.close();
}
}
}
use of org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry in project geode by apache.
the class CompactRangeIndex method lockedQuery.
/** Method called while appropriate lock held on index */
void lockedQuery(Object lowerBoundKey, int lowerBoundOperator, Object upperBoundKey, int upperBoundOperator, Collection results, Set keysToRemove, ExecutionContext context) throws TypeMismatchException, FunctionDomainException, NameResolutionException, QueryInvocationTargetException {
lowerBoundKey = TypeUtils.indexKeyFor(lowerBoundKey);
upperBoundKey = TypeUtils.indexKeyFor(upperBoundKey);
boolean lowerBoundInclusive = lowerBoundOperator == OQLLexerTokenTypes.TOK_GE;
boolean upperBoundInclusive = upperBoundOperator == OQLLexerTokenTypes.TOK_LE;
// LowerBound Key inclusive , Upper bound key exclusive
int limit = -1;
Boolean applyLimit = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_LIMIT_AT_INDEX);
if (applyLimit != null && applyLimit) {
limit = (Integer) context.cacheGet(CompiledValue.RESULT_LIMIT);
}
Boolean orderByClause = (Boolean) context.cacheGet(CompiledValue.CAN_APPLY_ORDER_BY_AT_INDEX);
List orderByAttrs;
boolean asc = true;
boolean multiColOrderBy = false;
if (orderByClause != null && orderByClause) {
orderByAttrs = (List) context.cacheGet(CompiledValue.ORDERBY_ATTRIB);
CompiledSortCriterion csc = (CompiledSortCriterion) orderByAttrs.get(0);
asc = !csc.getCriterion();
multiColOrderBy = orderByAttrs.size() > 1;
}
// return if the index map is still empty at this stage
if (isEmpty()) {
return;
}
lowerBoundKey = getPdxStringForIndexedPdxKeys(lowerBoundKey);
upperBoundKey = getPdxStringForIndexedPdxKeys(upperBoundKey);
if (keysToRemove == null) {
keysToRemove = new HashSet();
}
CloseableIterator<IndexStoreEntry> iterator = null;
try {
if (asc) {
iterator = indexStore.iterator(lowerBoundKey, lowerBoundInclusive, upperBoundKey, upperBoundInclusive, keysToRemove);
} else {
iterator = indexStore.descendingIterator(lowerBoundKey, lowerBoundInclusive, upperBoundKey, upperBoundInclusive, keysToRemove);
}
addToResultsFromEntries(lowerBoundKey, upperBoundKey, lowerBoundOperator, upperBoundOperator, iterator, results, null, null, context, null, null, true, multiColOrderBy ? -1 : limit);
} finally {
if (iterator != null) {
iterator.close();
}
}
}
use of org.apache.geode.cache.query.internal.index.IndexStore.IndexStoreEntry in project geode by apache.
the class CompactRangeIndex method queryEquijoinCondition.
public List queryEquijoinCondition(IndexProtocol indx, ExecutionContext context) throws TypeMismatchException, FunctionDomainException, NameResolutionException, QueryInvocationTargetException {
// get a read lock when doing a lookup
long start = updateIndexUseStats();
((AbstractIndex) indx).updateIndexUseStats();
List data = new ArrayList();
CloseableIterator<IndexStoreEntry> outer = null;
Iterator inner = null;
try {
// We will iterate over each of the index Map to obtain the keys
outer = indexStore.iterator(null);
if (indx instanceof CompactRangeIndex) {
inner = ((CompactRangeIndex) indx).getIndexStorage().iterator(null);
} else {
inner = ((RangeIndex) indx).getValueToEntriesMap().entrySet().iterator();
}
IndexStoreEntry outerEntry = null;
Object innerEntry = null;
Object outerKey = null;
Object innerKey = null;
boolean incrementInner = true;
outer: while (outer.hasNext()) {
outerEntry = outer.next();
outerKey = outerEntry.getDeserializedKey();
// TODO: eliminate all labels
inner: while (!incrementInner || inner.hasNext()) {
if (incrementInner) {
innerEntry = inner.next();
if (innerEntry instanceof IndexStoreEntry) {
innerKey = ((IndexStoreEntry) innerEntry).getDeserializedKey();
} else {
innerKey = ((Map.Entry) innerEntry).getKey();
}
}
int compare = ((Comparable) outerKey).compareTo(innerKey);
if (compare == 0) {
Object innerValue = null;
CloseableIterator<IndexStoreEntry> iter = null;
try {
if (innerEntry instanceof IndexStoreEntry) {
innerValue = ((CompactRangeIndex) indx).getIndexStorage().get(outerKey);
} else {
innerValue = ((Map.Entry) innerEntry).getValue();
}
iter = indexStore.get(outerKey);
populateListForEquiJoin(data, iter, innerValue, context, innerKey);
} finally {
if (iter != null) {
iter.close();
}
if (innerValue != null && innerValue instanceof CloseableIterator) {
((CloseableIterator<IndexStoreEntry>) innerValue).close();
}
}
incrementInner = true;
continue outer;
} else if (compare < 0) {
// The outer key is smaller than the inner key. That means
// that we need
// to increment the outer loop without moving inner loop.
// incrementOuter = true;
incrementInner = false;
continue outer;
} else {
// The outer key is greater than inner key , so increment the
// inner loop without changing outer
incrementInner = true;
}
}
break;
}
return data;
} finally {
((AbstractIndex) indx).updateIndexUseEndStats(start);
updateIndexUseEndStats(start);
if (outer != null) {
outer.close();
}
if (inner != null && indx instanceof CompactRangeIndex) {
((CloseableIterator<IndexStoreEntry>) inner).close();
}
}
}
Aggregations