Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -229,44 +229,120 @@ public static long calculateMaxPageEstimatedMemoryUsageInBytesWithBatchData(

public static List<Long> calculatePageEstimatedMemoryUsageInBytesWithBatchDataList(
final Chunk timeChunk, final List<Chunk> valueChunkList) throws IOException {
final ByteBuffer timeChunkDataBuffer = timeChunk.getData().duplicate();
final List<ByteBuffer> valueChunkDataBufferList = new ArrayList<>(valueChunkList.size());
final PageMemoryUsageEstimator estimator = new PageMemoryUsageEstimator(timeChunk);
for (final Chunk valueChunk : valueChunkList) {
valueChunkDataBufferList.add(
Objects.isNull(valueChunk) ? null : valueChunk.getData().duplicate());
estimator.addValueChunk(valueChunk);
}
return estimator.getPageEstimatedMemoryUsageInBytesList();
}

final List<Long> pageEstimatedMemoryUsageInBytesList = new ArrayList<>();
while (timeChunkDataBuffer.remaining() > 0) {
long pageUncompressedSizeInBytes = 0;
final PageHeader timePageHeader =
SinglePageWholeChunkReader.deserializePageHeader(
timeChunkDataBuffer, timeChunk.getHeader());
pageUncompressedSizeInBytes += timePageHeader.getUncompressedSize();
SinglePageWholeChunkReader.skipCompressedPageData(timeChunkDataBuffer, timePageHeader);

final List<TSDataType> valueDataTypeList = new ArrayList<>(valueChunkList.size());
for (int i = 0; i < valueChunkList.size(); ++i) {
final Chunk valueChunk = valueChunkList.get(i);
final ByteBuffer valueChunkDataBuffer = valueChunkDataBufferList.get(i);
if (Objects.isNull(valueChunk) || Objects.isNull(valueChunkDataBuffer)) {
valueDataTypeList.add(null);
continue;
}
static final class PageMemoryUsageEstimator {

final PageHeader valuePageHeader =
private final List<Long> pageUncompressedSizeInBytesList = new ArrayList<>();
private final List<Integer> pageRowCountList = new ArrayList<>();
private List<Long> pageEstimatedMemoryUsageInBytesList = new ArrayList<>();

private int valueCount;
private TSDataType singleValueDataType;
private long vectorValueMemoryUsageInBytes;

PageMemoryUsageEstimator(final Chunk timeChunk) throws IOException {
final ByteBuffer timeChunkDataBuffer = timeChunk.getData().duplicate();
timeChunkDataBuffer.rewind();
while (timeChunkDataBuffer.remaining() > 0) {
final PageHeader timePageHeader =
SinglePageWholeChunkReader.deserializePageHeader(
valueChunkDataBuffer, valueChunk.getHeader());
pageUncompressedSizeInBytes += valuePageHeader.getUncompressedSize();
valueDataTypeList.add(valueChunk.getHeader().getDataType());
SinglePageWholeChunkReader.skipCompressedPageData(valueChunkDataBuffer, valuePageHeader);
timeChunkDataBuffer, timeChunk.getHeader());
pageUncompressedSizeInBytesList.add((long) timePageHeader.getUncompressedSize());
pageRowCountList.add(SinglePageWholeChunkReader.getPageRowCount(timePageHeader, timeChunk));
SinglePageWholeChunkReader.skipCompressedPageData(timeChunkDataBuffer, timePageHeader);
}
pageEstimatedMemoryUsageInBytesList = calculatePageEstimatedMemoryUsageInBytesList();
}

long calculateMaxPageEstimatedMemoryUsageInBytesWithValueChunk(final Chunk valueChunk)
throws IOException {
final List<Long> pageEstimatedMemoryUsageInBytesList =
calculatePageEstimatedMemoryUsageInBytesList(valueChunk, false);
return pageEstimatedMemoryUsageInBytesList.isEmpty()
? 0
: pageEstimatedMemoryUsageInBytesList.get(0);
}

void addValueChunk(final Chunk valueChunk) throws IOException {
pageEstimatedMemoryUsageInBytesList =
calculatePageEstimatedMemoryUsageInBytesList(valueChunk, true);
}

List<Long> getPageEstimatedMemoryUsageInBytesList() {
return pageEstimatedMemoryUsageInBytesList;
}

private List<Long> calculatePageEstimatedMemoryUsageInBytesList() {
final List<Long> pageEstimatedMemoryUsageInBytesList =
new ArrayList<>(pageUncompressedSizeInBytesList.size());
for (int i = 0; i < pageUncompressedSizeInBytesList.size(); ++i) {
pageEstimatedMemoryUsageInBytesList.add(
SinglePageWholeChunkReader.estimatePageMemoryUsageInBytesWithBatchData(
pageUncompressedSizeInBytesList.get(i),
pageRowCountList.get(i),
valueCount,
singleValueDataType,
vectorValueMemoryUsageInBytes));
}
pageEstimatedMemoryUsageInBytesList.add(
SinglePageWholeChunkReader.estimatePageMemoryUsageInBytesWithBatchData(
pageUncompressedSizeInBytes,
SinglePageWholeChunkReader.getPageRowCount(timePageHeader, timeChunk),
valueDataTypeList));
return SinglePageWholeChunkReader.toSuffixMaxList(pageEstimatedMemoryUsageInBytesList);
}

private List<Long> calculatePageEstimatedMemoryUsageInBytesList(
final Chunk valueChunk, final boolean commit) throws IOException {
final ByteBuffer valueChunkDataBuffer;
final TSDataType valueDataType;
if (Objects.isNull(valueChunk)) {
valueChunkDataBuffer = null;
valueDataType = null;
} else {
valueChunkDataBuffer = valueChunk.getData().duplicate();
valueChunkDataBuffer.rewind();
valueDataType = valueChunk.getHeader().getDataType();
}

final int newValueCount = valueCount + 1;
final TSDataType newSingleValueDataType = valueCount == 0 ? valueDataType : null;
final long newVectorValueMemoryUsageInBytes =
vectorValueMemoryUsageInBytes
+ SinglePageWholeChunkReader.estimateVectorValueMemoryUsageInBytes(valueDataType);
final List<Long> newPageUncompressedSizeInBytesList =
new ArrayList<>(pageUncompressedSizeInBytesList);
final List<Long> pageEstimatedMemoryUsageInBytesList =
new ArrayList<>(pageUncompressedSizeInBytesList.size());

for (int i = 0; i < newPageUncompressedSizeInBytesList.size(); ++i) {
if (Objects.nonNull(valueChunkDataBuffer)) {
final PageHeader valuePageHeader =
SinglePageWholeChunkReader.deserializePageHeader(
valueChunkDataBuffer, valueChunk.getHeader());
newPageUncompressedSizeInBytesList.set(
i, newPageUncompressedSizeInBytesList.get(i) + valuePageHeader.getUncompressedSize());
SinglePageWholeChunkReader.skipCompressedPageData(valueChunkDataBuffer, valuePageHeader);
}
pageEstimatedMemoryUsageInBytesList.add(
SinglePageWholeChunkReader.estimatePageMemoryUsageInBytesWithBatchData(
newPageUncompressedSizeInBytesList.get(i),
pageRowCountList.get(i),
newValueCount,
newSingleValueDataType,
newVectorValueMemoryUsageInBytes));
}

if (commit) {
pageUncompressedSizeInBytesList.clear();
pageUncompressedSizeInBytesList.addAll(newPageUncompressedSizeInBytesList);
valueCount = newValueCount;
singleValueDataType = newSingleValueDataType;
vectorValueMemoryUsageInBytes = newVectorValueMemoryUsageInBytes;
}

return SinglePageWholeChunkReader.toSuffixMaxList(pageEstimatedMemoryUsageInBytesList);
}
return SinglePageWholeChunkReader.toSuffixMaxList(pageEstimatedMemoryUsageInBytesList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ static int getPageRowCount(final PageHeader pageHeader, final Chunk chunk) throw

private static int countSinglePageTimeValues(final Chunk chunk) throws IOException {
final ByteBuffer chunkDataBuffer = chunk.getData().duplicate();
chunkDataBuffer.rewind();
final PageHeader pageHeader = deserializePageHeader(chunkDataBuffer, chunk.getHeader());
final ByteBuffer pageData =
deserializePageData(
Expand Down Expand Up @@ -222,25 +223,42 @@ static long estimatePageMemoryUsageInBytesWithBatchData(
final long pageUncompressedSizeInBytes,
final int rowCount,
final List<TSDataType> valueDataTypeList) {
final int valueCount = valueDataTypeList.size();
return estimatePageMemoryUsageInBytesWithBatchData(
pageUncompressedSizeInBytes,
rowCount,
valueCount,
valueCount == 1 ? valueDataTypeList.get(0) : null,
estimateVectorValueMemoryUsageInBytes(valueDataTypeList));
}

static long estimatePageMemoryUsageInBytesWithBatchData(
final long pageUncompressedSizeInBytes,
final int rowCount,
final int valueCount,
final TSDataType singleValueDataType,
final long vectorValueMemoryUsageInBytes) {
return pageUncompressedSizeInBytes
+ estimateBatchDataMemoryUsageInBytes(rowCount, valueDataTypeList);
+ estimateBatchDataMemoryUsageInBytes(
rowCount, valueCount, singleValueDataType, vectorValueMemoryUsageInBytes);
}

private static long estimateBatchDataMemoryUsageInBytes(
final int rowCount, final List<TSDataType> valueDataTypeList) {
final int valueCount = valueDataTypeList.size();
final int rowCount,
final int valueCount,
final TSDataType singleValueDataType,
final long vectorValueMemoryUsageInBytes) {
final long segmentCount = Math.max(1, (rowCount + 15L) / 16);
long estimatedMemoryUsageInBytes = RamUsageEstimator.sizeOfLongArray(16) * segmentCount;

if (valueCount == 1) {
estimatedMemoryUsageInBytes +=
estimateSingleValueArrayMemoryUsageInBytes(rowCount, valueDataTypeList.get(0));
estimateSingleValueArrayMemoryUsageInBytes(rowCount, singleValueDataType);
} else if (valueCount > 1) {
estimatedMemoryUsageInBytes += RamUsageEstimator.sizeOfObjectArray(16) * segmentCount;
estimatedMemoryUsageInBytes +=
(long) rowCount
* (RamUsageEstimator.sizeOfObjectArray(valueCount)
+ estimateVectorValueMemoryUsageInBytes(valueDataTypeList));
* (RamUsageEstimator.sizeOfObjectArray(valueCount) + vectorValueMemoryUsageInBytes);
}

return estimatedMemoryUsageInBytes;
Expand All @@ -260,18 +278,21 @@ private static long estimateVectorValueMemoryUsageInBytes(
final List<TSDataType> valueDataTypeList) {
long estimatedMemoryUsageInBytes = 0;
for (final TSDataType dataType : valueDataTypeList) {
if (Objects.isNull(dataType)) {
continue;
}

estimatedMemoryUsageInBytes +=
RamUsageEstimator.alignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
+ estimateTsPrimitiveTypeValueMemoryUsageInBytes(dataType));
estimatedMemoryUsageInBytes += estimateVectorValueMemoryUsageInBytes(dataType);
}
return estimatedMemoryUsageInBytes;
}

static long estimateVectorValueMemoryUsageInBytes(final TSDataType dataType) {
if (Objects.isNull(dataType)) {
return 0;
}

return RamUsageEstimator.alignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
+ estimateTsPrimitiveTypeValueMemoryUsageInBytes(dataType));
}

private static long estimateTsPrimitiveTypeValueMemoryUsageInBytes(final TSDataType dataType) {
return Type.fromTsDataType(dataType).estimateValueSize();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -893,9 +892,8 @@ private boolean useNextPendingAlignedChunk(final byte marker) throws IOException
}
final List<Long> pageEstimatedMemoryUsageInBytesList =
nextIsMultiPage
? AlignedSinglePageWholeChunkReader
.calculatePageEstimatedMemoryUsageInBytesWithBatchDataList(
timeChunk, pendingAlignedChunkGroup.valueChunkList)
? pendingAlignedChunkGroup.pageMemoryUsageEstimator
.getPageEstimatedMemoryUsageInBytesList()
: Collections.emptyList();
final long maxPageEstimatedMemoryUsageInBytes =
pageEstimatedMemoryUsageInBytesList.isEmpty()
Expand Down Expand Up @@ -996,6 +994,7 @@ private void cacheAlignedValueChunk(final CachedAlignedValueChunk valueChunk) th
resizeChunkMemoryBlockIfFirstValueChunkExceedsLimit(pendingAlignedChunkGroup, valueChunk);
resizePageDataMemoryBlockIfFirstValueChunkExceedsLimit(pendingAlignedChunkGroup, valueChunk);

pendingAlignedChunkGroup.pageMemoryUsageEstimator.addValueChunk(valueChunk.chunk);
pendingAlignedChunkGroup.valueChunkList.add(valueChunk.chunk);
pendingAlignedChunkGroup.chunkSize += valueChunk.valueChunkSize;
pendingAlignedChunkSize += valueChunk.valueChunkSize;
Expand All @@ -1013,7 +1012,8 @@ private void cacheAlignedValueChunk(final CachedAlignedValueChunk valueChunk) th
currentDevice, Collections.singletonList(measurementID), currentModifications, false));
}

private PendingAlignedChunkGroup getOrCreatePendingAlignedChunkGroup(final int timeChunkIndex) {
private PendingAlignedChunkGroup getOrCreatePendingAlignedChunkGroup(final int timeChunkIndex)
throws IOException {
final PendingAlignedChunkGroup pendingAlignedChunkGroup =
findPendingAlignedChunkGroup(timeChunkIndex);
if (Objects.nonNull(pendingAlignedChunkGroup)) {
Expand All @@ -1023,7 +1023,8 @@ private PendingAlignedChunkGroup getOrCreatePendingAlignedChunkGroup(final int t
final PendingAlignedChunkGroup newPendingAlignedChunkGroup =
new PendingAlignedChunkGroup(
timeChunkIndex,
PipeMemoryWeightUtil.calculateChunkRamBytesUsed(timeChunkList.get(timeChunkIndex)));
PipeMemoryWeightUtil.calculateChunkRamBytesUsed(timeChunkList.get(timeChunkIndex)),
timeChunkList.get(timeChunkIndex));
pendingAlignedChunkSize += newPendingAlignedChunkGroup.chunkSize;

for (int i = 0; i < pendingAlignedChunkGroups.size(); ++i) {
Expand Down Expand Up @@ -1099,49 +1100,12 @@ private long calculateMaxAlignedPageMemorySizeWithBatchData(
final PendingAlignedChunkGroup pendingAlignedChunkGroup,
final CachedAlignedValueChunk valueChunk)
throws IOException {
final List<Chunk> valueChunkList =
new ArrayList<>(
(Objects.isNull(pendingAlignedChunkGroup)
? 0
: pendingAlignedChunkGroup.valueChunkList.size())
+ 1);
if (Objects.nonNull(pendingAlignedChunkGroup)) {
valueChunkList.addAll(pendingAlignedChunkGroup.valueChunkList);
}
valueChunkList.add(valueChunk.chunk);

final Chunk timeChunk = timeChunkList.get(timeChunkIndex);
final int timeChunkDataPosition = timeChunk.getData().position();
final List<Integer> valueChunkDataPositions = new ArrayList<>(valueChunkList.size());
for (final Chunk chunk : valueChunkList) {
valueChunkDataPositions.add(Objects.isNull(chunk) ? 0 : chunk.getData().position());
}

rewindChunkData(timeChunk);
valueChunkList.forEach(this::rewindChunkData);
try {
return AlignedSinglePageWholeChunkReader
.calculateMaxPageEstimatedMemoryUsageInBytesWithBatchData(timeChunk, valueChunkList);
} finally {
timeChunk.getData().position(timeChunkDataPosition);
for (int i = 0; i < valueChunkList.size(); ++i) {
final Chunk chunk = valueChunkList.get(i);
if (Objects.nonNull(chunk)) {
chunk.getData().position(valueChunkDataPositions.get(i));
}
}
}
}

private void rewindChunkData(final Chunk chunk) {
if (Objects.isNull(chunk)) {
return;
}

final ByteBuffer chunkData = chunk.getData();
if (Objects.nonNull(chunkData)) {
chunkData.rewind();
}
final AlignedSinglePageWholeChunkReader.PageMemoryUsageEstimator estimator =
Objects.isNull(pendingAlignedChunkGroup)
? new AlignedSinglePageWholeChunkReader.PageMemoryUsageEstimator(timeChunk)
: pendingAlignedChunkGroup.pageMemoryUsageEstimator;
return estimator.calculateMaxPageEstimatedMemoryUsageInBytesWithValueChunk(valueChunk.chunk);
}

private boolean isSinglePageValueChunk(final ChunkHeader chunkHeader) {
Expand Down Expand Up @@ -1207,14 +1171,20 @@ private Statistics findNonAlignedChunkStatistics(
private static class PendingAlignedChunkGroup {

private final int timeChunkIndex;
private final AlignedSinglePageWholeChunkReader.PageMemoryUsageEstimator
pageMemoryUsageEstimator;
private final List<Chunk> valueChunkList = new ArrayList<>();
private final List<IMeasurementSchema> measurements = new ArrayList<>();
private final List<ModsOperationUtil.ModsInfo> modsInfos = new ArrayList<>();
private long chunkSize;

private PendingAlignedChunkGroup(final int timeChunkIndex, final long timeChunkSize) {
private PendingAlignedChunkGroup(
final int timeChunkIndex, final long timeChunkSize, final Chunk timeChunk)
throws IOException {
this.timeChunkIndex = timeChunkIndex;
this.chunkSize = timeChunkSize;
this.pageMemoryUsageEstimator =
new AlignedSinglePageWholeChunkReader.PageMemoryUsageEstimator(timeChunk);
}
}

Expand Down
Loading
Loading