Skip to content

Commit

Permalink
Implement node estimation in Match statement
Browse files Browse the repository at this point in the history
  • Loading branch information
luigidellaquila committed Oct 5, 2015
1 parent e9f1315 commit 87a2bcf
Show file tree
Hide file tree
Showing 18 changed files with 451 additions and 38 deletions.
Expand Up @@ -106,5 +106,41 @@ public List<OBinaryCondition> getIndexedFunctionConditions(OClass iSchemaClass,
return result.size() == 0 ? null : result;
}

public List<OAndBlock> flatten() {
List<OAndBlock> result = new ArrayList<OAndBlock>();
boolean first = true;
for (OBooleanExpression sub : subBlocks) {
List<OAndBlock> subFlattened = sub.flatten();
List<OAndBlock> oldResult = result;
result = new ArrayList<OAndBlock>();
for (OAndBlock subAndItem : subFlattened) {
if (first) {
result.add(subAndItem);
} else {
;
for(OAndBlock oldResultItem:oldResult) {
OAndBlock block = new OAndBlock(-1);
block.subBlocks.addAll(oldResultItem.subBlocks);
for (OBooleanExpression resultItem : subAndItem.subBlocks) {
block.subBlocks.add(resultItem);
}
result.add(block);
}
}
}
first = false;
}
return result;
}

protected OAndBlock encapsulateInAndBlock(OBooleanExpression item) {
if(item instanceof OAndBlock){
return (OAndBlock)item;
}
OAndBlock result = new OAndBlock(-1);
result.subBlocks.add(item);
return result;
}

}
/* JavaCC - OriginalChecksum=cf1f66cc86cfc93d357f9fcdfa4a4604 (do not edit this line) */
Expand Up @@ -102,5 +102,16 @@ public Iterable<OIdentifiable> executeIndexedFunction(OFromClause target, OComma
return identifier.executeIndexedFunction(target, context, operator, right);
}

@Override
public boolean isBaseIdentifier() {
return identifier != null && modifier == null && identifier.isBaseIdentifier();
}

public boolean isEarlyCalculated() {
if (number != null || inputParam != null || string != null) {
return true;
}
return false;
}
}
/* JavaCC - OriginalChecksum=71b3e2d1b65c923dc7cfe11f9f449d2b (do not edit this line) */
Expand Up @@ -68,5 +68,9 @@ public Iterable<OIdentifiable> executeIndexedFunction(OFromClause target, OComma

return null;
}

public boolean isBaseIdentifier() {
return suffix!=null && suffix.isBaseIdentifier();
}
}
/* JavaCC - OriginalChecksum=ed89af10d8be41a83428c5608a4834f6 (do not edit this line) */
Expand Up @@ -111,4 +111,18 @@ public List<OBinaryCondition> getIndexedFunctionConditions(OClass iSchemaClass,
return null;
}

public List<OAndBlock> flatten() {

return Collections.singletonList(encapsulateInAndBlock(this));
}

protected OAndBlock encapsulateInAndBlock(OBooleanExpression item) {
if(item instanceof OAndBlock){
return (OAndBlock)item;
}
OAndBlock result = new OAndBlock(-1);
result.subBlocks.add(item);
return result;
}

}
Expand Up @@ -46,6 +46,32 @@ public Object execute(OIdentifiable iCurrentRecord, OCommandContext ctx) {

}

public boolean isBaseIdentifier(){
if(value instanceof OMathExpression) {
return ((OMathExpression)value).isBaseIdentifier();
}

return false;
}

public boolean isEarlyCalculated(){
if(value instanceof Number) {
return true;
}
if(value instanceof String) {
return true;
}
if(value instanceof OInputParameter) {
return true;
}

if(value instanceof OMathExpression) {
return ((OMathExpression)value).isEarlyCalculated();
}

return false;
}

public String getDefaultAlias() {

if (value instanceof String) {
Expand Down
Expand Up @@ -20,5 +20,12 @@ public Object jjtAccept(OrientSqlVisitor visitor, Object data) {
protected boolean supportsBasicCalculation() {
return super.supportsBasicCalculation();
}

public boolean isBaseIdentifier() {
if (value instanceof OIdentifier) {
return true;
}
return false;
}
}
/* JavaCC - OriginalChecksum=30dc1016b686d4841bbd57d6e6c0bfbd (do not edit this line) */
Expand Up @@ -16,7 +16,6 @@
import com.orientechnologies.orient.core.record.ORecord;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.OIterableRecordSource;
import com.orientechnologies.orient.core.sql.filter.OSQLTarget;
import com.orientechnologies.orient.core.sql.query.OBasicResultSet;
import com.orientechnologies.orient.core.sql.query.OSQLAsynchQuery;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
Expand Down Expand Up @@ -212,7 +211,7 @@ public Object execute(OSQLAsynchQuery<ODocument> request, OCommandContext contex
Map<Object, Object> iArgs = context.getInputParameters();
try {

Map<String, Long> estimatedRootEntries = estimateRootEntries(aliasClasses, aliasFilters);
Map<String, Long> estimatedRootEntries = estimateRootEntries(aliasClasses, aliasFilters, context);
if (estimatedRootEntries.values().contains(0l)) {
return new OBasicResultSet();// some aliases do not match on any classes
}
Expand All @@ -224,7 +223,6 @@ public Object execute(OSQLAsynchQuery<ODocument> request, OCommandContext contex
calculateMatch(estimatedRootEntries, new MatchContext(), aliasClasses, aliasFilters, context, request, executionPlan);
return getResult(request);
} finally {

if (request.getResultListener() != null) {
request.getResultListener().end();
}
Expand Down Expand Up @@ -309,7 +307,7 @@ private boolean calculateMatch(Pattern pattern, Map<String, Long> estimatedRootE
for (Map.Entry<String, Long> entryPoint : estimatedRootEntries.entrySet()) {
if (entryPoint.getValue() < threshold) {
String nextAlias = entryPoint.getKey();
Iterable<OIdentifiable> matches = calculateMatches(nextAlias, aliasFilters, iCommandContext, aliasClasses);
Iterable<OIdentifiable> matches = fetchAliasCandidates(nextAlias, aliasFilters, iCommandContext, aliasClasses);

Set<OIdentifiable> ids = new HashSet<OIdentifiable>();
if (!matches.iterator().hasNext()) {
Expand All @@ -324,7 +322,7 @@ private boolean calculateMatch(Pattern pattern, Map<String, Long> estimatedRootE
// no nodes under threshold, guess the smallest one
if (!rootFound) {
String nextAlias = getNextAlias(estimatedRootEntries, matchContext);
Iterable<OIdentifiable> matches = calculateMatches(nextAlias, aliasFilters, iCommandContext, aliasClasses);
Iterable<OIdentifiable> matches = fetchAliasCandidates(nextAlias, aliasFilters, iCommandContext, aliasClasses);
if (!matches.iterator().hasNext()) {
return true;
}
Expand Down Expand Up @@ -352,13 +350,12 @@ private boolean calculateMatch(Pattern pattern, Map<String, Long> estimatedRootE
return true;
}

private Iterable<OIdentifiable> calculateMatches(String nextAlias, Map<String, OWhereClause> aliasFilters,
private Iterable<OIdentifiable> fetchAliasCandidates(String nextAlias, Map<String, OWhereClause> aliasFilters,
OCommandContext iCommandContext, Map<String, String> aliasClasses) {
Iterable<OIdentifiable> it = query(aliasClasses.get(nextAlias), aliasFilters.get(nextAlias), iCommandContext);
Iterator<OIdentifiable> it = query(aliasClasses.get(nextAlias), aliasFilters.get(nextAlias), iCommandContext);
Set<OIdentifiable> result = new HashSet<OIdentifiable>();
// TODO dirty work around, review it. The iterable returned by the query just does not work.
for (OIdentifiable id : it) {
result.add(id.getIdentity());
while(it.hasNext()){
result.add(it.next().getIdentity());
}

return result;
Expand Down Expand Up @@ -492,7 +489,7 @@ private void expandCartesianProduct(Pattern pattern, MatchContext matchContext,
throw new OCommandExecutionException("Cannot execute MATCH statement on alias " + alias + ": class not defined");
}

Iterable<OIdentifiable> values = calculateMatches(alias, aliasFilters, iCommandContext, aliasClasses);
Iterable<OIdentifiable> values = fetchAliasCandidates(alias, aliasFilters, iCommandContext, aliasClasses);
for (OIdentifiable id : values) {
MatchContext childContext = matchContext.copy(alias, id);
if (allNodesCalculated(childContext, pattern)) {
Expand Down Expand Up @@ -589,7 +586,7 @@ private boolean returnsPaths() {
return false;
}

private Iterable<OIdentifiable> query(String className, OWhereClause oWhereClause, OCommandContext ctx) {
private Iterator<OIdentifiable> query(String className, OWhereClause oWhereClause, OCommandContext ctx) {
final ODatabaseDocument database = getDatabase();
OClass schemaClass = database.getMetadata().getSchema().getClass(className);
database.checkSecurity(ORule.ResourceGeneric.CLASS, ORole.PERMISSION_READ, schemaClass.getName().toLowerCase());
Expand All @@ -601,18 +598,33 @@ private Iterable<OIdentifiable> query(String className, OWhereClause oWhereClaus
// }
// Iterable<OIdentifiable> result = new FilteredIterator(baseIterable, oWhereClause);

String text;

if (oWhereClause == null) {
text = "(select from " + className + ")";
} else {
StringBuilder builder = new StringBuilder();
oWhereClause.toString(ctx.getInputParameters(), builder);
text = "(select from " + className + " where " + builder.toString() + ")";
}
OSQLTarget target = new OSQLTarget(text, ctx, "where");
OSelectStatement stm = buildSelectStatement(className, oWhereClause);
return stm.execute(ctx);

// String text;
// if (oWhereClause == null) {
// text = "(select from " + className + ")";
// } else {
// StringBuilder builder = new StringBuilder();
// oWhereClause.toString(ctx.getInputParameters(), builder);
// text = "(select from " + className + " where " + builder.toString() + ")";
// }
// OSQLTarget target = new OSQLTarget(text, ctx, "where");
//
// return (Iterable) target.getTargetRecords();
}

return (Iterable) target.getTargetRecords();
private OSelectStatement buildSelectStatement(String className, OWhereClause oWhereClause) {
OSelectStatement stm = new OSelectStatement(-1);
stm.whereClause = oWhereClause;
stm.target = new OFromClause(-1);
stm.target.item = new OFromItem(-1);
stm.target.item.identifier = new OBaseIdentifier(-1);
stm.target.item.identifier.suffix = new OSuffixIdentifier(-1);
stm.target.item.identifier.suffix.identifier = new OIdentifier(-1);
stm.target.item.identifier.suffix.identifier.value = className;
return stm;
}

private Iterable<ORecord> fetchFromIndex(OClass schemaClass, OWhereClause oWhereClause) {
Expand All @@ -635,7 +647,7 @@ private String getNextAlias(Map<String, Long> estimatedRootEntries, MatchContext
return lowerValue.getKey();
}

private Map<String, Long> estimateRootEntries(Map<String, String> aliasClasses, Map<String, OWhereClause> aliasFilters) {
private Map<String, Long> estimateRootEntries(Map<String, String> aliasClasses, Map<String, OWhereClause> aliasFilters, OCommandContext ctx) {
Set<String> allAliases = new LinkedHashSet<String>();
allAliases.addAll(aliasClasses.keySet());
allAliases.addAll(aliasFilters.keySet());
Expand All @@ -656,7 +668,7 @@ private Map<String, Long> estimateRootEntries(Map<String, String> aliasClasses,
long upperBound;
OWhereClause filter = aliasFilters.get(alias);
if (filter != null) {
upperBound = filter.estimate(oClass);
upperBound = filter.estimate(oClass, this.threshold, ctx);
} else {
upperBound = oClass.count();
}
Expand Down
Expand Up @@ -338,5 +338,21 @@ public Iterable<OIdentifiable> executeIndexedFunction(OFromClause target, OComma
}
return this.childExpressions.get(0).executeIndexedFunction(target, context, operator, right);
}

public boolean isBaseIdentifier() {
if (childExpressions.size() == 1) {
return childExpressions.get(0).isBaseIdentifier();
}
return false;
}

public boolean isEarlyCalculated() {
for (OMathExpression exp : childExpressions) {
if (!exp.isEarlyCalculated()) {
return false;
}
}
return true;
}
}
/* JavaCC - OriginalChecksum=c255bea24e12493e1005ba2a4d1dbb9d (do not edit this line) */
Expand Up @@ -82,5 +82,12 @@ public List<OBinaryCondition> getIndexedFunctionConditions(OClass iSchemaClass,
}
return sub.getIndexedFunctionConditions(iSchemaClass, database);
}

@Override public List<OAndBlock> flatten() {
if(!negate){
return sub.flatten();
}
return super.flatten();
}
}
/* JavaCC - OriginalChecksum=1926313b3f854235aaa20811c22d583b (do not edit this line) */
Expand Up @@ -117,5 +117,16 @@ public List<OBinaryCondition> getIndexedFunctionConditions(OClass iSchemaClass,
return result.size() == 0 ? null : result;
}

public List<OAndBlock> flatten() {
List<OAndBlock> result = new ArrayList<OAndBlock>();
for(OBooleanExpression sub:subBlocks){
List<OAndBlock> childFlattened = sub.flatten();
for(OAndBlock child:childFlattened){
result.add(child);
}
}
return result;
}

}
/* JavaCC - OriginalChecksum=98d3077303a598705894dbb7bd4e1573 (do not edit this line) */
Expand Up @@ -51,5 +51,9 @@ protected int getNumberOfExternalCalculations() {
protected List<Object> getExternalCalculationConditions() {
return subElement.getExternalCalculationConditions();
}

@Override public List<OAndBlock> flatten() {
return subElement.flatten();
}
}
/* JavaCC - OriginalChecksum=9a16b6cf7d051382acb94c45067631a9 (do not edit this line) */
Expand Up @@ -32,14 +32,18 @@ public void toString(Map<Object, Object> params, StringBuilder builder) {
builder.append(")");
}



@Override
protected boolean supportsBasicCalculation() {
if (expression != null) {
return expression.supportsBasicCalculation();
}
return true;
}

@Override
public boolean isEarlyCalculated() {
// TODO implement query execution and early calculation;
return expression != null && expression.isEarlyCalculated();
}
}
/* JavaCC - OriginalChecksum=4656e5faf4f54dc3fc45a06d8e375c35 (do not edit this line) */

0 comments on commit 87a2bcf

Please sign in to comment.