From 28e06166e087b94fc1f29bc6f71ee91517a12ff7 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 21 Jul 2022 18:10:43 +0200 Subject: [PATCH] perspectives - prepare for nested incremental load --- packages/datalib/src/PerspectiveCache.ts | 42 +++++++++++++++++-- .../datalib/src/PerspectiveDataProvider.ts | 12 ++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/packages/datalib/src/PerspectiveCache.ts b/packages/datalib/src/PerspectiveCache.ts index c4705ab4..27b41b58 100644 --- a/packages/datalib/src/PerspectiveCache.ts +++ b/packages/datalib/src/PerspectiveCache.ts @@ -1,14 +1,23 @@ import { RangeDefinition } from 'dbgate-types'; import { PerspectiveDataLoadProps } from './PerspectiveDataProvider'; import _pick from 'lodash/pick'; -import _omit from 'lodash/omit'; +import _zip from 'lodash/zip'; import _difference from 'lodash/difference'; import debug from 'debug'; const dbg = debug('dbgate:PerspectiveCache'); +export class PerspectiveBindingGroup { + constructor(public table: PerspectiveCacheTable) {} + + groupSize?: number; + loadedAll: boolean; + loadedRows: any[] = []; + bindingValues: any[]; +} + export class PerspectiveCacheTable { - constructor(props: PerspectiveDataLoadProps) { + constructor(props: PerspectiveDataLoadProps, public cache: PerspectiveCache) { this.schemaName = props.schemaName; this.pureName = props.pureName; this.bindingColumns = props.bindingColumns; @@ -22,6 +31,8 @@ export class PerspectiveCacheTable { dataColumns: string[]; loadedAll: boolean; loadedRows: any[] = []; + bindingGroups: { [bindingKey: string]: PerspectiveBindingGroup } = {}; + get loadedCount() { return this.loadedRows.length; } @@ -32,6 +43,31 @@ export class PerspectiveCacheTable { incomplete: props.topCount < this.loadedCount || !this.loadedAll, }; } + + getBindingGroups(props: PerspectiveDataLoadProps): { cached: PerspectiveBindingGroup[]; uncached: any[][] } { + const cached: PerspectiveBindingGroup[] = []; + const uncached = []; + for (const group in props.bindingValues) { + const key = this.cache.stableStringify(group); + const item = this.bindingGroups[key]; + if (item) { + cached.push(item); + } else { + uncached.push(group); + } + } + return { cached, uncached }; + } + + storeGroupSize(props: PerspectiveDataLoadProps, bindingValues: any[], count: number) { + const originalBindingValue = props.bindingValues.find(v => _zip(v, bindingValues).every(([x, y]) => x == y)); + if (originalBindingValue) { + const key = this.cache.stableStringify(originalBindingValue); + const group = new PerspectiveBindingGroup(this); + group.groupSize = count; + this.bindingGroups[key] = group; + } + } } export class PerspectiveCache { @@ -54,7 +90,7 @@ export class PerspectiveCache { } if (!res) { - res = new PerspectiveCacheTable(props); + res = new PerspectiveCacheTable(props, this); this.tables[tableKey] = res; return res; } diff --git a/packages/datalib/src/PerspectiveDataProvider.ts b/packages/datalib/src/PerspectiveDataProvider.ts index b137e522..739540f9 100644 --- a/packages/datalib/src/PerspectiveDataProvider.ts +++ b/packages/datalib/src/PerspectiveDataProvider.ts @@ -24,6 +24,18 @@ export class PerspectiveDataProvider { async loadData(props: PerspectiveDataLoadProps): Promise<{ rows: any[]; incomplete: boolean }> { const tableCache = this.cache.getTableCache(props); + if (props.bindingColumns) { + const { cached, uncached } = tableCache.getBindingGroups(props); + const counts = await this.loader.loadGrouping({ + ...props, + bindingValues: uncached, + }); + for (const countItem of counts) { + const { _perspective_group_size_, ...fields } = countItem; + tableCache.storeGroupSize(props, fields, _perspective_group_size_); + } + } + if (props.topCount <= tableCache.loadedCount) { return tableCache.getRowsResult(props); }