From 23f366aa132b1f72026f4a0745c234718d874cba Mon Sep 17 00:00:00 2001 From: Bilal Shafi Date: Mon, 23 Dec 2024 17:31:26 +0500 Subject: [PATCH] Make cache work with aggregation --- .../features/aggregation/useGridAggregation.ts | 1 - .../src/hooks/features/dataSource/cache.ts | 13 +++++++++++++ .../dataSource/useGridDataSourcePremium.tsx | 8 ++++++++ .../src/hooks/features/dataSource/cache.ts | 18 ++++++++++++++---- .../dataSource/useGridDataSourceBase.ts | 12 +++++++++--- 5 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 packages/x-data-grid-premium/src/hooks/features/dataSource/cache.ts diff --git a/packages/x-data-grid-premium/src/hooks/features/aggregation/useGridAggregation.ts b/packages/x-data-grid-premium/src/hooks/features/aggregation/useGridAggregation.ts index 7a36f1262054..ba8db5bc55dc 100644 --- a/packages/x-data-grid-premium/src/hooks/features/aggregation/useGridAggregation.ts +++ b/packages/x-data-grid-premium/src/hooks/features/aggregation/useGridAggregation.ts @@ -137,7 +137,6 @@ export const useGridAggregation = ( // Re-apply the row hydration to add / remove the aggregation footers if (!areAggregationRulesEqual(rulesOnLastRowHydration, aggregationRules)) { if (props.unstable_dataSource) { - apiRef.current.unstable_dataSource.cache.clear(); apiRef.current.unstable_dataSource.fetchRows(); } else { apiRef.current.requestPipeProcessorsApplication('hydrateRows'); diff --git a/packages/x-data-grid-premium/src/hooks/features/dataSource/cache.ts b/packages/x-data-grid-premium/src/hooks/features/dataSource/cache.ts new file mode 100644 index 000000000000..db35e1db051d --- /dev/null +++ b/packages/x-data-grid-premium/src/hooks/features/dataSource/cache.ts @@ -0,0 +1,13 @@ +import { GridGetRowsParamsPremium } from './models'; + +export function getKeyPremium(params: GridGetRowsParamsPremium) { + return JSON.stringify([ + params.filterModel, + params.sortModel, + params.groupKeys, + params.groupFields, + params.start, + params.end, + params.aggregationModel, + ]); +} diff --git a/packages/x-data-grid-premium/src/hooks/features/dataSource/useGridDataSourcePremium.tsx b/packages/x-data-grid-premium/src/hooks/features/dataSource/useGridDataSourcePremium.tsx index 999b058c1203..4833fedb88e8 100644 --- a/packages/x-data-grid-premium/src/hooks/features/dataSource/useGridDataSourcePremium.tsx +++ b/packages/x-data-grid-premium/src/hooks/features/dataSource/useGridDataSourcePremium.tsx @@ -17,6 +17,13 @@ import { GridPrivateApiPremium } from '../../../models/gridApiPremium'; import { DataGridPremiumProcessedProps } from '../../../models/dataGridPremiumProps'; import { GridDataSourcePremiumPrivateApi, GridGetRowsResponsePremium } from './models'; import { gridAggregationModelSelector } from '../aggregation/gridAggregationSelectors'; +import { getKeyPremium } from './cache'; + +const options = { + cacheOptions: { + getKey: getKeyPremium, + }, +}; export const useGridDataSourcePremium = ( apiRef: React.MutableRefObject, @@ -25,6 +32,7 @@ export const useGridDataSourcePremium = ( const { api, strategyProcessor, events } = useGridDataSourceBase( apiRef, props, + options, ); const aggregationModel = useGridSelector(apiRef, gridAggregationModelSelector); const aggregateRowRef = React.useRef({}); diff --git a/packages/x-data-grid-pro/src/hooks/features/dataSource/cache.ts b/packages/x-data-grid-pro/src/hooks/features/dataSource/cache.ts index 1881154cf870..c3e2e421345d 100644 --- a/packages/x-data-grid-pro/src/hooks/features/dataSource/cache.ts +++ b/packages/x-data-grid-pro/src/hooks/features/dataSource/cache.ts @@ -7,9 +7,16 @@ export type GridDataSourceCacheDefaultConfig = { * @default 300000 (5 minutes) */ ttl?: number; + /** + * Function to generate a cache key from the params. + * @param {GridGetRowsParams} params The params to generate the cache key from. + * @returns {string} The cache key. + * @default `getKeyDefault()` + */ + getKey?: (params: GridGetRowsParams) => string; }; -function getKey(params: GridGetRowsParams) { +function getKeyDefault(params: GridGetRowsParams) { return JSON.stringify([ params.filterModel, params.sortModel, @@ -25,19 +32,22 @@ export class GridDataSourceCacheDefault { private ttl: number; - constructor({ ttl = 300000 }: GridDataSourceCacheDefaultConfig) { + private getKey: (params: GridGetRowsParams) => string; + + constructor({ ttl = 300000, getKey = getKeyDefault }: GridDataSourceCacheDefaultConfig) { this.cache = {}; this.ttl = ttl; + this.getKey = getKey; } set(key: GridGetRowsParams, value: GridGetRowsResponse) { - const keyString = getKey(key); + const keyString = this.getKey(key); const expiry = Date.now() + this.ttl; this.cache[keyString] = { value, expiry }; } get(key: GridGetRowsParams): GridGetRowsResponse | undefined { - const keyString = getKey(key); + const keyString = this.getKey(key); const entry = this.cache[keyString]; if (!entry) { return undefined; diff --git a/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSourceBase.ts b/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSourceBase.ts index 5de3258096b5..1a6820ca9655 100644 --- a/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSourceBase.ts +++ b/packages/x-data-grid-pro/src/hooks/features/dataSource/useGridDataSourceBase.ts @@ -70,6 +70,9 @@ export const useGridDataSourceBase = ( | 'treeData' | 'unstable_lazyLoading' >, + options: { + cacheOptions?: GridDataSourceCacheDefaultConfig; + } = {}, ) => { const setStrategyAvailability = React.useCallback(() => { apiRef.current.setStrategyAvailability( @@ -100,7 +103,7 @@ export const useGridDataSourceBase = ( return new CacheChunkManager(cacheChunkSize); }).current; const [cache, setCache] = React.useState(() => - getCache(props.unstable_dataSourceCache), + getCache(props.unstable_dataSourceCache, options.cacheOptions), ); const fetchRows = React.useCallback( @@ -374,9 +377,12 @@ export const useGridDataSourceBase = ( isFirstRender.current = false; return; } - const newCache = getCache(props.unstable_dataSourceCache); + if (props.unstable_dataSourceCache === undefined) { + return; + } + const newCache = getCache(props.unstable_dataSourceCache, options.cacheOptions); setCache((prevCache) => (prevCache !== newCache ? newCache : prevCache)); - }, [props.unstable_dataSourceCache]); + }, [props.unstable_dataSourceCache, options.cacheOptions]); React.useEffect(() => { setStrategyAvailability();