This is an automated email from the ASF dual-hosted git repository. hui pushed a commit to branch lmh/extendFilter in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit fdba22f3b32761cca0102d50dfa23a977db148c3 Author: Minghui Liu <[email protected]> AuthorDate: Tue Dec 5 10:37:35 2023 +0800 finish IMetadata interface --- .../operator/source/AlignedSeriesScanUtil.java | 61 ++++++++++------------ .../read/reader/chunk/MemAlignedPageReader.java | 13 +++-- .../read/reader/chunk/MemPageReader.java | 37 +++++++------ .../tsfile/file/metadata/AlignedChunkMetadata.java | 32 ++++++++++-- .../file/metadata/AlignedTimeSeriesMetadata.java | 25 +++++++++ .../iotdb/tsfile/file/metadata/ChunkMetadata.java | 11 ++-- .../iotdb/tsfile/file/metadata/IChunkMetadata.java | 2 - .../iotdb/tsfile/file/metadata/IMetadata.java | 38 ++++---------- .../tsfile/file/metadata/ITimeSeriesMetadata.java | 1 - .../tsfile/file/metadata/TimeseriesMetadata.java | 14 +++-- .../iotdb/tsfile/read/reader/IPageReader.java | 2 - .../tsfile/read/reader/page/AlignedPageReader.java | 25 ++++++++- .../iotdb/tsfile/read/reader/page/PageReader.java | 43 +++++++++------ 13 files changed, 188 insertions(+), 116 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/AlignedSeriesScanUtil.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/AlignedSeriesScanUtil.java index 686ee690c1f..1f6c270c6c9 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/AlignedSeriesScanUtil.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/AlignedSeriesScanUtil.java @@ -173,34 +173,30 @@ public class AlignedSeriesScanUtil extends SeriesScanUtil { } } - @SuppressWarnings("squid:S3740") private void skipOffsetByTimeSeriesMetadata() { - // For aligned series, When we only query some measurements under an aligned device, if any - // values of these queried measurements has the same value count as the time column, the - // timestamp will be selected. - // NOTE: if we change the query semantic in the future for aligned series, we need to remove - // this check here. - boolean canUse = - queryAllSensors - || ((AlignedTimeSeriesMetadata) firstTimeSeriesMetadata).getMeasurementCount() == 0; - if (!canUse && (((AlignedTimeSeriesMetadata) firstTimeSeriesMetadata).timeAllSelected())) { - canUse = true; - } - - if (!canUse) { + if (!canSkipOffsetByTimeSeriesMetadata((AlignedTimeSeriesMetadata) firstTimeSeriesMetadata)) { return; } - // When the number of points in all value chunk groups is the same as that in the time chunk - // group, it means that there is no null value, and all timestamps will be selected. - long rowCount = - ((AlignedTimeSeriesMetadata) firstTimeSeriesMetadata).getTimeStatistics().getCount(); + long rowCount = firstTimeSeriesMetadata.getTimeStatistics().getCount(); if (paginationController.hasCurOffset(rowCount)) { skipCurrentFile(); paginationController.consumeOffset(rowCount); } } + private boolean canSkipOffsetByTimeSeriesMetadata( + AlignedTimeSeriesMetadata alignedTimeSeriesMetadata) { + if (queryAllSensors || alignedTimeSeriesMetadata.getMeasurementCount() == 0) { + return true; + } + + // For aligned series, we can use statistics to skip OFFSET only when all times are selected. + // NOTE: if we change the query semantic in the future for aligned series, we need to remove + // this check here. + return alignedTimeSeriesMetadata.timeAllSelected(); + } + @Override protected void filterFirstChunkMetadata() throws IOException { if (firstChunkMetadata != null && !isChunkOverlapped() && !firstChunkMetadata.isModified()) { @@ -214,27 +210,26 @@ public class AlignedSeriesScanUtil extends SeriesScanUtil { } } - @SuppressWarnings("squid:S3740") private void skipOffsetByChunkMetadata() { - // For aligned series, When we only query some measurements under an aligned device, if any - // values of these queried measurements has the same value count as the time column, the - // timestamp will be selected. - // NOTE: if we change the query semantic in the future for aligned series, we need to remove - // this check here. - long rowCount = firstChunkMetadata.getStatistics().getCount(); - boolean canUse = - queryAllSensors || ((AlignedChunkMetadata) firstChunkMetadata).getMeasurementCount() == 0; - if (!canUse && (((AlignedChunkMetadata) firstChunkMetadata).timeAllSelected())) { - canUse = true; - } - if (!canUse) { + if (!canSkipOffsetByChunkMetadata((AlignedChunkMetadata) firstChunkMetadata)) { return; } - // When the number of points in all value chunks is the same as that in the time chunk, it - // means that there is no null value, and all timestamps will be selected. + + long rowCount = firstChunkMetadata.getStatistics().getCount(); if (paginationController.hasCurOffset(rowCount)) { skipCurrentChunk(); paginationController.consumeOffset(rowCount); } } + + private boolean canSkipOffsetByChunkMetadata(AlignedChunkMetadata alignedChunkMetadata) { + if (queryAllSensors || alignedChunkMetadata.getMeasurementCount() == 0) { + return true; + } + + // For aligned series, we can use statistics to skip OFFSET only when all times are selected. + // NOTE: if we change the query semantic in the future for aligned series, we need to remove + // this check here. + return alignedChunkMetadata.timeAllSelected(); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/read/reader/chunk/MemAlignedPageReader.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/read/reader/chunk/MemAlignedPageReader.java index 1541cb31604..9f234c10ed2 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/read/reader/chunk/MemAlignedPageReader.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/read/reader/chunk/MemAlignedPageReader.java @@ -125,14 +125,14 @@ public class MemAlignedPageReader implements IPageReader { } private boolean canSkipOffsetByStatistics() { - if (queryAllSensors || getMeasurementCount() == 0) { + if (queryAllSensors || chunkMetadata.getMeasurementCount() == 0) { return true; } // For aligned series, we can use statistics to skip OFFSET only when all times are selected. // NOTE: if we change the query semantic in the future for aligned series, we need to remove // this check here. - return timeAllSelected(); + return chunkMetadata.timeAllSelected(); } @Override @@ -243,8 +243,13 @@ public class MemAlignedPageReader implements IPageReader { } @Override - public int getMeasurementCount() { - return chunkMetadata.getMeasurementCount(); + public boolean hasNullValue(int measurementIndex) { + return chunkMetadata.hasNullValue(measurementIndex); + } + + @Override + public boolean isAllNulls(int measurementIndex) { + return chunkMetadata.isAllNulls(measurementIndex); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/read/reader/chunk/MemPageReader.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/read/reader/chunk/MemPageReader.java index bb600b03421..a4764261549 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/read/reader/chunk/MemPageReader.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/read/reader/chunk/MemPageReader.java @@ -329,6 +329,27 @@ public class MemPageReader implements IPageReader { return chunkMetadata.getStatistics(); } + @Override + public Statistics<? extends Serializable> getTimeStatistics() { + return chunkMetadata.getTimeStatistics(); + } + + @Override + public Optional<Statistics<? extends Serializable>> getMeasurementStatistics( + int measurementIndex) { + return chunkMetadata.getMeasurementStatistics(measurementIndex); + } + + @Override + public boolean hasNullValue(int measurementIndex) { + return chunkMetadata.hasNullValue(measurementIndex); + } + + @Override + public boolean isAllNulls(int measurementIndex) { + return chunkMetadata.isAllNulls(measurementIndex); + } + @Override public void setFilter(Filter filter) { if (valueFilter == null) { @@ -352,20 +373,4 @@ public class MemPageReader implements IPageReader { public void initTsBlockBuilder(List<TSDataType> dataTypes) { // non-aligned page reader don't need to init TsBlockBuilder at the very beginning } - - @Override - public Statistics<? extends Serializable> getTimeStatistics() { - return getStatistics(); - } - - @Override - public Optional<Statistics<? extends Serializable>> getMeasurementStatistics( - int measurementIndex) { - return Optional.ofNullable(getStatistics()); - } - - @Override - public int getMeasurementCount() { - return 1; - } } diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedChunkMetadata.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedChunkMetadata.java index 0a724ce785b..ffc8f247610 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedChunkMetadata.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedChunkMetadata.java @@ -26,7 +26,6 @@ import org.apache.iotdb.tsfile.read.controller.IChunkLoader; import java.io.OutputStream; import java.io.Serializable; -import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -47,29 +46,54 @@ public class AlignedChunkMetadata implements IChunkMetadata { } @Override - public <T extends Serializable> Statistics<T> getStatistics() { + public Statistics<? extends Serializable> getStatistics() { return valueChunkMetadataList.size() == 1 && valueChunkMetadataList.get(0) != null ? valueChunkMetadataList.get(0).getStatistics() : timeChunkMetadata.getStatistics(); } @Override - public <T extends Serializable> Statistics<T> getTimeStatistics() { + public Statistics<? extends Serializable> getTimeStatistics() { return timeChunkMetadata.getStatistics(); } @Override - public <T extends Serializable> Optional< Statistics<T>> getMeasurementStatistics( + public Optional<Statistics<? extends Serializable>> getMeasurementStatistics( int measurementIndex) { IChunkMetadata chunkMetadata = valueChunkMetadataList.get(measurementIndex); return Optional.ofNullable(chunkMetadata == null ? null : chunkMetadata.getStatistics()); } @Override + public boolean hasNullValue(int measurementIndex) { + long rowCount = getTimeStatistics().getCount(); + Optional<Statistics<? extends Serializable>> statistics = + getMeasurementStatistics(measurementIndex); + return statistics.map(stat -> stat.hasNullValue(rowCount)).orElse(true); + } + + @Override + public boolean isAllNulls(int measurementIndex) { + Optional<Statistics<? extends Serializable>> statistics = + getMeasurementStatistics(measurementIndex); + return statistics.map(stat -> stat.getCount() == 0).orElse(true); + } + public int getMeasurementCount() { return valueChunkMetadataList.size(); } + public boolean timeAllSelected() { + for (int index = 0; index < getMeasurementCount(); index++) { + if (!hasNullValue(index)) { + // When there is any value page point number that is the same as the time page, + // it means that all timestamps in time page will be selected. + return true; + } + } + return false; + } + @Override public boolean isModified() { return timeChunkMetadata.isModified(); diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedTimeSeriesMetadata.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedTimeSeriesMetadata.java index 33e33ab05b1..de778dcd8b6 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedTimeSeriesMetadata.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/AlignedTimeSeriesMetadata.java @@ -67,10 +67,35 @@ public class AlignedTimeSeriesMetadata implements ITimeSeriesMetadata { } @Override + public boolean hasNullValue(int measurementIndex) { + long rowCount = getTimeStatistics().getCount(); + Optional<Statistics<? extends Serializable>> statistics = + getMeasurementStatistics(measurementIndex); + return statistics.map(stat -> stat.hasNullValue(rowCount)).orElse(true); + } + + @Override + public boolean isAllNulls(int measurementIndex) { + Optional<Statistics<? extends Serializable>> statistics = + getMeasurementStatistics(measurementIndex); + return statistics.map(stat -> stat.getCount() == 0).orElse(true); + } + public int getMeasurementCount() { return valueTimeseriesMetadataList.size(); } + public boolean timeAllSelected() { + for (int index = 0; index < getMeasurementCount(); index++) { + if (!hasNullValue(index)) { + // When there is any value page point number that is the same as the time page, + // it means that all timestamps in time page will be selected. + return true; + } + } + return false; + } + @Override public boolean isModified() { return timeseriesMetadata.isModified(); diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/ChunkMetadata.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/ChunkMetadata.java index 8d39da5aace..e4f56e8ed63 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/ChunkMetadata.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/ChunkMetadata.java @@ -358,12 +358,17 @@ public class ChunkMetadata implements IChunkMetadata { int measurementIndex) { checkArgument( measurementIndex == 0, - "ChunkMetadata only has one measurement, but measurementIndex is %s"); + "Non-aligned chunk only has one measurement, but measurementIndex is " + measurementIndex); return Optional.ofNullable(statistics); } @Override - public int getMeasurementCount() { - return 1; + public boolean hasNullValue(int measurementIndex) { + return false; + } + + @Override + public boolean isAllNulls(int measurementIndex) { + return false; } } diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/IChunkMetadata.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/IChunkMetadata.java index 05621d2a940..43f66b7a326 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/IChunkMetadata.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/IChunkMetadata.java @@ -20,13 +20,11 @@ package org.apache.iotdb.tsfile.file.metadata; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; -import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics; import org.apache.iotdb.tsfile.read.common.TimeRange; import org.apache.iotdb.tsfile.read.controller.IChunkLoader; import java.io.IOException; import java.io.OutputStream; -import java.io.Serializable; import java.util.List; public interface IChunkMetadata extends IMetadata { diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/IMetadata.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/IMetadata.java index c2184353ca1..0bc8c397122 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/IMetadata.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/IMetadata.java @@ -26,33 +26,13 @@ import java.util.Optional; public interface IMetadata { - <T extends Serializable> Statistics<T> getStatistics(); - - <T extends Serializable> Statistics<T> getTimeStatistics(); - - <T extends Serializable> Optional<Statistics<T>> getMeasurementStatistics(int measurementIndex); - - int getMeasurementCount(); - - default boolean hasNullValue(int measurementIndex) { - long rowCount = getTimeStatistics().getCount(); - Optional<Statistics<Serializable>> statistics = - getMeasurementStatistics(measurementIndex); - return statistics.map(stat -> stat.hasNullValue(rowCount)).orElse(true); - } - - default boolean isAllNulls(int measurementIndex) { - return false; - } - - default boolean timeAllSelected() { - for (int index = 0; index < getMeasurementCount(); index++) { - if (!hasNullValue(index)) { - // When there is any value page point number that is the same as the time page, - // it means that all timestamps in time page will be selected. - return true; - } - } - return false; - } + Statistics<? extends Serializable> getStatistics(); + + Statistics<? extends Serializable> getTimeStatistics(); + + Optional<Statistics<? extends Serializable>> getMeasurementStatistics(int measurementIndex); + + boolean hasNullValue(int measurementIndex); + + boolean isAllNulls(int measurementIndex); } diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/ITimeSeriesMetadata.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/ITimeSeriesMetadata.java index 708318ad761..7390fe92332 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/ITimeSeriesMetadata.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/ITimeSeriesMetadata.java @@ -19,7 +19,6 @@ package org.apache.iotdb.tsfile.file.metadata; -import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics; import org.apache.iotdb.tsfile.read.controller.IChunkMetadataLoader; import java.util.List; diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/TimeseriesMetadata.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/TimeseriesMetadata.java index da279f4bf43..608bafeed5e 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/TimeseriesMetadata.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/TimeseriesMetadata.java @@ -238,13 +238,21 @@ public class TimeseriesMetadata implements ITimeSeriesMetadata { @Override public Optional<Statistics<? extends Serializable>> getMeasurementStatistics( int measurementIndex) { - checkArgument(measurementIndex == 0); + checkArgument( + measurementIndex == 0, + "Non-aligned timeseries only has one measurement, but measurementIndex is " + + measurementIndex); return Optional.ofNullable(statistics); } @Override - public int getMeasurementCount() { - return 1; + public boolean hasNullValue(int measurementIndex) { + return false; + } + + @Override + public boolean isAllNulls(int measurementIndex) { + return false; } public void setChunkMetadataLoader(IChunkMetadataLoader chunkMetadataLoader) { diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/IPageReader.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/IPageReader.java index 1ceab56f0a2..46954ed72b3 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/IPageReader.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/IPageReader.java @@ -21,14 +21,12 @@ package org.apache.iotdb.tsfile.read.reader; import org.apache.iotdb.tsfile.file.metadata.IMetadata; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; -import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics; import org.apache.iotdb.tsfile.read.common.BatchData; import org.apache.iotdb.tsfile.read.common.block.TsBlock; import org.apache.iotdb.tsfile.read.filter.basic.Filter; import org.apache.iotdb.tsfile.read.reader.series.PaginationController; import java.io.IOException; -import java.io.Serializable; import java.util.List; public interface IPageReader extends IMetadata { diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/AlignedPageReader.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/AlignedPageReader.java index 139f309c12b..361a1096ef6 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/AlignedPageReader.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/AlignedPageReader.java @@ -155,6 +155,17 @@ public class AlignedPageReader implements IPageReader { return timeAllSelected(); } + private boolean timeAllSelected() { + for (int index = 0; index < valueCount; index++) { + if (!hasNullValue(index)) { + // When there is any value page point number that is the same as the time page, + // it means that all timestamps in time page will be selected. + return true; + } + } + return false; + } + public IPointReader getLazyPointReader() throws IOException { return new LazyLoadAlignedPagePointReader(timePageReader, valuePageReaderList); } @@ -387,8 +398,18 @@ public class AlignedPageReader implements IPageReader { } @Override - public int getMeasurementCount() { - return valueCount; + public boolean hasNullValue(int measurementIndex) { + long rowCount = getTimeStatistics().getCount(); + Optional<Statistics<? extends Serializable>> statistics = + getMeasurementStatistics(measurementIndex); + return statistics.map(stat -> stat.hasNullValue(rowCount)).orElse(true); + } + + @Override + public boolean isAllNulls(int measurementIndex) { + Optional<Statistics<? extends Serializable>> statistics = + getMeasurementStatistics(measurementIndex); + return statistics.map(stat -> stat.getCount() == 0).orElse(true); } private List<Statistics<? extends Serializable>> getValueStatisticsList() { diff --git a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/PageReader.java b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/PageReader.java index 6dbb93a0d7e..28faa6b23d2 100644 --- a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/PageReader.java +++ b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/reader/page/PageReader.java @@ -46,10 +46,11 @@ import java.util.List; import java.util.Optional; import static org.apache.iotdb.tsfile.read.reader.series.PaginationController.UNLIMITED_PAGINATION_CONTROLLER; +import static org.apache.iotdb.tsfile.utils.Preconditions.checkArgument; public class PageReader implements IPageReader { - private PageHeader pageHeader; + private final PageHeader pageHeader; protected TSDataType dataType; @@ -337,6 +338,30 @@ public class PageReader implements IPageReader { return pageHeader.getStatistics(); } + @Override + public Statistics<? extends Serializable> getTimeStatistics() { + return getStatistics(); + } + + @Override + public Optional<Statistics<? extends Serializable>> getMeasurementStatistics( + int measurementIndex) { + checkArgument( + measurementIndex == 0, + "Non-aligned page only has one measurement, but measurementIndex is " + measurementIndex); + return Optional.ofNullable(getStatistics()); + } + + @Override + public boolean hasNullValue(int measurementIndex) { + return false; + } + + @Override + public boolean isAllNulls(int measurementIndex) { + return false; + } + @Override public void setFilter(Filter filter) { if (this.filter == null) { @@ -381,20 +406,4 @@ public class PageReader implements IPageReader { } return false; } - - @Override - public Statistics<? extends Serializable> getTimeStatistics() { - return getStatistics(); - } - - @Override - public Optional<Statistics<? extends Serializable>> getMeasurementStatistics( - int measurementIndex) { - return Optional.ofNullable(getStatistics()); - } - - @Override - public int getMeasurementCount() { - return 1; - } }
