liutaohua commented on a change in pull request #1731: URL: https://github.com/apache/incubator-iotdb/pull/1731#discussion_r492644306
########## File path: server/src/main/java/org/apache/iotdb/db/metadata/MManager.java ########## @@ -937,12 +937,11 @@ public int getNodesCountInGivenLevel(PartialPath prefixPath, int level) throws M try { Pair<Map<String, String>, Map<String, String>> pair = Review comment: Change to a more meaningful name, like `tagAndAttributePair` ########## File path: server/src/main/java/org/apache/iotdb/db/metadata/MManager.java ########## @@ -1003,18 +1002,13 @@ private boolean match(PartialPath fullPath, String[] prefixNodes) { for (Pair<PartialPath, String[]> ansString : ans) { long tagFileOffset = Long.parseLong(ansString.right[5]); try { - if (tagFileOffset < 0) { - // no tags/attributes - res.add(new ShowTimeSeriesResult(ansString.left.getFullPath(), ansString.right[0], ansString.right[1], ansString.right[2], - ansString.right[3], ansString.right[4], Collections.emptyMap())); - } else { - // has tags/attributes - Pair<Map<String, String>, Map<String, String>> pair = - tagLogFile.read(config.getTagAttributeTotalSize(), tagFileOffset); - pair.left.putAll(pair.right); - res.add(new ShowTimeSeriesResult(ansString.left.getFullPath(), ansString.right[0], ansString.right[1], ansString.right[2], - ansString.right[3], ansString.right[4], pair.left)); + Pair<Map<String, String>, Map<String, String>> pair = new Pair<>(Collections.emptyMap(),Collections.emptyMap()); Review comment: same ########## File path: server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java ########## @@ -566,7 +567,7 @@ private QueryDataSet processShowStorageGroup(ShowStorageGroupPlan showStorageGro private QueryDataSet processShowTimeseries(ShowTimeSeriesPlan showTimeSeriesPlan, QueryContext context) throws MetadataException { List<ShowTimeSeriesResult> timeseriesList = showTimeseries(showTimeSeriesPlan, context); - return QueryUtils.getQueryDataSet(timeseriesList, showTimeSeriesPlan, context); + return new ShowTimeseriesDataSet(showTimeSeriesPlan, context, timeseriesList); } protected List<ShowTimeSeriesResult> showTimeseries(ShowTimeSeriesPlan plan, QueryContext context) Review comment: I think this method can be removed, or move it to `ShowTimeseriesDataSet` ########## File path: server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeseriesDataSet.java ########## @@ -19,44 +19,123 @@ package org.apache.iotdb.db.query.dataset; -import static org.apache.iotdb.db.utils.QueryUtils.transferShowTimeSeriesResultToRecordList; - +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_ATTRIBUTE; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_STORAGE_GROUP; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TAG; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_ALIAS; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_COMPRESSION; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_DATATYPE; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_ENCODING; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.apache.iotdb.db.exception.metadata.MetadataException; import org.apache.iotdb.db.metadata.MManager; import org.apache.iotdb.db.metadata.PartialPath; import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan; import org.apache.iotdb.db.query.context.QueryContext; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; +import org.apache.iotdb.tsfile.read.common.Field; import org.apache.iotdb.tsfile.read.common.Path; import org.apache.iotdb.tsfile.read.common.RowRecord; import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet; +import org.apache.iotdb.tsfile.utils.Binary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ShowTimeseriesDataSet extends QueryDataSet { private static final Logger logger = LoggerFactory.getLogger(ShowTimeseriesDataSet.class); - private final ShowTimeSeriesPlan plan; private List<RowRecord> result = new ArrayList<>(); private int index = 0; private QueryContext context; + private List<ShowTimeSeriesResult> timeseriesList; + private boolean hasSetRecord; public boolean hasLimit = true; - public ShowTimeseriesDataSet(List<PartialPath> paths, List<TSDataType> dataTypes, - ShowTimeSeriesPlan showTimeSeriesPlan, QueryContext context) { - super(new ArrayList<>(paths), dataTypes); + private static Path[] resourcePaths = {new PartialPath(COLUMN_TIMESERIES, false), + new PartialPath(COLUMN_TIMESERIES_ALIAS, false), new PartialPath(COLUMN_STORAGE_GROUP, false), + new PartialPath(COLUMN_TIMESERIES_DATATYPE, false), new PartialPath(COLUMN_TIMESERIES_ENCODING, false), + new PartialPath(COLUMN_TIMESERIES_COMPRESSION, false), new PartialPath(COLUMN_TAG, false), + new PartialPath(COLUMN_ATTRIBUTE, false)}; + private static TSDataType[] resourceTypes = {TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, + TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT}; + + public ShowTimeseriesDataSet(ShowTimeSeriesPlan showTimeSeriesPlan, QueryContext context, + List<ShowTimeSeriesResult> timeseriesList) { + super(Arrays.asList(resourcePaths), Arrays.asList(resourceTypes)); this.plan = showTimeSeriesPlan; this.context = context; + this.timeseriesList = timeseriesList; + this.hasSetRecord = false; + } + + public QueryDataSet getQueryDataSet() { + hasLimit = plan.hasLimit(); Review comment: i think that it can be initialized in the `constructor` ########## File path: server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeseriesDataSet.java ########## @@ -19,44 +19,123 @@ package org.apache.iotdb.db.query.dataset; -import static org.apache.iotdb.db.utils.QueryUtils.transferShowTimeSeriesResultToRecordList; - +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_ATTRIBUTE; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_STORAGE_GROUP; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TAG; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_ALIAS; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_COMPRESSION; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_DATATYPE; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_ENCODING; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.apache.iotdb.db.exception.metadata.MetadataException; import org.apache.iotdb.db.metadata.MManager; import org.apache.iotdb.db.metadata.PartialPath; import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan; import org.apache.iotdb.db.query.context.QueryContext; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; +import org.apache.iotdb.tsfile.read.common.Field; import org.apache.iotdb.tsfile.read.common.Path; import org.apache.iotdb.tsfile.read.common.RowRecord; import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet; +import org.apache.iotdb.tsfile.utils.Binary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ShowTimeseriesDataSet extends QueryDataSet { private static final Logger logger = LoggerFactory.getLogger(ShowTimeseriesDataSet.class); - private final ShowTimeSeriesPlan plan; private List<RowRecord> result = new ArrayList<>(); private int index = 0; private QueryContext context; + private List<ShowTimeSeriesResult> timeseriesList; + private boolean hasSetRecord; public boolean hasLimit = true; - public ShowTimeseriesDataSet(List<PartialPath> paths, List<TSDataType> dataTypes, - ShowTimeSeriesPlan showTimeSeriesPlan, QueryContext context) { - super(new ArrayList<>(paths), dataTypes); + private static Path[] resourcePaths = {new PartialPath(COLUMN_TIMESERIES, false), + new PartialPath(COLUMN_TIMESERIES_ALIAS, false), new PartialPath(COLUMN_STORAGE_GROUP, false), + new PartialPath(COLUMN_TIMESERIES_DATATYPE, false), new PartialPath(COLUMN_TIMESERIES_ENCODING, false), + new PartialPath(COLUMN_TIMESERIES_COMPRESSION, false), new PartialPath(COLUMN_TAG, false), + new PartialPath(COLUMN_ATTRIBUTE, false)}; + private static TSDataType[] resourceTypes = {TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, + TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT}; + + public ShowTimeseriesDataSet(ShowTimeSeriesPlan showTimeSeriesPlan, QueryContext context, + List<ShowTimeSeriesResult> timeseriesList) { + super(Arrays.asList(resourcePaths), Arrays.asList(resourceTypes)); this.plan = showTimeSeriesPlan; this.context = context; + this.timeseriesList = timeseriesList; + this.hasSetRecord = false; + } + + public QueryDataSet getQueryDataSet() { + hasLimit = plan.hasLimit(); + for (ShowTimeSeriesResult result : timeseriesList) { + RowRecord record = new RowRecord(0); Review comment: duplicate code, `transferShowTimeSeriesResultToRecordList` and `getQueryDataSet ` ########## File path: server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeseriesDataSet.java ########## @@ -19,44 +19,123 @@ package org.apache.iotdb.db.query.dataset; -import static org.apache.iotdb.db.utils.QueryUtils.transferShowTimeSeriesResultToRecordList; - +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_ATTRIBUTE; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_STORAGE_GROUP; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TAG; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_ALIAS; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_COMPRESSION; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_DATATYPE; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_ENCODING; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.apache.iotdb.db.exception.metadata.MetadataException; import org.apache.iotdb.db.metadata.MManager; import org.apache.iotdb.db.metadata.PartialPath; import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan; import org.apache.iotdb.db.query.context.QueryContext; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; +import org.apache.iotdb.tsfile.read.common.Field; import org.apache.iotdb.tsfile.read.common.Path; import org.apache.iotdb.tsfile.read.common.RowRecord; import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet; +import org.apache.iotdb.tsfile.utils.Binary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ShowTimeseriesDataSet extends QueryDataSet { private static final Logger logger = LoggerFactory.getLogger(ShowTimeseriesDataSet.class); - private final ShowTimeSeriesPlan plan; private List<RowRecord> result = new ArrayList<>(); private int index = 0; private QueryContext context; + private List<ShowTimeSeriesResult> timeseriesList; + private boolean hasSetRecord; public boolean hasLimit = true; - public ShowTimeseriesDataSet(List<PartialPath> paths, List<TSDataType> dataTypes, - ShowTimeSeriesPlan showTimeSeriesPlan, QueryContext context) { - super(new ArrayList<>(paths), dataTypes); + private static Path[] resourcePaths = {new PartialPath(COLUMN_TIMESERIES, false), + new PartialPath(COLUMN_TIMESERIES_ALIAS, false), new PartialPath(COLUMN_STORAGE_GROUP, false), + new PartialPath(COLUMN_TIMESERIES_DATATYPE, false), new PartialPath(COLUMN_TIMESERIES_ENCODING, false), + new PartialPath(COLUMN_TIMESERIES_COMPRESSION, false), new PartialPath(COLUMN_TAG, false), + new PartialPath(COLUMN_ATTRIBUTE, false)}; + private static TSDataType[] resourceTypes = {TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, + TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT}; + + public ShowTimeseriesDataSet(ShowTimeSeriesPlan showTimeSeriesPlan, QueryContext context, + List<ShowTimeSeriesResult> timeseriesList) { + super(Arrays.asList(resourcePaths), Arrays.asList(resourceTypes)); this.plan = showTimeSeriesPlan; this.context = context; + this.timeseriesList = timeseriesList; + this.hasSetRecord = false; + } + + public QueryDataSet getQueryDataSet() { + hasLimit = plan.hasLimit(); + for (ShowTimeSeriesResult result : timeseriesList) { + RowRecord record = new RowRecord(0); + updateRecord(record, result.getName()); + updateRecord(record, result.getAlias()); + updateRecord(record, result.getSgName()); + updateRecord(record, result.getDataType().toString()); + updateRecord(record, result.getEncoding().toString()); + updateRecord(record, result.getCompressor().toString()); + updateRecord(record, result.getTag()); + updateRecord(record, result.getAttribute()); + putRecord(record); + } + return this; + } + + public List<RowRecord> transferShowTimeSeriesResultToRecordList( + List<ShowTimeSeriesResult> timeseriesList) { + List<RowRecord> records = new ArrayList<>(); + for (ShowTimeSeriesResult result : timeseriesList) { + RowRecord record = new RowRecord(0); + updateRecord(record, result.getName()); + updateRecord(record, result.getAlias()); + updateRecord(record, result.getSgName()); + updateRecord(record, result.getDataType().toString()); + updateRecord(record, result.getEncoding().toString()); + updateRecord(record, result.getCompressor().toString()); + updateRecord(record, result.getTag()); + updateRecord(record, result.getAttribute()); + records.add(record); + } + return records; + } + + private void updateRecord(RowRecord record, Map<String, String> map) { + String text = map.entrySet().stream() + .map(e -> "\"" + e.getKey() + "\"" + ":" + "\"" + e.getValue() + "\"") + .collect(Collectors.joining(",")); + + updateRecord(record, text.length() == 0 ? null : "{" + text + "}"); + } + + private void updateRecord(RowRecord record, String s) { + if (s == null) { + record.addField(null); + return; + } + Field field = new Field(TSDataType.TEXT); + field.setBinaryV(new Binary(s)); + record.addField(field); } @Override protected boolean hasNextWithoutConstraint() throws IOException { + if (!hasSetRecord) { Review comment: i think that this code can be optimizing: 1. Take the data directly from the `MManager` and initialize it in the `constructor` 2. if the total amount of data is less than the `fetchSize`, which means there is no more data, reducing the access to the `MManager`. > when hasLimit = false, limit was means fetchSize 3. if `index == result.size()== fetchSize`, get data from `MManager` again. ########## File path: server/src/main/java/org/apache/iotdb/db/query/dataset/ShowTimeseriesDataSet.java ########## @@ -19,44 +19,123 @@ package org.apache.iotdb.db.query.dataset; -import static org.apache.iotdb.db.utils.QueryUtils.transferShowTimeSeriesResultToRecordList; - +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_ATTRIBUTE; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_STORAGE_GROUP; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TAG; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_ALIAS; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_COMPRESSION; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_DATATYPE; +import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_TIMESERIES_ENCODING; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.apache.iotdb.db.exception.metadata.MetadataException; import org.apache.iotdb.db.metadata.MManager; import org.apache.iotdb.db.metadata.PartialPath; import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan; import org.apache.iotdb.db.query.context.QueryContext; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; +import org.apache.iotdb.tsfile.read.common.Field; import org.apache.iotdb.tsfile.read.common.Path; import org.apache.iotdb.tsfile.read.common.RowRecord; import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet; +import org.apache.iotdb.tsfile.utils.Binary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ShowTimeseriesDataSet extends QueryDataSet { private static final Logger logger = LoggerFactory.getLogger(ShowTimeseriesDataSet.class); - private final ShowTimeSeriesPlan plan; private List<RowRecord> result = new ArrayList<>(); private int index = 0; private QueryContext context; + private List<ShowTimeSeriesResult> timeseriesList; + private boolean hasSetRecord; public boolean hasLimit = true; - public ShowTimeseriesDataSet(List<PartialPath> paths, List<TSDataType> dataTypes, - ShowTimeSeriesPlan showTimeSeriesPlan, QueryContext context) { - super(new ArrayList<>(paths), dataTypes); + private static Path[] resourcePaths = {new PartialPath(COLUMN_TIMESERIES, false), + new PartialPath(COLUMN_TIMESERIES_ALIAS, false), new PartialPath(COLUMN_STORAGE_GROUP, false), + new PartialPath(COLUMN_TIMESERIES_DATATYPE, false), new PartialPath(COLUMN_TIMESERIES_ENCODING, false), + new PartialPath(COLUMN_TIMESERIES_COMPRESSION, false), new PartialPath(COLUMN_TAG, false), + new PartialPath(COLUMN_ATTRIBUTE, false)}; + private static TSDataType[] resourceTypes = {TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, + TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT}; + + public ShowTimeseriesDataSet(ShowTimeSeriesPlan showTimeSeriesPlan, QueryContext context, + List<ShowTimeSeriesResult> timeseriesList) { + super(Arrays.asList(resourcePaths), Arrays.asList(resourceTypes)); this.plan = showTimeSeriesPlan; this.context = context; + this.timeseriesList = timeseriesList; + this.hasSetRecord = false; + } + + public QueryDataSet getQueryDataSet() { + hasLimit = plan.hasLimit(); + for (ShowTimeSeriesResult result : timeseriesList) { + RowRecord record = new RowRecord(0); + updateRecord(record, result.getName()); + updateRecord(record, result.getAlias()); + updateRecord(record, result.getSgName()); + updateRecord(record, result.getDataType().toString()); + updateRecord(record, result.getEncoding().toString()); + updateRecord(record, result.getCompressor().toString()); + updateRecord(record, result.getTag()); + updateRecord(record, result.getAttribute()); + putRecord(record); + } + return this; + } + + public List<RowRecord> transferShowTimeSeriesResultToRecordList( + List<ShowTimeSeriesResult> timeseriesList) { + List<RowRecord> records = new ArrayList<>(); + for (ShowTimeSeriesResult result : timeseriesList) { + RowRecord record = new RowRecord(0); + updateRecord(record, result.getName()); + updateRecord(record, result.getAlias()); + updateRecord(record, result.getSgName()); + updateRecord(record, result.getDataType().toString()); + updateRecord(record, result.getEncoding().toString()); + updateRecord(record, result.getCompressor().toString()); + updateRecord(record, result.getTag()); + updateRecord(record, result.getAttribute()); + records.add(record); + } + return records; + } + + private void updateRecord(RowRecord record, Map<String, String> map) { + String text = map.entrySet().stream() + .map(e -> "\"" + e.getKey() + "\"" + ":" + "\"" + e.getValue() + "\"") + .collect(Collectors.joining(",")); + + updateRecord(record, text.length() == 0 ? null : "{" + text + "}"); + } + + private void updateRecord(RowRecord record, String s) { Review comment: `putRecord` method should also be modified to `private` ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org