>From Preetham Poluparthi <[email protected]>:
Preetham Poluparthi has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21369?usp=email )
Change subject: WIP : Optimize FieldNameAccess
......................................................................
WIP : Optimize FieldNameAccess
Change-Id: I4d6cd6e14c1e1b917bb32a921f8776abfd9642e0
---
M
asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
M
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/FieldAccessByNameEvalFactory.java
2 files changed, 37 insertions(+), 18 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/69/21369/1
diff --git
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
index e955756..41855faf 100644
---
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
+++
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
@@ -301,6 +301,23 @@
public static int getFieldOffsetByName(byte[] serRecord, int start, int
len, byte[] fieldName, int nstart,
IBinaryHashFunction nameHashFunction, IBinaryComparator
nameComparator) throws HyracksDataException {
+ if (hasNoFields(serRecord, start, len) || serRecord[start + 5] != 1) {
+ return -1;
+ }
+ int fieldUtflength = UTF8StringUtil.getUTFLength(fieldName, nstart +
1);
+ int fieldUtfMetaLen =
UTF8StringUtil.getNumBytesToStoreLength(fieldUtflength);
+ int fieldNameHashCode = nameHashFunction.hash(fieldName, nstart + 1,
fieldUtflength + fieldUtfMetaLen);
+ return getFieldOffsetByName(serRecord, start, len, fieldName, nstart,
fieldNameHashCode, fieldUtflength,
+ fieldUtfMetaLen, nameComparator);
+ }
+
+ /**
+ * Variant for callers that have already computed the field name's hash
and UTF-8 length metadata (e.g. when the
+ * field name is constant across records). Avoids redundant hash
computation on every call.
+ */
+ public static int getFieldOffsetByName(byte[] serRecord, int start, int
len, byte[] fieldName, int nstart,
+ int fieldNameHashCode, int fieldUtflength, int fieldUtfMetaLen,
IBinaryComparator nameComparator)
+ throws HyracksDataException {
// 5 is the index of the byte that determines whether the record is
expanded or not, i.e. it has an open part.
if (hasNoFields(serRecord, start, len) || serRecord[start + 5] != 1) {
return -1;
@@ -308,9 +325,6 @@
// 6 is the index of the first byte of the openPartOffset value.
int openPartOffset = start +
AInt32SerializerDeserializer.getInt(serRecord, start + 6);
int numberOfOpenField = AInt32SerializerDeserializer.getInt(serRecord,
openPartOffset);
- int fieldUtflength = UTF8StringUtil.getUTFLength(fieldName, nstart +
1);
- int fieldUtfMetaLen =
UTF8StringUtil.getNumBytesToStoreLength(fieldUtflength);
- int fieldNameHashCode = nameHashFunction.hash(fieldName, nstart + 1,
fieldUtflength + fieldUtfMetaLen);
int offset = openPartOffset + 4;
int fieldOffset = -1;
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/FieldAccessByNameEvalFactory.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/FieldAccessByNameEvalFactory.java
index ce2f2d6..cbb0c62 100644
---
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/FieldAccessByNameEvalFactory.java
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/FieldAccessByNameEvalFactory.java
@@ -41,6 +41,7 @@
import org.apache.hyracks.data.std.primitive.VoidPointable;
import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import org.apache.hyracks.util.string.UTF8StringUtil;
public class FieldAccessByNameEvalFactory implements IScalarEvaluatorFactory {
@@ -73,16 +74,29 @@
private final IPointable inputArg0 = new VoidPointable();
private final IPointable inputArg1 = new VoidPointable();
private final IScalarEvaluator eval0 =
recordEvalFactory.createScalarEvaluator(ctx);
- private final IScalarEvaluator eval1 =
fldNameEvalFactory.createScalarEvaluator(ctx);
+ // fldNameHashCode, fldNameUtfLen, fldNameUtfMetaLen are
precomputed once at construction
+ // because the field name is constant (does not depend on the
tuple).
+ private final int fldNameHashCode;
+ private final int fldNameUtfLen;
+ private final int fldNameUtfMetaLen;
+
+ {
+ IScalarEvaluator eval1 =
fldNameEvalFactory.createScalarEvaluator(ctx);
+ eval1.evaluate(null, inputArg1);
+ byte[] bytes = inputArg1.getByteArray();
+ int offset = inputArg1.getStartOffset();
+ fldNameUtfLen = UTF8StringUtil.getUTFLength(bytes, offset + 1);
+ fldNameUtfMetaLen =
UTF8StringUtil.getNumBytesToStoreLength(fldNameUtfLen);
+ fldNameHashCode = fieldNameHashFunction.hash(bytes, offset +
1, fldNameUtfLen + fldNameUtfMetaLen);
+ }
@Override
public void evaluate(IFrameTupleReference tuple, IPointable
result) throws HyracksDataException {
try {
resultStorage.reset();
eval0.evaluate(tuple, inputArg0);
- eval1.evaluate(tuple, inputArg1);
- if (PointableHelper.checkAndSetMissingOrNull(result,
inputArg0, inputArg1)) {
+ if (PointableHelper.checkAndSetMissingOrNull(result,
inputArg0)) {
return;
}
@@ -97,18 +111,9 @@
result.set(resultStorage);
return;
}
- byte[] serFldName = inputArg1.getByteArray();
- int serFldNameOffset = inputArg1.getStartOffset();
- if (serFldName[serFldNameOffset] !=
ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
- ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, funID,
serFldName[serFldNameOffset], 1,
- ATypeTag.STRING);
- out.writeByte(ATypeTag.SERIALIZED_MISSING_TYPE_TAG);
- result.set(resultStorage);
- return;
- }
- int fieldValueOffset =
-
ARecordSerializerDeserializer.getFieldOffsetByName(serRecord, serRecordOffset,
serRecordLen,
- serFldName, serFldNameOffset,
fieldNameHashFunction, fieldNameComparator);
+ int fieldValueOffset =
ARecordSerializerDeserializer.getFieldOffsetByName(serRecord, serRecordOffset,
+ serRecordLen, inputArg1.getByteArray(),
inputArg1.getStartOffset(), fldNameHashCode,
+ fldNameUtfLen, fldNameUtfMetaLen,
fieldNameComparator);
if (fieldValueOffset < 0) {
out.writeByte(ATypeTag.SERIALIZED_MISSING_TYPE_TAG);
result.set(resultStorage);
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21369?usp=email
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I4d6cd6e14c1e1b917bb32a921f8776abfd9642e0
Gerrit-Change-Number: 21369
Gerrit-PatchSet: 1
Gerrit-Owner: Preetham Poluparthi <[email protected]>