From 6022c7a8f247d95bd7fc60cc9e413b4f4753e153 Mon Sep 17 00:00:00 2001 From: Zanna_37 <43404980+zanna-37@users.noreply.github.com> Date: Mon, 7 Nov 2022 01:19:53 +0100 Subject: [PATCH 1/3] docs: better inline documentation for `fetchSingleRange(...)` --- src/cache/Cache.ts | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/cache/Cache.ts b/src/cache/Cache.ts index dcb275e..c2b2c04 100644 --- a/src/cache/Cache.ts +++ b/src/cache/Cache.ts @@ -25,6 +25,42 @@ async function fetchSingleRange( significant_changes_only: boolean, minimal_response: boolean ): Promise { + // We fetch slightly more than requested. The reason is the following: + // When fetching data in a range `[startT,endT]`, Home Assistant adds a fictitious datapoint at + // the start of the fetched period containing a copy of the first datapoint that occurred before + // `startT`, except if there is actually one at `startT`. + // We fetch slightly more than requested (`[startT-1,endT]`) and we mark the datapoint at + // `startT-1` to be deleted (`fake_boundary_datapoint`). When merging the fetched data with the + // cached one, we keep the fictitious datapoint only if it's placed at the start, otherwise it's + // discarded. We don't really know whether the datapoint is fictitious or it's a real datapoint + // that happened to be exactly at `startT-1`, therefore we purposely fetch it outside cached range + // (which is `[startT,endT]`). Since it is not cached by our caching system, it will be requested + // again in following fetches. If it's a real datapoint, it will be returned with new fetches, + // otherwise it won't (which means that it was fictitious). + // + // Examples: + // + // * = fictitious + // + = real + // _ = fetched range + // + // _________ 1st fetch + // * + + + // ^ + // '-- point at the edge, kept + // + // _______ 2nd fetch + // * + * + + + // ^ ^ + // | '--- discarded as it was fictitious + // '--- point at the edge, kept + // + // ________ 3rd fetch + // * + + +* + + + // ^ ^ + // | '--- discarded as it is fictitious + // '--- point at the edge, kept + const start = new Date(startT - 1); endT = Math.min(endT, Date.now()); const end = new Date(endT); @@ -41,13 +77,6 @@ async function fetchSingleRange( ); } - /* - home assistant will "invent" a datapoiont at startT with the previous - known value, except if there is actually one at startT. - To avoid these duplicates, the "fetched range" starts at startT-1, - but the first point is marked to be deleted (fake_boundary_datapoint). - Delettion occurs when merging the fetched range inside the cached history. - */ let range: [number, number] = [startT, endT]; if (history.length) { history[0].fake_boundary_datapoint = true; From 34459145d5a646946e485114d81142b11e2020f8 Mon Sep 17 00:00:00 2001 From: David Buezas Date: Mon, 7 Nov 2022 20:44:24 +0100 Subject: [PATCH 2/3] Expanded docs of the fake_boundary_datapoint logic --- src/cache/Cache.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/cache/Cache.ts b/src/cache/Cache.ts index c2b2c04..efa1156 100644 --- a/src/cache/Cache.ts +++ b/src/cache/Cache.ts @@ -25,18 +25,19 @@ async function fetchSingleRange( significant_changes_only: boolean, minimal_response: boolean ): Promise { - // We fetch slightly more than requested. The reason is the following: + // We fetch slightly more than requested (i.e the range visible in the screen). The reason is the following: // When fetching data in a range `[startT,endT]`, Home Assistant adds a fictitious datapoint at // the start of the fetched period containing a copy of the first datapoint that occurred before // `startT`, except if there is actually one at `startT`. - // We fetch slightly more than requested (`[startT-1,endT]`) and we mark the datapoint at - // `startT-1` to be deleted (`fake_boundary_datapoint`). When merging the fetched data with the - // cached one, we keep the fictitious datapoint only if it's placed at the start, otherwise it's - // discarded. We don't really know whether the datapoint is fictitious or it's a real datapoint - // that happened to be exactly at `startT-1`, therefore we purposely fetch it outside cached range - // (which is `[startT,endT]`). Since it is not cached by our caching system, it will be requested - // again in following fetches. If it's a real datapoint, it will be returned with new fetches, - // otherwise it won't (which means that it was fictitious). + // We fetch slightly more than requested/visible (`[startT-1,endT]`) and we mark the datapoint at + // `startT-1` to be deleted (`fake_boundary_datapoint`). When merging the fetched data into the + // cache, we keep the fictitious datapoint only if it's placed at the start (see `add` function), otherwise it's + // discarded. + // In general, we don't really know whether the datapoint is fictitious or it's a real datapoint + // that happened to be exactly at `startT-1`, therefore we purposely fetch it outside the requested range + // (which is `[startT,endT]`) and we leave it out of the "known cached ranges". + // If it happens to be a a real datapoint, it will be fetched properly when the user scrolls/zooms bring it into + // the visible part of the screen. // // Examples: // @@ -47,7 +48,7 @@ async function fetchSingleRange( // _________ 1st fetch // * + + // ^ - // '-- point at the edge, kept + // '-- point kept because it is out of the visible range // // _______ 2nd fetch // * + * + + From 6ff528413b6f929d7dd246a560addee06f64b774 Mon Sep 17 00:00:00 2001 From: David Buezas Date: Wed, 9 Nov 2022 12:17:24 +0100 Subject: [PATCH 3/3] improved comment line After lengthy deliberation, the "committee for the philosophy of comments and other non-executable bytes" converged to "point kept because it's at the start-edge of the trace and it's outside the visible range" --- src/cache/Cache.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cache/Cache.ts b/src/cache/Cache.ts index efa1156..525d14f 100644 --- a/src/cache/Cache.ts +++ b/src/cache/Cache.ts @@ -48,12 +48,12 @@ async function fetchSingleRange( // _________ 1st fetch // * + + // ^ - // '-- point kept because it is out of the visible range + // '-- point kept because it's at the start-edge of the trace and it's outside the visible range // // _______ 2nd fetch // * + * + + // ^ ^ - // | '--- discarded as it was fictitious + // | '--- discarded as it was fictitious and not at the start-edge // '--- point at the edge, kept // // ________ 3rd fetch