@VisibleForTesting
    static RowGroup createRowGroup(int groupId, long rowsInStripe, long rowsInRowGroup, Map<StreamId, List<RowGroupIndex>> columnIndexes, Map<StreamId, ValueInputStream<?>> valueStreams, Map<StreamId, StreamCheckpoint> checkpoints)
    {
        long totalRowGroupBytes = columnIndexes
                .values()
                .stream()
                .mapToLong(e -> e.get(groupId)
                        .getColumnStatistics()
                        .getTotalValueSizeInBytes())
                .sum();

        long rowOffset = multiplyExact(groupId, rowsInRowGroup);
        int rowCount = toIntExact(Math.min(rowsInStripe - rowOffset, rowsInRowGroup));
        ImmutableMap.Builder<StreamId, InputStreamSource<?>> builder = ImmutableMap.builder();
        for (Entry<StreamId, StreamCheckpoint> entry : checkpoints.entrySet()) {
            StreamId streamId = entry.getKey();
            StreamCheckpoint checkpoint = entry.getValue();

            // skip streams without data
            ValueInputStream<?> valueStream = valueStreams.get(streamId);
            if (valueStream == null) {
                continue;
            }

            builder.put(streamId, createCheckpointStreamSource(valueStream, checkpoint));
        }
        InputStreamSources rowGroupStreams = new InputStreamSources(builder.build());
        return new RowGroup(groupId, rowOffset, rowCount, totalRowGroupBytes, rowGroupStreams);
    }
@Test
    public void testRowSize()
    {
        int numberOfEntries = 10_000;
        long numRowsInGroup = MILLION;
        IntegerStatistics integerStatistics = new IntegerStatistics(0L, 0L, 0L);
        ColumnStatistics intColumnStatistics = new IntegerColumnStatistics(numRowsInGroup, null, null, null, integerStatistics);
        ColumnStatistics mapColumnStatistics = new ColumnStatistics(numRowsInGroup, null, null, null);
        ColumnStatistics mapKeyColumnStatistics = new IntegerColumnStatistics(numRowsInGroup * numberOfEntries, null, null, null, integerStatistics);
        ColumnStatistics mapValueColumnStatistics = new IntegerColumnStatistics(numRowsInGroup * numberOfEntries, null, null, null, integerStatistics);

        StreamId intStreamId = new StreamId(1, 0, Stream.StreamKind.ROW_INDEX);
        StreamId mapStreamId = new StreamId(2, 0, Stream.StreamKind.ROW_INDEX);
        StreamId mapKeyStreamId = new StreamId(3, 0, Stream.StreamKind.ROW_INDEX);
        StreamId mapValueStreamId = new StreamId(4, 0, Stream.StreamKind.ROW_INDEX);

        Map<StreamId, List<RowGroupIndex>> columnIndexes = ImmutableMap.of(intStreamId, createRowGroupIndex(intColumnStatistics),
                mapStreamId, createRowGroupIndex(mapColumnStatistics),
                mapKeyStreamId, createRowGroupIndex(mapKeyColumnStatistics),
                mapValueStreamId, createRowGroupIndex(mapValueColumnStatistics));

        // Each row contains 1 integer, 2 * numberOfEntries * integer (2 is for key and value).
        long expectedRowSize = INTEGER_VALUE_BYTES + 2 * numberOfEntries * INTEGER_VALUE_BYTES;
        RowGroup rowGroup = StripeReader.createRowGroup(0, Long.MAX_VALUE, numRowsInGroup, columnIndexes, ImmutableMap.of(), ImmutableMap.of());
        assertEquals(expectedRowSize, rowGroup.getMinAverageRowBytes());
    }