* @return events
*/
public Collection<EventBean> snapshot(FilterSpecCompiled optionalFilter, Annotation[] annotations) {
// Determine virtual data window
VirtualDWView virtualDataWindow = null;
if (isVirtualDataWindow()) {
virtualDataWindow = getVirtualDataWindow();
}
if (optionalFilter == null || optionalFilter.getParameters().isEmpty()) {
if (virtualDataWindow != null) {
Pair<IndexMultiKey,EventTable> pair = virtualDataWindow.getFireAndForgetDesc(Collections.<String>emptySet(), Collections.<String>emptySet());
return virtualDataWindow.getFireAndForgetData(pair.getSecond(), new Object[0], new RangeIndexLookupValue[0], annotations);
}
return null;
}
// Determine what straight-equals keys and which ranges are available.
// Widening/Coercion is part of filter spec compile.
Set<String> keysAvailable = new HashSet<String>();
Set<String> rangesAvailable = new HashSet<String>();
for (FilterSpecParam param : optionalFilter.getParameters()) {
if (!(param instanceof FilterSpecParamConstant || param instanceof FilterSpecParamRange)) {
continue;
}
if (param.getFilterOperator() == FilterOperator.EQUAL || param.getFilterOperator() == FilterOperator.IS) {
keysAvailable.add(param.getLookupable().getExpression());
}
else if (param.getFilterOperator().isRangeOperator() ||
param.getFilterOperator().isInvertedRangeOperator() ||
param.getFilterOperator().isComparisonOperator()) {
rangesAvailable.add(param.getLookupable().getExpression());
}
else if (param.getFilterOperator().isRangeOperator()) {
rangesAvailable.add(param.getLookupable().getExpression());
}
}
// Find an index that matches the needs
Pair<IndexMultiKey, EventTable> tablePair;
if (virtualDataWindow != null) {
tablePair = virtualDataWindow.getFireAndForgetDesc(keysAvailable, rangesAvailable);
}
else {
tablePair = indexRepository.findTable(keysAvailable, rangesAvailable, explicitIndexes);
}
if (tablePair == null) {
if (rootView.isQueryPlanLogging() && rootView.getQueryPlanLog().isInfoEnabled()) {
rootView.getQueryPlanLog().info("no index found");
}
return null; // indicates table scan
}
// Compile key index lookup values
String[] keyIndexProps = IndexedPropDesc.getIndexProperties(tablePair.getFirst().getHashIndexedProps());
Object[] keyValues = new Object[keyIndexProps.length];
for (int keyIndex = 0; keyIndex < keyIndexProps.length; keyIndex++) {
for (FilterSpecParam param : optionalFilter.getParameters()) {
if (param.getLookupable().getExpression().equals(keyIndexProps[keyIndex])) {
keyValues[keyIndex] = param.getFilterValue(null, agentInstanceContext);
break;
}
}
}
// Analyze ranges - these may include key lookup value (EQUALS semantics)
String[] rangeIndexProps = IndexedPropDesc.getIndexProperties(tablePair.getFirst().getRangeIndexedProps());
RangeIndexLookupValue[] rangeValues;
if (rangeIndexProps.length > 0) {
rangeValues = compileRangeLookupValues(rangeIndexProps, optionalFilter.getParameters());
}
else {
rangeValues = new RangeIndexLookupValue[0];
}
if (virtualDataWindow != null) {
return virtualDataWindow.getFireAndForgetData(tablePair.getSecond(), keyValues, rangeValues, annotations);
}
IndexMultiKey indexMultiKey = tablePair.getFirst();
Set<EventBean> result;
if (indexMultiKey.getHashIndexedProps().length > 0 && indexMultiKey.getRangeIndexedProps().length == 0) {