Skip to content

Commit

Permalink
Array Expansion Kernel O(n^2) -> O(n) (deephaven#2458)
Browse files Browse the repository at this point in the history
  • Loading branch information
nbauernfeind committed Jun 1, 2022
1 parent b778e11 commit e932fac
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import io.deephaven.chunk.WritableObjectChunk;
import io.deephaven.chunk.attributes.Any;
import io.deephaven.chunk.attributes.ChunkPositions;
import io.deephaven.chunk.sized.SizedBooleanChunk;
import io.deephaven.util.datastructures.LongSizedDataStructure;

public class BooleanArrayExpansionKernel implements ArrayExpansionKernel {
private final static boolean[] ZERO_LEN_ARRAY = new boolean[0];
Expand All @@ -33,24 +33,29 @@ public <T, A extends Any> WritableChunk<A> expand(final ObjectChunk<T, A> source
}

final ObjectChunk<boolean[], A> typedSource = source.asObjectChunk();
final SizedBooleanChunk<A> resultWrapper = new SizedBooleanChunk<>();

long totalSize = 0;
for (int i = 0; i < typedSource.size(); ++i) {
final boolean[] row = typedSource.get(i);
totalSize += row == null ? 0 : row.length;
}
final WritableBooleanChunk<A> result = WritableBooleanChunk.makeWritableChunk(
LongSizedDataStructure.intSize("ExpansionKernel", totalSize));

int lenWritten = 0;
perElementLengthDest.setSize(source.size() + 1);
for (int i = 0; i < typedSource.size(); ++i) {
final boolean[] row = typedSource.get(i);
final int len = row == null ? 0 : row.length;
perElementLengthDest.set(i, lenWritten);
final WritableBooleanChunk<A> result = resultWrapper.ensureCapacityPreserve(lenWritten + len);
for (int j = 0; j < len; ++j) {
result.set(lenWritten + j, row[j]);
if (row == null) {
continue;
}
lenWritten += len;
result.setSize(lenWritten);
result.copyFromArray(row, 0, lenWritten, row.length);
lenWritten += row.length;
}
perElementLengthDest.set(typedSource.size(), lenWritten);

return resultWrapper.get();
return result;
}

@Override
Expand All @@ -77,15 +82,13 @@ public <T, A extends Any> WritableObjectChunk<T, A> contract(

int lenRead = 0;
for (int i = 0; i < itemsInBatch; ++i) {
final int ROW_LEN = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (ROW_LEN == 0) {
final int rowLen = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (rowLen == 0) {
result.set(outOffset + i, ZERO_LEN_ARRAY);
} else {
final boolean[] row = new boolean[ROW_LEN];
for (int j = 0; j < ROW_LEN; ++j) {
row[j] = typedSource.get(lenRead + j);
}
lenRead += ROW_LEN;
final boolean[] row = new boolean[rowLen];
typedSource.copyToArray(lenRead, row,0, rowLen);
lenRead += rowLen;
result.set(outOffset + i, row);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import io.deephaven.chunk.WritableObjectChunk;
import io.deephaven.chunk.attributes.Any;
import io.deephaven.chunk.attributes.ChunkPositions;
import io.deephaven.chunk.sized.SizedByteChunk;
import io.deephaven.util.datastructures.LongSizedDataStructure;

public class ByteArrayExpansionKernel implements ArrayExpansionKernel {
private final static byte[] ZERO_LEN_ARRAY = new byte[0];
Expand All @@ -33,24 +33,29 @@ public <T, A extends Any> WritableChunk<A> expand(final ObjectChunk<T, A> source
}

final ObjectChunk<byte[], A> typedSource = source.asObjectChunk();
final SizedByteChunk<A> resultWrapper = new SizedByteChunk<>();

long totalSize = 0;
for (int i = 0; i < typedSource.size(); ++i) {
final byte[] row = typedSource.get(i);
totalSize += row == null ? 0 : row.length;
}
final WritableByteChunk<A> result = WritableByteChunk.makeWritableChunk(
LongSizedDataStructure.intSize("ExpansionKernel", totalSize));

int lenWritten = 0;
perElementLengthDest.setSize(source.size() + 1);
for (int i = 0; i < typedSource.size(); ++i) {
final byte[] row = typedSource.get(i);
final int len = row == null ? 0 : row.length;
perElementLengthDest.set(i, lenWritten);
final WritableByteChunk<A> result = resultWrapper.ensureCapacityPreserve(lenWritten + len);
for (int j = 0; j < len; ++j) {
result.set(lenWritten + j, row[j]);
if (row == null) {
continue;
}
lenWritten += len;
result.setSize(lenWritten);
result.copyFromArray(row, 0, lenWritten, row.length);
lenWritten += row.length;
}
perElementLengthDest.set(typedSource.size(), lenWritten);

return resultWrapper.get();
return result;
}

@Override
Expand All @@ -77,15 +82,13 @@ public <T, A extends Any> WritableObjectChunk<T, A> contract(

int lenRead = 0;
for (int i = 0; i < itemsInBatch; ++i) {
final int ROW_LEN = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (ROW_LEN == 0) {
final int rowLen = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (rowLen == 0) {
result.set(outOffset + i, ZERO_LEN_ARRAY);
} else {
final byte[] row = new byte[ROW_LEN];
for (int j = 0; j < ROW_LEN; ++j) {
row[j] = typedSource.get(lenRead + j);
}
lenRead += ROW_LEN;
final byte[] row = new byte[rowLen];
typedSource.copyToArray(lenRead, row,0, rowLen);
lenRead += rowLen;
result.set(outOffset + i, row);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import io.deephaven.chunk.WritableObjectChunk;
import io.deephaven.chunk.attributes.Any;
import io.deephaven.chunk.attributes.ChunkPositions;
import io.deephaven.chunk.sized.SizedCharChunk;
import io.deephaven.util.datastructures.LongSizedDataStructure;

public class CharArrayExpansionKernel implements ArrayExpansionKernel {
private final static char[] ZERO_LEN_ARRAY = new char[0];
Expand All @@ -28,24 +28,29 @@ public <T, A extends Any> WritableChunk<A> expand(final ObjectChunk<T, A> source
}

final ObjectChunk<char[], A> typedSource = source.asObjectChunk();
final SizedCharChunk<A> resultWrapper = new SizedCharChunk<>();

long totalSize = 0;
for (int i = 0; i < typedSource.size(); ++i) {
final char[] row = typedSource.get(i);
totalSize += row == null ? 0 : row.length;
}
final WritableCharChunk<A> result = WritableCharChunk.makeWritableChunk(
LongSizedDataStructure.intSize("ExpansionKernel", totalSize));

int lenWritten = 0;
perElementLengthDest.setSize(source.size() + 1);
for (int i = 0; i < typedSource.size(); ++i) {
final char[] row = typedSource.get(i);
final int len = row == null ? 0 : row.length;
perElementLengthDest.set(i, lenWritten);
final WritableCharChunk<A> result = resultWrapper.ensureCapacityPreserve(lenWritten + len);
for (int j = 0; j < len; ++j) {
result.set(lenWritten + j, row[j]);
if (row == null) {
continue;
}
lenWritten += len;
result.setSize(lenWritten);
result.copyFromArray(row, 0, lenWritten, row.length);
lenWritten += row.length;
}
perElementLengthDest.set(typedSource.size(), lenWritten);

return resultWrapper.get();
return result;
}

@Override
Expand All @@ -72,15 +77,13 @@ public <T, A extends Any> WritableObjectChunk<T, A> contract(

int lenRead = 0;
for (int i = 0; i < itemsInBatch; ++i) {
final int ROW_LEN = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (ROW_LEN == 0) {
final int rowLen = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (rowLen == 0) {
result.set(outOffset + i, ZERO_LEN_ARRAY);
} else {
final char[] row = new char[ROW_LEN];
for (int j = 0; j < ROW_LEN; ++j) {
row[j] = typedSource.get(lenRead + j);
}
lenRead += ROW_LEN;
final char[] row = new char[rowLen];
typedSource.copyToArray(lenRead, row,0, rowLen);
lenRead += rowLen;
result.set(outOffset + i, row);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import io.deephaven.chunk.WritableObjectChunk;
import io.deephaven.chunk.attributes.Any;
import io.deephaven.chunk.attributes.ChunkPositions;
import io.deephaven.chunk.sized.SizedDoubleChunk;
import io.deephaven.util.datastructures.LongSizedDataStructure;

public class DoubleArrayExpansionKernel implements ArrayExpansionKernel {
private final static double[] ZERO_LEN_ARRAY = new double[0];
Expand All @@ -33,24 +33,29 @@ public <T, A extends Any> WritableChunk<A> expand(final ObjectChunk<T, A> source
}

final ObjectChunk<double[], A> typedSource = source.asObjectChunk();
final SizedDoubleChunk<A> resultWrapper = new SizedDoubleChunk<>();

long totalSize = 0;
for (int i = 0; i < typedSource.size(); ++i) {
final double[] row = typedSource.get(i);
totalSize += row == null ? 0 : row.length;
}
final WritableDoubleChunk<A> result = WritableDoubleChunk.makeWritableChunk(
LongSizedDataStructure.intSize("ExpansionKernel", totalSize));

int lenWritten = 0;
perElementLengthDest.setSize(source.size() + 1);
for (int i = 0; i < typedSource.size(); ++i) {
final double[] row = typedSource.get(i);
final int len = row == null ? 0 : row.length;
perElementLengthDest.set(i, lenWritten);
final WritableDoubleChunk<A> result = resultWrapper.ensureCapacityPreserve(lenWritten + len);
for (int j = 0; j < len; ++j) {
result.set(lenWritten + j, row[j]);
if (row == null) {
continue;
}
lenWritten += len;
result.setSize(lenWritten);
result.copyFromArray(row, 0, lenWritten, row.length);
lenWritten += row.length;
}
perElementLengthDest.set(typedSource.size(), lenWritten);

return resultWrapper.get();
return result;
}

@Override
Expand All @@ -77,15 +82,13 @@ public <T, A extends Any> WritableObjectChunk<T, A> contract(

int lenRead = 0;
for (int i = 0; i < itemsInBatch; ++i) {
final int ROW_LEN = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (ROW_LEN == 0) {
final int rowLen = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (rowLen == 0) {
result.set(outOffset + i, ZERO_LEN_ARRAY);
} else {
final double[] row = new double[ROW_LEN];
for (int j = 0; j < ROW_LEN; ++j) {
row[j] = typedSource.get(lenRead + j);
}
lenRead += ROW_LEN;
final double[] row = new double[rowLen];
typedSource.copyToArray(lenRead, row,0, rowLen);
lenRead += rowLen;
result.set(outOffset + i, row);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import io.deephaven.chunk.WritableObjectChunk;
import io.deephaven.chunk.attributes.Any;
import io.deephaven.chunk.attributes.ChunkPositions;
import io.deephaven.chunk.sized.SizedFloatChunk;
import io.deephaven.util.datastructures.LongSizedDataStructure;

public class FloatArrayExpansionKernel implements ArrayExpansionKernel {
private final static float[] ZERO_LEN_ARRAY = new float[0];
Expand All @@ -33,24 +33,29 @@ public <T, A extends Any> WritableChunk<A> expand(final ObjectChunk<T, A> source
}

final ObjectChunk<float[], A> typedSource = source.asObjectChunk();
final SizedFloatChunk<A> resultWrapper = new SizedFloatChunk<>();

long totalSize = 0;
for (int i = 0; i < typedSource.size(); ++i) {
final float[] row = typedSource.get(i);
totalSize += row == null ? 0 : row.length;
}
final WritableFloatChunk<A> result = WritableFloatChunk.makeWritableChunk(
LongSizedDataStructure.intSize("ExpansionKernel", totalSize));

int lenWritten = 0;
perElementLengthDest.setSize(source.size() + 1);
for (int i = 0; i < typedSource.size(); ++i) {
final float[] row = typedSource.get(i);
final int len = row == null ? 0 : row.length;
perElementLengthDest.set(i, lenWritten);
final WritableFloatChunk<A> result = resultWrapper.ensureCapacityPreserve(lenWritten + len);
for (int j = 0; j < len; ++j) {
result.set(lenWritten + j, row[j]);
if (row == null) {
continue;
}
lenWritten += len;
result.setSize(lenWritten);
result.copyFromArray(row, 0, lenWritten, row.length);
lenWritten += row.length;
}
perElementLengthDest.set(typedSource.size(), lenWritten);

return resultWrapper.get();
return result;
}

@Override
Expand All @@ -77,15 +82,13 @@ public <T, A extends Any> WritableObjectChunk<T, A> contract(

int lenRead = 0;
for (int i = 0; i < itemsInBatch; ++i) {
final int ROW_LEN = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (ROW_LEN == 0) {
final int rowLen = perElementLengthDest.get(i + 1) - perElementLengthDest.get(i);
if (rowLen == 0) {
result.set(outOffset + i, ZERO_LEN_ARRAY);
} else {
final float[] row = new float[ROW_LEN];
for (int j = 0; j < ROW_LEN; ++j) {
row[j] = typedSource.get(lenRead + j);
}
lenRead += ROW_LEN;
final float[] row = new float[rowLen];
typedSource.copyToArray(lenRead, row,0, rowLen);
lenRead += rowLen;
result.set(outOffset + i, row);
}
}
Expand Down
Loading

0 comments on commit e932fac

Please sign in to comment.