blob: 99bc78e9148563ae72bb3ae366089ee699938ad5 [file] [log] [blame]
(window.webpackJsonp=window.webpackJsonp||[]).push([[33],{599:function(e,s,t){"use strict";t.r(s);var a=t(68),i=Object(a.a)({},(function(){var e=this,s=e.$createElement,t=e._self._c||s;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"fill-function"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#fill-function"}},[e._v("#")]),e._v(" Fill Function")]),e._v(" "),t("p",[e._v("The main logic of Fill function is in FillQueryExecutor")]),e._v(" "),t("ul",[t("li",[e._v("org.apache.iotdb.db.query.executor.FillQueryExecutor")])]),e._v(" "),t("p",[e._v("Two fill functions are support in IoTDB, Previous Fill and Linear Fill.")]),e._v(" "),t("h1",{attrs:{id:"previous-fill"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#previous-fill"}},[e._v("#")]),e._v(" Previous Fill")]),e._v(" "),t("p",[e._v("The target of Previous Fill is to find out the time-value that has the largest timestamp, which is also smaller or equal to "),t("code",[e._v("queryTime")]),e._v(". The graph below displays one scenario of the function.")]),e._v(" "),t("div",{staticClass:"language- line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v(" |\n+-------------------------+ |\n| seq files | |\n+-------------------------+ |\n |\n +---------------------------+\n | unseq files | |\n +---------------------------+ \n |\n |\n queryTime\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br"),t("span",{staticClass:"line-number"},[e._v("3")]),t("br"),t("span",{staticClass:"line-number"},[e._v("4")]),t("br"),t("span",{staticClass:"line-number"},[e._v("5")]),t("br"),t("span",{staticClass:"line-number"},[e._v("6")]),t("br"),t("span",{staticClass:"line-number"},[e._v("7")]),t("br"),t("span",{staticClass:"line-number"},[e._v("8")]),t("br"),t("span",{staticClass:"line-number"},[e._v("9")]),t("br"),t("span",{staticClass:"line-number"},[e._v("10")]),t("br"),t("span",{staticClass:"line-number"},[e._v("11")]),t("br")])]),t("h2",{attrs:{id:"design-principle"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#design-principle"}},[e._v("#")]),e._v(" Design principle")]),e._v(" "),t("p",[e._v("In the real scenarios, the previous fill result may exist in a single page in tons of TsFiles. To accelerate the search procedure, "),t("strong",[e._v("the key point")]),e._v(" is to filter as many tsFiles out as possible.")]),e._v(" "),t("p",[e._v("The main logic of TsFile filtering work is in "),t("code",[e._v("UnpackOverlappedUnseqFiles()")]),e._v(".")]),e._v(" "),t("h2",{attrs:{id:"find-the-lower-bound-from-all-the-sequential-files"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#find-the-lower-bound-from-all-the-sequential-files"}},[e._v("#")]),e._v(' Find the "lower bound" from all the sequential files')]),e._v(" "),t("p",[e._v('We first find out the "last point" of sequential files that satisfies fill queryTime. Since all the chunk data in sequential files are in decent order, this last point can be easily obtained by '),t("code",[e._v("retrieveValidLastPointFromSeqFiles()")]),e._v(" function.")]),e._v(" "),t("p",[e._v('After the above "last point " is found via '),t("code",[e._v("retrieveValidLastPointFromSeqFiles()")]),e._v(", the timestamp of this last point can be treated as a lower bound in the following searching. Only those points whose timestamps exceeds this lower bound are candidates to become the final result.")]),e._v(" "),t("p",[e._v('In the below example, the unseq file is not qualified to be processed as its end time is before "last point".')]),e._v(" "),t("div",{staticClass:"language- line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v(" last point\n | |\n +---------------------------+\n | seq file | | |\n +---------------------------+ \n +-------------------------+ | |\n | unseq file | | |\n +-------------------------+ | |\n | |\n |\n queryTime\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br"),t("span",{staticClass:"line-number"},[e._v("3")]),t("br"),t("span",{staticClass:"line-number"},[e._v("4")]),t("br"),t("span",{staticClass:"line-number"},[e._v("5")]),t("br"),t("span",{staticClass:"line-number"},[e._v("6")]),t("br"),t("span",{staticClass:"line-number"},[e._v("7")]),t("br"),t("span",{staticClass:"line-number"},[e._v("8")]),t("br"),t("span",{staticClass:"line-number"},[e._v("9")]),t("br"),t("span",{staticClass:"line-number"},[e._v("10")]),t("br"),t("span",{staticClass:"line-number"},[e._v("11")]),t("br")])]),t("h2",{attrs:{id:"filter-unseq-files-with-lower-bound"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#filter-unseq-files-with-lower-bound"}},[e._v("#")]),e._v(" Filter unseq files with lower bound")]),e._v(" "),t("p",[e._v("The selecting of unseq files is in method "),t("code",[e._v("UnpackOverlappedUnseqFiles(long lBoundTime)")]),e._v(". All the unseq files are filtered by the parameter "),t("code",[e._v("lBoundTime")]),e._v(", and unpacked into Timeseries Metadata. We cache all the "),t("code",[e._v("TimeseriesMetadata")]),e._v(" into "),t("code",[e._v("unseqTimeseriesMetadataList")]),e._v(".")]),e._v(" "),t("p",[e._v("Firstly the method selects the last unseq file that satisfies timeFilter. Its end time must be larger than "),t("code",[e._v("lBoundTime")]),e._v(", otherwise this file will be skipped. It is guaranteed that the rest files will cross the queryTime line, that is startTime <= queryTime and queryTime <= endTime. Then we can update the "),t("code",[e._v("lBoundTime")]),e._v(" with the start time of the unpacked "),t("code",[e._v("TimeseriesMetadata")]),e._v(".")]),e._v(" "),t("p",[e._v("In the below graph, the "),t("code",[e._v("lBoundTime")]),e._v(" is updated with start time of unseq file in case1, and not updated in case2.")]),e._v(" "),t("div",{staticClass:"language- line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("case1 case2\n | | |\n | +---------------------------+\n | | | unseq file | |\n | +---------------------------+ \n | | |\n | | |\nlBoundTime lBoundTime queryTime\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br"),t("span",{staticClass:"line-number"},[e._v("3")]),t("br"),t("span",{staticClass:"line-number"},[e._v("4")]),t("br"),t("span",{staticClass:"line-number"},[e._v("5")]),t("br"),t("span",{staticClass:"line-number"},[e._v("6")]),t("br"),t("span",{staticClass:"line-number"},[e._v("7")]),t("br"),t("span",{staticClass:"line-number"},[e._v("8")]),t("br")])]),t("div",{staticClass:"language- line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("while (!unseqFileResource.isEmpty()) {\n // The very end time of unseq files is smaller than lBoundTime,\n // then skip all the rest unseq files\n if (unseqFileResource.peek().getEndTimeMap().get(seriesPath.getDevice()) < lBoundTime) {\n return;\n }\n TimeseriesMetadata timeseriesMetadata =\n FileLoaderUtils.loadTimeSeriesMetadata(\n unseqFileResource.poll(), seriesPath, context, timeFilter, allSensors);\n if (timeseriesMetadata != null && timeseriesMetadata.getStatistics().canUseStatistics()\n && lBoundTime <= timeseriesMetadata.getStatistics().getEndTime()) {\n lBoundTime = Math.max(lBoundTime, timeseriesMetadata.getStatistics().getStartTime());\n unseqTimeseriesMetadataList.add(timeseriesMetadata);\n break;\n }\n}\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br"),t("span",{staticClass:"line-number"},[e._v("3")]),t("br"),t("span",{staticClass:"line-number"},[e._v("4")]),t("br"),t("span",{staticClass:"line-number"},[e._v("5")]),t("br"),t("span",{staticClass:"line-number"},[e._v("6")]),t("br"),t("span",{staticClass:"line-number"},[e._v("7")]),t("br"),t("span",{staticClass:"line-number"},[e._v("8")]),t("br"),t("span",{staticClass:"line-number"},[e._v("9")]),t("br"),t("span",{staticClass:"line-number"},[e._v("10")]),t("br"),t("span",{staticClass:"line-number"},[e._v("11")]),t("br"),t("span",{staticClass:"line-number"},[e._v("12")]),t("br"),t("span",{staticClass:"line-number"},[e._v("13")]),t("br"),t("span",{staticClass:"line-number"},[e._v("14")]),t("br"),t("span",{staticClass:"line-number"},[e._v("15")]),t("br"),t("span",{staticClass:"line-number"},[e._v("16")]),t("br")])]),t("p",[e._v("Next, the selected Timeseries Metadata could be used to find all the other overlapped unseq files. It should be noted that each time when a overlapped unseq file is added, the "),t("code",[e._v("lBoundTime")]),e._v(" could be updated if the end time of this file satisfies "),t("code",[e._v("queryTime")])]),e._v(" "),t("div",{staticClass:"language- line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("while (!unseqFileResource.isEmpty()\n && (lBoundTime <= unseqFileResource.peek().getEndTimeMap().get(seriesPath.getDevice()))) {\n TimeseriesMetadata timeseriesMetadata =\n FileLoaderUtils.loadTimeSeriesMetadata(\n unseqFileResource.poll(), seriesPath, context, timeFilter, allSensors);\n unseqTimeseriesMetadataList.add(timeseriesMetadata);\n // update lBoundTime if current unseq timeseriesMetadata's last point is a valid result\n if (timeseriesMetadata.getStatistics().canUseStatistics()\n && endtimeContainedByTimeFilter(timeseriesMetadata.getStatistics())) {\n lBoundTime = Math.max(lBoundTime, timeseriesMetadata.getStatistics().getEndTime());\n }\n}\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br"),t("span",{staticClass:"line-number"},[e._v("3")]),t("br"),t("span",{staticClass:"line-number"},[e._v("4")]),t("br"),t("span",{staticClass:"line-number"},[e._v("5")]),t("br"),t("span",{staticClass:"line-number"},[e._v("6")]),t("br"),t("span",{staticClass:"line-number"},[e._v("7")]),t("br"),t("span",{staticClass:"line-number"},[e._v("8")]),t("br"),t("span",{staticClass:"line-number"},[e._v("9")]),t("br"),t("span",{staticClass:"line-number"},[e._v("10")]),t("br"),t("span",{staticClass:"line-number"},[e._v("11")]),t("br"),t("span",{staticClass:"line-number"},[e._v("12")]),t("br")])]),t("h2",{attrs:{id:"compose-the-previous-fill-result"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#compose-the-previous-fill-result"}},[e._v("#")]),e._v(" Compose the Previous Fill result")]),e._v(" "),t("p",[e._v("The method "),t("code",[e._v("getFillResult()")]),e._v(" will search among the sequential and un-sequential file to find the result. When searching in a chunk or a page, the statistic data should be utilized first.")]),e._v(" "),t("div",{staticClass:"language- line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("public TimeValuePair getFillResult() throws IOException {\n TimeValuePair lastPointResult = retrieveValidLastPointFromSeqFiles();\n UnpackOverlappedUnseqFiles(lastPointResult.getTimestamp());\n \n long lastVersion = 0;\n PriorityQueue<ChunkMetadata> sortedChunkMetatdataList = sortUnseqChunkMetadatasByEndtime();\n while (!sortedChunkMetatdataList.isEmpty()\n && lastPointResult.getTimestamp() <= sortedChunkMetatdataList.peek().getEndTime()) {\n ChunkMetadata chunkMetadata = sortedChunkMetatdataList.poll();\n TimeValuePair lastChunkPoint = getChunkLastPoint(chunkMetadata);\n if (shouldUpdate(lastPointResult.getTimestamp(), lastVersion,\n lastChunkPoint.getTimestamp(), chunkMetadata.getVersion())) {\n lastPointResult = lastChunkPoint;\n lastVersion = chunkMetadata.getVersion();\n }\n }\n return lastPointResult;\n}\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br"),t("span",{staticClass:"line-number"},[e._v("3")]),t("br"),t("span",{staticClass:"line-number"},[e._v("4")]),t("br"),t("span",{staticClass:"line-number"},[e._v("5")]),t("br"),t("span",{staticClass:"line-number"},[e._v("6")]),t("br"),t("span",{staticClass:"line-number"},[e._v("7")]),t("br"),t("span",{staticClass:"line-number"},[e._v("8")]),t("br"),t("span",{staticClass:"line-number"},[e._v("9")]),t("br"),t("span",{staticClass:"line-number"},[e._v("10")]),t("br"),t("span",{staticClass:"line-number"},[e._v("11")]),t("br"),t("span",{staticClass:"line-number"},[e._v("12")]),t("br"),t("span",{staticClass:"line-number"},[e._v("13")]),t("br"),t("span",{staticClass:"line-number"},[e._v("14")]),t("br"),t("span",{staticClass:"line-number"},[e._v("15")]),t("br"),t("span",{staticClass:"line-number"},[e._v("16")]),t("br"),t("span",{staticClass:"line-number"},[e._v("17")]),t("br"),t("span",{staticClass:"line-number"},[e._v("18")]),t("br")])]),t("h1",{attrs:{id:"linear-fill"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#linear-fill"}},[e._v("#")]),e._v(" Linear Fill")]),e._v(" "),t("p",[e._v('The result of Linear Fill functions at timestamp "T" is calculated by performing a linear fitting method on two timeseries values, one is at the closest timestamp before T, and the other is at the closest timestamp after T. Linear Fill function calculation only supports numeric types including int, double and float.')]),e._v(" "),t("h2",{attrs:{id:"calculating-before-timestamp-value"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#calculating-before-timestamp-value"}},[e._v("#")]),e._v(" Calculating before timestamp value")]),e._v(" "),t("p",[e._v("Before timestamp value is calculated in the same way with Previous Fill.")]),e._v(" "),t("h2",{attrs:{id:"calculating-after-timestamp-value"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#calculating-after-timestamp-value"}},[e._v("#")]),e._v(" Calculating after timestamp value")]),e._v(" "),t("p",[e._v('For after timestamp value, the time-value pair is generated by two aggregation querys "MIN_TIME" and "FIRST_VALUE". '),t("code",[e._v("AggregationExecutor.aggregateOneSeries()")]),e._v(" is used to calculate these two aggregation results and compose a time-value pair.")])])}),[],!1,null,null,null);s.default=i.exports}}]);