blob: 75814df60fd4dedfcf930007057a94375d1c05d6 [file] [log] [blame]
package edu.uci.ics.asterix.runtime.evaluators.functions;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import edu.uci.ics.asterix.common.utils.UTF8CharSequence;
import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
import edu.uci.ics.asterix.om.base.AString;
import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
import edu.uci.ics.asterix.om.types.BuiltinType;
import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
import edu.uci.ics.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
/**
* @author Xiaoyu Ma
*/
public class StringMatchesDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
public IFunctionDescriptor createFunctionDescriptor() {
return new StringMatchesDescriptor();
}
};
@Override
public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
return new ICopyEvaluatorFactory() {
private static final long serialVersionUID = 1L;
@Override
public ICopyEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
DataOutput dout = output.getDataOutput();
return new AbstractBinaryStringBoolEval(dout, args[0], args[1]) {
private Pattern pattern = null;
private Matcher matcher = null;
private ByteArrayAccessibleOutputStream lastPattern = new ByteArrayAccessibleOutputStream();
private IBinaryComparator strComp = AqlBinaryComparatorFactoryProvider.INSTANCE
.getBinaryComparatorFactory(BuiltinType.ASTRING, true).createBinaryComparator();
private UTF8CharSequence carSeq = new UTF8CharSequence();
@SuppressWarnings("unchecked")
private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
.getSerializerDeserializer(BuiltinType.ASTRING);
@Override
protected boolean compute(byte[] lBytes, int lLen, int lStart, byte[] rBytes, int rLen, int rStart,
ArrayBackedValueStorage array0, ArrayBackedValueStorage array1) throws AlgebricksException {
try {
boolean newPattern = false;
if (pattern == null) {
newPattern = true;
} else {
int c = strComp.compare(rBytes, rStart, rLen, lastPattern.getByteArray(), 0,
lastPattern.size());
if (c != 0) {
newPattern = true;
}
}
if (newPattern) {
lastPattern.reset();
lastPattern.write(rBytes, rStart, rLen);
// ! object creation !
DataInputStream di = new DataInputStream(new ByteArrayInputStream(
lastPattern.getByteArray()));
AString strPattern = (AString) stringSerde.deserialize(di);
// pattern = Pattern.compile(toRegex(strPattern));
pattern = Pattern.compile(strPattern.getStringValue());
}
carSeq.reset(array0, 1);
if (newPattern) {
matcher = pattern.matcher(carSeq);
} else {
matcher.reset(carSeq);
}
return matcher.find();
} catch (HyracksDataException e) {
throw new AlgebricksException(e);
}
}
};
}
};
}
@Override
public FunctionIdentifier getIdentifier() {
return AsterixBuiltinFunctions.STRING_MATCHES;
}
}