From 94460377e3071db30c5bb9feec0fde1f95eca7d3 Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Thu, 16 Nov 2017 12:02:13 +0100 Subject: [PATCH] serialize vectors using VectorAccess --- .../oracle/truffle/r/runtime/RSerialize.java | 134 +++++++----------- 1 file changed, 54 insertions(+), 80 deletions(-) diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index 3b5cda9b10..33167db999 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -53,10 +53,8 @@ import com.oracle.truffle.r.runtime.data.Closure; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; -import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; @@ -66,7 +64,6 @@ import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RPromise.PromiseState; -import com.oracle.truffle.r.runtime.data.RRawVector; import com.oracle.truffle.r.runtime.data.RScalar; import com.oracle.truffle.r.runtime.data.RShareable; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -77,11 +74,14 @@ import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractListBaseVector; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.nodes.VectorAccess; +import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.env.frame.ActiveBinding; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; @@ -1262,10 +1262,8 @@ public class RSerialize { } } - // Serialize support is currently very limited, essentially to saving the CRAN package format - // info, - private abstract static class POutputStream { + protected OutputStream os; POutputStream(OutputStream os) { @@ -1278,7 +1276,7 @@ public class RSerialize { abstract void writeDouble(double value) throws IOException; - abstract void writeRaw(byte[] value) throws IOException; + abstract void writeRaw(byte value) throws IOException; abstract void flush() throws IOException; @@ -1339,16 +1337,9 @@ public class RSerialize { } @Override - void writeRaw(byte[] value) throws IOException { - int valueLen = value.length; - if (valueLen > buf.length) { - flushBuffer(); - os.write(value); - } else { - ensureSpace(valueLen); - System.arraycopy(value, 0, buf, offset, valueLen); - offset += valueLen; - } + void writeRaw(byte value) throws IOException { + ensureSpace(1); + buf[offset++] = value; } @Override @@ -1480,6 +1471,9 @@ public class RSerialize { Object obj = objArg; boolean tailCall; do { + // convert primitive types into RAbstractVectors + obj = RRuntime.asAbstractVector(obj); + tailCall = false; SEXPTYPE specialType; Object psn; @@ -1548,70 +1542,49 @@ public class RSerialize { stream.writeInt(flags); switch (type) { case STRSXP: { - if (obj instanceof String) { - // length 1 vector - stream.writeInt(1); - writeCHARSXP((String) obj); - } else { - outStringVec((RAbstractStringVector) obj, true); - } + outStringVec((RAbstractStringVector) obj, true); break; } - case INTSXP: { - if (obj instanceof Integer) { - stream.writeInt(1); - stream.writeInt((int) obj); - } else { - RAbstractIntVector vec = (RAbstractIntVector) obj; - stream.writeInt(vec.getLength()); - for (int i = 0; i < vec.getLength(); i++) { - stream.writeInt(vec.getDataAt(i)); + case INTSXP: + case LGLSXP: { + // logicals are written as ints + RAbstractVector vector = (RAbstractVector) obj; + VectorAccess access = vector.slowPathAccess(); + try (SequentialIterator iter = access.access(vector)) { + stream.writeInt(access.getLength(iter)); + while (access.next(iter)) { + stream.writeInt(access.getInt(iter)); } } break; } case REALSXP: { - if (obj instanceof Double) { - stream.writeInt(1); - stream.writeDouble((double) obj); - } else { - RAbstractDoubleVector vec = (RAbstractDoubleVector) obj; - stream.writeInt(vec.getLength()); - for (int i = 0; i < vec.getLength(); i++) { - stream.writeDouble(vec.getDataAt(i)); - } - } - break; - } - - case LGLSXP: { - // Output as ints - if (obj instanceof Byte) { - stream.writeInt(1); - stream.writeInt(RRuntime.logical2int((byte) obj)); - } else { - RAbstractLogicalVector vec = (RAbstractLogicalVector) obj; - stream.writeInt(vec.getLength()); - for (int i = 0; i < vec.getLength(); i++) { - stream.writeInt(RRuntime.logical2int(vec.getDataAt(i))); + RAbstractDoubleVector vector = (RAbstractDoubleVector) obj; + VectorAccess access = vector.slowPathAccess(); + try (SequentialIterator iter = access.access(vector)) { + stream.writeInt(access.getLength(iter)); + while (access.next(iter)) { + stream.writeDouble(access.getDouble(iter)); } } break; } case CPLXSXP: { - RAbstractComplexVector vec = (RAbstractComplexVector) obj; - stream.writeInt(vec.getLength()); - for (int i = 0; i < vec.getLength(); i++) { - RComplex val = vec.getDataAt(i); - if (RRuntime.isNA(val)) { - stream.writeDouble(RRuntime.DOUBLE_NA); - stream.writeDouble(RRuntime.DOUBLE_NA); - } else { - stream.writeDouble(val.getRealPart()); - stream.writeDouble(val.getImaginaryPart()); + RAbstractComplexVector vector = (RAbstractComplexVector) obj; + VectorAccess access = vector.slowPathAccess(); + try (SequentialIterator iter = access.access(vector)) { + stream.writeInt(access.getLength(iter)); + while (access.next(iter)) { + if (access.isNA(iter)) { + stream.writeDouble(RRuntime.DOUBLE_NA); + stream.writeDouble(RRuntime.DOUBLE_NA); + } else { + stream.writeDouble(access.getComplexR(iter)); + stream.writeDouble(access.getComplexI(iter)); + } } } break; @@ -1619,25 +1592,26 @@ public class RSerialize { case EXPRSXP: case VECSXP: { - RAbstractVector list; - if (type == SEXPTYPE.EXPRSXP) { - list = (RExpression) obj; - } else { - list = (RList) obj; - } - stream.writeInt(list.getLength()); - for (int i = 0; i < list.getLength(); i++) { - Object listObj = list.getDataAtAsObject(i); - writeItem(listObj); + RAbstractListBaseVector vector = (RAbstractListBaseVector) obj; + VectorAccess access = vector.slowPathAccess(); + try (SequentialIterator iter = access.access(vector)) { + stream.writeInt(access.getLength(iter)); + while (access.next(iter)) { + writeItem(access.getListElement(iter)); + } } break; } case RAWSXP: { - RRawVector raw = (RRawVector) obj; - byte[] data = raw.getReadonlyData(); - stream.writeInt(data.length); - stream.writeRaw(data); + RAbstractRawVector vector = (RAbstractRawVector) obj; + VectorAccess access = vector.slowPathAccess(); + try (SequentialIterator iter = access.access(vector)) { + stream.writeInt(access.getLength(iter)); + while (access.next(iter)) { + stream.writeRaw(access.getRaw(iter)); + } + } break; } -- GitLab