blob: 07d41f05431617f092778effc54d216986293792 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.asterix.external.classad;
import org.apache.asterix.external.classad.object.pool.ClassAdObjectPool;
import org.apache.asterix.om.base.AMutableDouble;
import org.apache.asterix.om.base.AMutableInt32;
import org.apache.asterix.om.base.AMutableInt64;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.hyracks.api.exceptions.HyracksDataException;
public class Value {
private ValueType valueType;
private long longVal;
private double doubleVal;
private boolean boolVal;
private final ClassAdTime timeVal;
private final ClassAd classadVal;
private final ExprList listVal;
private String stringVal;
/// Value types
public enum ValueType {
NULL_VALUE,
/** The error value */
ERROR_VALUE,
/** The undefined value */
UNDEFINED_VALUE,
/** A boolean value (false, true) */
BOOLEAN_VALUE,
/** An integer value */
INTEGER_VALUE,
/** A real value */
REAL_VALUE,
/** A relative time value */
RELATIVE_TIME_VALUE,
/** An absolute time value */
ABSOLUTE_TIME_VALUE,
/** A string value */
STRING_VALUE,
/** A classad value */
CLASSAD_VALUE,
/** A list value (not owned here) */
LIST_VALUE,
/** A list value (owned via shared_ptr) */
SLIST_VALUE
}
/// Number factors
public enum NumberFactor {
/** No factor specified */
NO_FACTOR,
/** Byte factor */
B_FACTOR,
/** Kilo factor */
K_FACTOR,
/** Mega factor */
M_FACTOR,
/** Giga factor */
G_FACTOR,
/** Terra factor */
T_FACTOR
}
public ValueType getType() {
return valueType;
}
public boolean isBooleanValue(MutableBoolean b) {
if (valueType == ValueType.BOOLEAN_VALUE) {
b.setValue(boolVal);
return true;
}
return false;
}
public boolean isBooleanValue() {
return (valueType == ValueType.BOOLEAN_VALUE);
}
public boolean isIntegerValue(AMutableInt64 i) {
if (valueType == ValueType.INTEGER_VALUE) {
i.setValue(longVal);
return true;
}
return false;
}
public boolean isIntegerValue() {
return (valueType == ValueType.INTEGER_VALUE);
}
public boolean isRealValue(AMutableDouble r) {
if (valueType == ValueType.REAL_VALUE) {
r.setValue(doubleVal);
return true;
}
return false;
}
public boolean isRealValue() {
return (valueType == ValueType.REAL_VALUE);
}
public boolean isListValue(ExprList el) {
if (valueType == ValueType.LIST_VALUE || valueType == ValueType.SLIST_VALUE) {
el.getExprList().addAll(listVal.getExprList());
el.isShared = listVal.isShared;
return true;
} else {
return false;
}
}
public boolean isListValue() {
return (valueType == ValueType.LIST_VALUE || valueType == ValueType.SLIST_VALUE);
}
public boolean isStringValue() {
return (valueType == ValueType.STRING_VALUE);
}
public boolean isStringValue(AMutableCharArrayString s) {
if (valueType == ValueType.STRING_VALUE) {
s.setValue(stringVal);
return true;
} else {
return false;
}
}
public boolean isStringValue(AMutableCharArrayString s, int len) {
if (valueType == ValueType.STRING_VALUE) {
s.setValue(stringVal, len);
return (true);
}
return (false);
}
public boolean isStringValue(AMutableInt32 size) {
if (valueType == ValueType.STRING_VALUE) {
size.setValue(stringVal.length());
return true;
} else {
size.setValue(-1);
return false;
}
}
public boolean isClassAdValue(ClassAd ad) throws HyracksDataException {
if (valueType == ValueType.CLASSAD_VALUE) {
ad.setValue(classadVal);
return true;
} else {
return false;
}
}
public boolean isClassAdValue() {
return (valueType == ValueType.CLASSAD_VALUE);
}
public boolean isUndefinedValue() {
return (valueType == ValueType.UNDEFINED_VALUE);
}
public boolean isErrorValue() {
return (valueType == ValueType.ERROR_VALUE);
}
public boolean isExceptional() {
return (valueType == ValueType.UNDEFINED_VALUE || valueType == ValueType.ERROR_VALUE);
}
public boolean isAbsoluteTimeValue() {
return (valueType == ValueType.ABSOLUTE_TIME_VALUE);
}
public boolean isAbsoluteTimeValue(ClassAdTime secs) {
if (valueType == ValueType.ABSOLUTE_TIME_VALUE) {
secs.setValue(timeVal);
return true;
} else {
return false;
}
}
public boolean isRelativeTimeValue() {
return (valueType == ValueType.RELATIVE_TIME_VALUE);
}
public boolean isRelativeTimeValue(ClassAdTime secs) {
if (valueType == ValueType.RELATIVE_TIME_VALUE) {
secs.setValue(timeVal);
return true;
}
return false;
}
public boolean isNumber() {
return (valueType == ValueType.INTEGER_VALUE || valueType == ValueType.REAL_VALUE);
}
public boolean isNumber(AMutableInt64 i) {
switch (valueType) {
case INTEGER_VALUE:
i.setValue(longVal);
return true;
case REAL_VALUE:
i.setValue((long) doubleVal);
return true;
case BOOLEAN_VALUE:
i.setValue(boolVal ? 1L : 0L);
return true;
default:
return false;
}
}
public boolean isNumber(AMutableDouble r) {
switch (valueType) {
case INTEGER_VALUE:
r.setValue(longVal);
return true;
case REAL_VALUE:
r.setValue(doubleVal);
return true;
case BOOLEAN_VALUE:
r.setValue(boolVal ? 1.0 : 0.0);
return true;
default:
return false;
}
}
// Implementation
public static final double[] ScaleFactor = { 1.0, // none
1.0, // B
1024.0, // Kilo
1024.0 * 1024.0, // Mega
1024.0 * 1024.0 * 1024.0, // Giga
1024.0 * 1024.0 * 1024.0 * 1024.0 // Terra
};
public Value(ClassAdObjectPool objectPool) {
valueType = ValueType.UNDEFINED_VALUE;
this.timeVal = new ClassAdTime();
this.listVal = new ExprList(objectPool);
this.classadVal = new ClassAd(objectPool);
}
public void setValue(Value value) throws HyracksDataException {
valueType = value.valueType;
switch (value.valueType) {
case ABSOLUTE_TIME_VALUE:
this.timeVal.setValue(value.timeVal);
break;
case BOOLEAN_VALUE:
this.boolVal = value.boolVal;
break;
case CLASSAD_VALUE:
this.classadVal.setValue(value.classadVal);
break;
case ERROR_VALUE:
break;
case INTEGER_VALUE:
this.longVal = value.longVal;
break;
case LIST_VALUE:
this.listVal.setValue(value.listVal);
break;
case NULL_VALUE:
break;
case REAL_VALUE:
this.doubleVal = value.doubleVal;
break;
case RELATIVE_TIME_VALUE:
this.timeVal.setValue((value.timeVal));
break;
case SLIST_VALUE:
listVal.setValue(value.listVal);
break;
case STRING_VALUE:
stringVal = value.stringVal;
break;
case UNDEFINED_VALUE:
break;
default:
break;
}
}
private void clear() {
valueType = ValueType.UNDEFINED_VALUE;
}
public void reset() {
valueType = ValueType.UNDEFINED_VALUE;
listVal.reset();
timeVal.reset();
classadVal.reset();
}
public void setRealValue(double r) {
valueType = ValueType.REAL_VALUE;
doubleVal = r;
}
public void setRealValue(AMutableDouble r) {
valueType = ValueType.REAL_VALUE;
doubleVal = r.getDoubleValue();
}
public void setBooleanValue(boolean b) {
valueType = ValueType.BOOLEAN_VALUE;
boolVal = b;
}
public void setBooleanValue(MutableBoolean b) {
valueType = ValueType.BOOLEAN_VALUE;
boolVal = b.booleanValue();
}
public void setIntegerValue(long i) {
valueType = ValueType.INTEGER_VALUE;
longVal = i;
}
public void setUndefinedValue() {
valueType = ValueType.UNDEFINED_VALUE;
}
public void setErrorValue() {
valueType = ValueType.ERROR_VALUE;
}
public void setStringValue(AMutableCharArrayString s) {
valueType = ValueType.STRING_VALUE;
stringVal = s.toString();
}
public void setStringValue(String s) {
valueType = ValueType.STRING_VALUE;
stringVal = s;
}
public void setListValue(ExprList expList) throws HyracksDataException {
valueType = expList.isShared ? ValueType.SLIST_VALUE : ValueType.LIST_VALUE;
listVal.setValue(expList);
}
public void setClassAdValue(ClassAd ad) throws HyracksDataException {
clear();
valueType = ValueType.CLASSAD_VALUE;
classadVal.setValue(ad);
}
public void setRelativeTimeValue(ClassAdTime rsecs) {
clear();
valueType = ValueType.RELATIVE_TIME_VALUE;
timeVal.setValue(rsecs);
}
public void setRelativeTimeValue(long rsecs) {
clear();
valueType = ValueType.RELATIVE_TIME_VALUE;
timeVal.setValue(rsecs);
timeVal.isAbsolute(false);
}
public void setAbsoluteTimeValue(ClassAdTime tim) {
clear();
valueType = ValueType.ABSOLUTE_TIME_VALUE;
timeVal.setValue(tim);
}
public boolean sameAs(Value otherValue) {
boolean is_same = false;
if (valueType != otherValue.valueType) {
is_same = false;
} else {
switch (valueType) {
case NULL_VALUE:
case ERROR_VALUE:
case UNDEFINED_VALUE:
is_same = true;
break;
case BOOLEAN_VALUE:
is_same = (boolVal == otherValue.boolVal);
break;
case INTEGER_VALUE:
is_same = (longVal == otherValue.longVal);
break;
case REAL_VALUE:
is_same = (doubleVal == otherValue.doubleVal);
break;
case LIST_VALUE:
case SLIST_VALUE:
is_same = listVal.equals(otherValue.listVal);
break;
case CLASSAD_VALUE:
is_same = classadVal.equals(otherValue.classadVal);
break;
case RELATIVE_TIME_VALUE:
case ABSOLUTE_TIME_VALUE:
is_same = timeVal.equals(otherValue.timeVal);
break;
case STRING_VALUE:
is_same = stringVal.equals(otherValue.stringVal);
break;
}
}
return is_same;
}
public boolean equals(Value value) {
return sameAs(value);
}
public boolean isBooleanValueEquiv(MutableBoolean b) {
return isBooleanValue(b);
}
@Override
public String toString() {
ClassAdUnParser unparser = new PrettyPrint(new ClassAdObjectPool());
AMutableCharArrayString unparsed_text = new AMutableCharArrayString();
switch (valueType) {
case ABSOLUTE_TIME_VALUE:
case CLASSAD_VALUE:
case RELATIVE_TIME_VALUE:
case SLIST_VALUE:
case LIST_VALUE:
try {
unparser.unparse(unparsed_text, this);
} catch (HyracksDataException e) {
e.printStackTrace();
}
return unparsed_text.toString();
case BOOLEAN_VALUE:
if (boolVal) {
return "true";
} else {
return "false";
}
case ERROR_VALUE:
return "error";
case INTEGER_VALUE:
return String.valueOf(longVal);
case NULL_VALUE:
return "(null)";
case REAL_VALUE:
return String.valueOf(doubleVal);
case STRING_VALUE:
return stringVal;
case UNDEFINED_VALUE:
return "undefined";
default:
break;
}
return null;
}
public static boolean convertValueToRealValue(Value value, Value realValue, ClassAdObjectPool objectPool)
throws HyracksDataException {
boolean could_convert;
AMutableCharArrayString buf = objectPool.strPool.get();
int endIndex;
char end;
AMutableInt64 ivalue = objectPool.int64Pool.get();
ClassAdTime atvalue = objectPool.classAdTimePool.get();
MutableBoolean bvalue = objectPool.boolPool.get();
double rvalue;
NumberFactor nf = NumberFactor.NO_FACTOR;
switch (value.getType()) {
case UNDEFINED_VALUE:
realValue.setUndefinedValue();
could_convert = false;
break;
case ERROR_VALUE:
case CLASSAD_VALUE:
case LIST_VALUE:
case SLIST_VALUE:
realValue.setErrorValue();
could_convert = false;
break;
case STRING_VALUE:
could_convert = true;
value.isStringValue(buf);
endIndex = buf.fistNonDoubleDigitChar();
if (endIndex < 0) {
// no non digit
String buffString = buf.toString();
if (buffString.contains("INF")) {
buffString = buffString.replace("INF", "Infinity");
}
rvalue = Double.parseDouble(buffString);
nf = NumberFactor.NO_FACTOR;
} else {
rvalue = Double.parseDouble(buf.substr(0, endIndex));
end = buf.charAt(endIndex);
switch (Character.toUpperCase(end)) {
case 'B':
nf = NumberFactor.B_FACTOR;
break;
case 'K':
nf = NumberFactor.K_FACTOR;
break;
case 'M':
nf = NumberFactor.M_FACTOR;
break;
case 'G':
nf = NumberFactor.G_FACTOR;
break;
case 'T':
nf = NumberFactor.T_FACTOR;
break;
case '\0':
nf = NumberFactor.NO_FACTOR;
break;
default:
nf = NumberFactor.NO_FACTOR;
break;
}
}
if (could_convert) {
realValue.setRealValue(rvalue * Value.ScaleFactor[nf.ordinal()]);
}
break;
case BOOLEAN_VALUE:
value.isBooleanValue(bvalue);
realValue.setRealValue(bvalue.booleanValue() ? 1.0 : 0.0);
could_convert = true;
break;
case INTEGER_VALUE:
value.isIntegerValue(ivalue);
realValue.setRealValue(ivalue.getLongValue());
could_convert = true;
break;
case REAL_VALUE:
realValue.setValue(value);
could_convert = true;
break;
case ABSOLUTE_TIME_VALUE:
value.isAbsoluteTimeValue(atvalue);
realValue.setRealValue(atvalue.getTimeInMillis() / 1000.0);
could_convert = true;
break;
case RELATIVE_TIME_VALUE:
value.isRelativeTimeValue(atvalue);
realValue.setRealValue(atvalue.getRelativeTime() / 1000.0);
could_convert = true;
break;
default:
could_convert = false; // Make gcc's -Wuninitalized happy
throw new HyracksDataException("Should not reach here");
}
return could_convert;
}
public static boolean convertValueToIntegerValue(Value value, Value integerValue, ClassAdObjectPool objectPool)
throws HyracksDataException {
boolean could_convert;
AMutableCharArrayString buf = objectPool.strPool.get();
char end;
AMutableInt64 ivalue = objectPool.int64Pool.get();
AMutableDouble rtvalue = objectPool.doublePool.get();
ClassAdTime atvalue = objectPool.classAdTimePool.get();
MutableBoolean bvalue = objectPool.boolPool.get();
NumberFactor nf;
switch (value.getType()) {
case UNDEFINED_VALUE:
integerValue.setUndefinedValue();
could_convert = false;
break;
case ERROR_VALUE:
case CLASSAD_VALUE:
case LIST_VALUE:
case SLIST_VALUE:
integerValue.setErrorValue();
could_convert = false;
break;
case STRING_VALUE:
could_convert = true;
value.isStringValue(buf);
int endIndex = buf.firstNonDigitChar();
if (endIndex < 0) {
// no non digit
ivalue.setValue(Long.parseLong(buf.toString()));
nf = NumberFactor.NO_FACTOR;
break;
} else {
ivalue.setValue(Long.parseLong(buf.substr(0, endIndex)));
end = buf.charAt(endIndex);
switch (Character.toUpperCase(end)) {
case 'B':
nf = NumberFactor.B_FACTOR;
break;
case 'K':
nf = NumberFactor.K_FACTOR;
break;
case 'M':
nf = NumberFactor.M_FACTOR;
break;
case 'G':
nf = NumberFactor.G_FACTOR;
break;
case 'T':
nf = NumberFactor.T_FACTOR;
break;
case '\0':
nf = NumberFactor.NO_FACTOR;
break;
default:
nf = NumberFactor.NO_FACTOR;
break;
}
if (could_convert) {
integerValue
.setIntegerValue((long) ((ivalue.getLongValue() * Value.ScaleFactor[nf.ordinal()])));
}
}
break;
case BOOLEAN_VALUE:
value.isBooleanValue(bvalue);
integerValue.setIntegerValue(bvalue.booleanValue() ? 1 : 0);
could_convert = true;
break;
case INTEGER_VALUE:
integerValue.setValue(value);
could_convert = true;
break;
case REAL_VALUE:
value.isRealValue(rtvalue);
integerValue.setIntegerValue((long) rtvalue.getDoubleValue());
could_convert = true;
break;
case ABSOLUTE_TIME_VALUE:
value.isAbsoluteTimeValue(atvalue);
integerValue.setIntegerValue(atvalue.getTimeInMillis() / 1000L);
could_convert = true;
break;
case RELATIVE_TIME_VALUE:
value.isRelativeTimeValue(atvalue);
integerValue.setIntegerValue((atvalue.getTime() / 1000L));
could_convert = true;
break;
default:
could_convert = false; // Make gcc's -Wuninitalized happy
throw new HyracksDataException("Should not reach here");
}
return could_convert;
}
public static boolean convertValueToStringValue(Value value, Value stringValue, ClassAdObjectPool objectPool)
throws HyracksDataException {
boolean could_convert = false;
ClassAdTime atvalue = objectPool.classAdTimePool.get();
AMutableCharArrayString string_representation = objectPool.strPool.get();
ClassAdUnParser unparser = objectPool.prettyPrintPool.get();
switch (value.getType()) {
case UNDEFINED_VALUE:
stringValue.setUndefinedValue();
could_convert = false;
break;
case ERROR_VALUE:
stringValue.setErrorValue();
could_convert = false;
break;
case STRING_VALUE:
stringValue.setValue(value);
could_convert = true;
break;
case CLASSAD_VALUE:
case LIST_VALUE:
case SLIST_VALUE:
case BOOLEAN_VALUE:
case INTEGER_VALUE:
case REAL_VALUE:
unparser.unparse(string_representation, value);
stringValue.setStringValue(string_representation);
could_convert = true;
break;
case ABSOLUTE_TIME_VALUE:
value.isAbsoluteTimeValue(atvalue);
Util.absTimeToString(atvalue, string_representation);
stringValue.setStringValue(string_representation);
could_convert = true;
break;
case RELATIVE_TIME_VALUE:
value.isRelativeTimeValue(atvalue);
Util.relTimeToString(atvalue.getTimeInMillis(), string_representation);
stringValue.setStringValue(string_representation);
could_convert = true;
break;
default:
could_convert = false; // Make gcc's -Wuninitalized happy
throw new HyracksDataException("Should not reach here");
}
return could_convert;
}
public boolean isSListValue(ExprList l) throws HyracksDataException {
if (valueType == ValueType.SLIST_VALUE || valueType == ValueType.LIST_VALUE) {
l.setValue(listVal);
return true;
} else {
return false;
}
}
public ValueType getValueType() {
return valueType;
}
public long getLongVal() {
return longVal;
}
public double getDoubleVal() {
return doubleVal;
}
public boolean getBoolVal() {
return boolVal;
}
public ClassAdTime getTimeVal() {
return timeVal;
}
public ClassAd getClassadVal() {
return classadVal;
}
public ExprList getListVal() {
return listVal;
}
public String getStringVal() {
return stringVal;
}
public static double[] getScalefactor() {
return ScaleFactor;
}
}