use of com.orientechnologies.common.concur.resource.OSharedResource in project orientdb by orientechnologies.
the class OCommandExecutorSQLSelect method searchInIndex.
private void searchInIndex() {
final OIndex<Object> index = (OIndex<Object>) getDatabase().getMetadata().getIndexManager().getIndex(parsedTarget.getTargetIndex());
if (index == null) {
throw new OCommandExecutionException("Target index '" + parsedTarget.getTargetIndex() + "' not found");
}
boolean ascOrder = true;
if (!orderedFields.isEmpty()) {
if (orderedFields.size() != 1) {
throw new OCommandExecutionException("Index can be ordered only by key field");
}
final String fieldName = orderedFields.get(0).getKey();
if (!fieldName.equalsIgnoreCase("key")) {
throw new OCommandExecutionException("Index can be ordered only by key field");
}
final String order = orderedFields.get(0).getValue();
ascOrder = order.equalsIgnoreCase(KEYWORD_ASC);
}
// nothing was added yet, so index definition for manual index was not calculated
if (index.getDefinition() == null) {
return;
}
if (compiledFilter != null && compiledFilter.getRootCondition() != null) {
if (!"KEY".equalsIgnoreCase(compiledFilter.getRootCondition().getLeft().toString())) {
throw new OCommandExecutionException("'Key' field is required for queries against indexes");
}
final OQueryOperator indexOperator = compiledFilter.getRootCondition().getOperator();
if (indexOperator instanceof OQueryOperatorBetween) {
final Object[] values = (Object[]) compiledFilter.getRootCondition().getRight();
final OIndexCursor cursor = index.iterateEntriesBetween(getIndexKey(index.getDefinition(), values[0], context), true, getIndexKey(index.getDefinition(), values[2], context), true, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorMajor) {
final Object value = compiledFilter.getRootCondition().getRight();
final OIndexCursor cursor = index.iterateEntriesMajor(getIndexKey(index.getDefinition(), value, context), false, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorMajorEquals) {
final Object value = compiledFilter.getRootCondition().getRight();
final OIndexCursor cursor = index.iterateEntriesMajor(getIndexKey(index.getDefinition(), value, context), true, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorMinor) {
final Object value = compiledFilter.getRootCondition().getRight();
OIndexCursor cursor = index.iterateEntriesMinor(getIndexKey(index.getDefinition(), value, context), false, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorMinorEquals) {
final Object value = compiledFilter.getRootCondition().getRight();
OIndexCursor cursor = index.iterateEntriesMinor(getIndexKey(index.getDefinition(), value, context), true, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorIn) {
final List<Object> origValues = (List<Object>) compiledFilter.getRootCondition().getRight();
final List<Object> values = new ArrayList<Object>(origValues.size());
for (Object val : origValues) {
if (index.getDefinition() instanceof OCompositeIndexDefinition) {
throw new OCommandExecutionException("Operator IN not supported yet.");
}
val = getIndexKey(index.getDefinition(), val, context);
values.add(val);
}
OIndexCursor cursor = index.iterateEntries(values, true);
fetchEntriesFromIndexCursor(cursor);
} else {
final Object right = compiledFilter.getRootCondition().getRight();
Object keyValue = getIndexKey(index.getDefinition(), right, context);
if (keyValue == null) {
return;
}
final Object res;
if (index.getDefinition().getParamCount() == 1) {
// CONVERT BEFORE SEARCH IF NEEDED
final OType type = index.getDefinition().getTypes()[0];
keyValue = OType.convert(keyValue, type.getDefaultJavaType());
res = index.get(keyValue);
} else {
final Object secondKey = getIndexKey(index.getDefinition(), right, context);
if (keyValue instanceof OCompositeKey && secondKey instanceof OCompositeKey && ((OCompositeKey) keyValue).getKeys().size() == index.getDefinition().getParamCount() && ((OCompositeKey) secondKey).getKeys().size() == index.getDefinition().getParamCount()) {
res = index.get(keyValue);
} else {
OIndexCursor cursor = index.iterateEntriesBetween(keyValue, true, secondKey, true, true);
fetchEntriesFromIndexCursor(cursor);
return;
}
}
if (res != null) {
if (res instanceof Collection<?>) {
// MULTI VALUES INDEX
for (final OIdentifiable r : (Collection<OIdentifiable>) res) {
final ODocument record = createIndexEntryAsDocument(keyValue, r.getIdentity());
applyGroupBy(record, context);
if (!handleResult(record, context)) // LIMIT REACHED
{
break;
}
}
} else {
// SINGLE VALUE INDEX
final ODocument record = createIndexEntryAsDocument(keyValue, ((OIdentifiable) res).getIdentity());
applyGroupBy(record, context);
handleResult(record, context);
}
}
}
} else {
if (isIndexSizeQuery()) {
getProjectionGroup(null, context).applyValue(projections.keySet().iterator().next(), index.getSize());
return;
}
if (isIndexKeySizeQuery()) {
getProjectionGroup(null, context).applyValue(projections.keySet().iterator().next(), index.getKeySize());
return;
}
final OIndexInternal<?> indexInternal = index.getInternal();
if (indexInternal instanceof OSharedResource) {
((OSharedResource) indexInternal).acquireExclusiveLock();
}
try {
// ADD ALL THE ITEMS AS RESULT
if (ascOrder) {
final OIndexCursor cursor = index.cursor();
fetchEntriesFromIndexCursor(cursor);
} else {
final OIndexCursor cursor = index.descCursor();
fetchEntriesFromIndexCursor(cursor);
}
} finally {
if (indexInternal instanceof OSharedResource) {
((OSharedResource) indexInternal).releaseExclusiveLock();
}
}
}
}
Aggregations