com.yahoo.document.select.ResultList Maven / Gradle / Ivy
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.document.select;
import com.yahoo.document.datatypes.FieldPathIteratorHandler;
import com.yahoo.document.select.rule.AttributeNode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ResultList {
public static class ResultPair {
ResultPair(FieldPathIteratorHandler.VariableMap var, Result res) {
variables = var;
result = res;
}
FieldPathIteratorHandler.VariableMap variables;
Result result;
public FieldPathIteratorHandler.VariableMap getVariables() { return variables; }
public Result getResult() { return result; }
public String toString() {
return variables.toString() + " => " + result;
}
}
public static class VariableValue {
public VariableValue(FieldPathIteratorHandler.VariableMap vars, Object value) {
variables = vars;
this.value = value;
}
FieldPathIteratorHandler.VariableMap variables;
Object value;
public FieldPathIteratorHandler.VariableMap getVariables() { return variables; }
public Object getValue() { return value; }
public String toString() {
return variables.toString() + " => " + value;
}
}
private List results = new ArrayList<>();
public ResultList() {
}
public ResultList(Result result) {
add(new FieldPathIteratorHandler.VariableMap(), result);
}
public void add(FieldPathIteratorHandler.VariableMap variables, Result result) {
results.add(new ResultPair(variables, result));
}
public List getResults() {
return results;
}
public static ResultList fromBoolean(boolean result) {
return new ResultList(result ? Result.TRUE : Result.FALSE);
}
public Result toResult() {
if (results.isEmpty()) {
return Result.FALSE;
}
boolean foundFalse = false;
for (ResultPair rp : results) {
if (rp.result == Result.TRUE) {
return Result.TRUE;
} else if (rp.result == Result.FALSE) {
foundFalse = true;
}
}
if (foundFalse) {
return Result.FALSE;
} else {
return Result.INVALID;
}
}
private boolean combineVariables(FieldPathIteratorHandler.VariableMap output, FieldPathIteratorHandler.VariableMap input) {
// First, verify that all variables are overlapping
for (Map.Entry entry : output.entrySet()) {
FieldPathIteratorHandler.IndexValue found = input.get(entry.getKey());
if (found != null) {
if (!(found.equals(entry.getValue()))) {
return false;
}
}
}
for (Map.Entry entry : input.entrySet()) {
FieldPathIteratorHandler.IndexValue found = output.get(entry.getKey());
if (found != null) {
if (!(found.equals(entry.getValue()))) {
return false;
}
}
}
// Ok, variables are overlapping. Add all variables from input to output.
for (Map.Entry entry : input.entrySet()) {
output.put(entry.getKey(), entry.getValue());
}
return true;
}
public interface LazyResultList {
ResultList getResult();
}
public ResultList combineAND(LazyResultList other)
{
if (Result.FALSE == toResult()) return ResultList.toResultList(false);
ResultList result = new ResultList();
// TODO: optimize
for (ResultPair pair : results) {
for (ResultPair otherPair : other.getResult().results) {
FieldPathIteratorHandler.VariableMap varMap = (FieldPathIteratorHandler.VariableMap)pair.variables.clone();
if (combineVariables(varMap, otherPair.variables)) {
result.add(varMap, combineAND(pair.result, otherPair.result));
}
}
}
return result;
}
private static Result combineAND(Result lhs, Result rhs) {
if (lhs == Result.TRUE && rhs == Result.TRUE) {
return Result.TRUE;
}
if (lhs == Result.FALSE || rhs == Result.FALSE) {
return Result.FALSE;
}
return Result.INVALID;
}
public ResultList combineOR(LazyResultList other)
{
if (Result.TRUE == toResult()) return ResultList.toResultList(true);
ResultList result = new ResultList();
// TODO: optimize
for (ResultPair pair : results) {
for (ResultPair otherPair : other.getResult().results) {
FieldPathIteratorHandler.VariableMap varMap = (FieldPathIteratorHandler.VariableMap)pair.variables.clone();
if (combineVariables(varMap, otherPair.variables)) {
result.add(varMap, combineOR(pair.result, otherPair.result));
}
}
}
return result;
}
private static Result combineOR(Result lhs, Result rhs) {
if (lhs == Result.TRUE || rhs == Result.TRUE) {
return Result.TRUE;
}
if (lhs == Result.FALSE && rhs == Result.FALSE) {
return Result.FALSE;
}
return Result.INVALID;
}
/**
* Converts the given object value into a result list, so it can be compared by logical operators.
*
* @param value The object to convert.
* @return The corresponding result value.
*/
public static ResultList toResultList(Object value) {
if (value instanceof ResultList) {
return (ResultList)value;
} else if (value instanceof AttributeNode.VariableValueList) {
ResultList retVal = new ResultList();
for (VariableValue vv : (AttributeNode.VariableValueList)value) {
retVal.add(vv.getVariables(), Result.TRUE);
}
return retVal;
} else if (value == null || value == Result.FALSE || value == Boolean.FALSE ||
(value instanceof Number && ((Number)value).doubleValue() == 0)) {
return new ResultList(Result.FALSE);
} else if (value == Result.INVALID) {
return new ResultList(Result.INVALID);
} else {
return new ResultList(Result.TRUE);
}
}
public String toString() {
return results.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy