Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added id-based cell size cache #538

Merged
merged 1 commit into from
Jan 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/CellMeasurer.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ class CellSizeCache {
```

The [default caching strategy](https://github.com/bvaughn/react-virtualized/blob/master/source/CellMeasurer/defaultCellSizeCache.js) is exported as `defaultCellMeasurerCellSizeCache` should you wish to decorate it.
You can also use [an alternative caching strategy](https://github.com/bvaughn/react-virtualized/blob/master/source/CellMeasurer/uniformSizeCellSizeCache.js) for lists with a uniform (yet unknown) row height, exported as `uniformSizeCellMeasurerCellSizeCache`.
You can also pass `uniformRowHeight` and/or `uniformColumnWidth` named parameters to the constructor for lists with a uniform (yet unknown) cell sizes.

An [id-based caching strategy](https://github.com/bvaughn/react-virtualized/blob/master/source/CellMeasurer/idCellSizeCache.js) is also available for data that may be sorted.
This strategy maps data ids to cell sizes rathe than index so that the sorting order of the data does not invalidate sizes.

### Examples

Expand Down
14 changes: 7 additions & 7 deletions source/CellMeasurer/defaultCellSizeCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Permanently caches all cell sizes (identified by column and row index) unless explicitly cleared.
* Can be configured to handle uniform cell widths and/or heights as a way of optimizing certain use cases.
*/
export default class CellSizeCache {
export default class DefaultCellSizeCache {
constructor ({
uniformRowHeight = false,
uniformColumnWidth = false
Expand All @@ -28,36 +28,36 @@ export default class CellSizeCache {
this._cachedRowHeights = {}
}

clearColumnWidth (index: number) {
clearColumnWidth (index: any) {
this._cachedColumnWidth = undefined

delete this._cachedColumnWidths[index]
}

clearRowHeight (index: number) {
clearRowHeight (index: any) {
this._cachedRowHeight = undefined

delete this._cachedRowHeights[index]
}

getColumnWidth (index: number): ?number {
getColumnWidth (index: any): ?number {
return this._uniformColumnWidth
? this._cachedColumnWidth
: this._cachedColumnWidths[index]
}

getRowHeight (index: number): ?number {
getRowHeight (index: any): ?number {
return this._uniformRowHeight
? this._cachedRowHeight
: this._cachedRowHeights[index]
}

setColumnWidth (index: number, width: number) {
setColumnWidth (index: any, width: number) {
this._cachedColumnWidth = width
this._cachedColumnWidths[index] = width
}

setRowHeight (index: number, height: number) {
setRowHeight (index: any, height: number) {
this._cachedRowHeight = height
this._cachedRowHeights[index] = height
}
Expand Down
72 changes: 72 additions & 0 deletions source/CellMeasurer/idCellSizeCache.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/** @flow */
import DefaultCellSizeCache from './defaultCellSizeCache'

type IdCellSizeCacheConstructorParams = {
indexToIdMap : Function,
uniformRowHeight ?: boolean,
uniformColumnWidth ?: boolean
};

/**
* Alternate CellMeasurer `cellSizeCache` implementation.
* Similar to `defaultCellSizeCache` except that sizes are tied to data id rather than index.
* Requires an index-to-id map function (passed in externally) to operate.
*/
export default function idCellSizeCache ({
indexToIdMap,
uniformColumnWidth = false,
uniformRowHeight = false
} : IdCellSizeCacheConstructorParams) {
const cellSizeCache = new DefaultCellSizeCache({
uniformColumnWidth,
uniformRowHeight
})

return {
clearAllColumnWidths () {
cellSizeCache.clearAllColumnWidths()
},

clearAllRowHeights () {
cellSizeCache.clearAllRowHeights()
},

clearColumnWidth (index: number) {
cellSizeCache.clearColumnWidth(
indexToIdMap(index)
)
},

clearRowHeight (index: number) {
cellSizeCache.clearRowHeight(
indexToIdMap(index)
)
},

getColumnWidth (index: number): ?number {
return cellSizeCache.getColumnWidth(
indexToIdMap(index)
)
},

getRowHeight (index: number): ?number {
return cellSizeCache.getRowHeight(
indexToIdMap(index)
)
},

setColumnWidth (index: number, width: number) {
cellSizeCache.setColumnWidth(
indexToIdMap(index),
width
)
},

setRowHeight (index: number, height: number) {
cellSizeCache.setRowHeight(
indexToIdMap(index),
height
)
}
}
}
68 changes: 68 additions & 0 deletions source/CellMeasurer/idCellSizeCache.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import idCellSizeCache from './idCellSizeCache'

describe('idCellSizeCache', () => {
it('should track width and height using id instead of index', () => {
const indexToIdMap = {
0: 'foo',
1: 'bar',
2: 'baz'
}
const indexToIdMapCalls = []
const cache = idCellSizeCache({
indexToIdMap: (index) => {
indexToIdMapCalls.push(index)
return indexToIdMap[index]
}
})

// Set values with initial indices
cache.setColumnWidth(0, 100)
cache.setRowHeight(0, 25)
cache.setColumnWidth(1, 200)
cache.setRowHeight(1, 50)
cache.setColumnWidth(2, 300)
cache.setRowHeight(2, 75)

// Mimic a sort operation
indexToIdMap[0] = 'baz'
indexToIdMap[1] = 'bar'
indexToIdMap[2] = 'foo'

// Previous widths and heights should still be available
expect(cache.getColumnWidth(0)).toBe(300)
expect(cache.getRowHeight(0)).toBe(75)
expect(cache.getColumnWidth(1)).toBe(200)
expect(cache.getRowHeight(1)).toBe(50)
expect(cache.getColumnWidth(2)).toBe(100)
expect(cache.getRowHeight(2)).toBe(25)

// Clear a specific item
cache.clearColumnWidth(0)
cache.clearRowHeight(0)

// Mimic a sort operation
indexToIdMap[0] = 'bar'
indexToIdMap[1] = 'foo'
indexToIdMap[2] = 'baz'

// Previous widths and heights should still be available
expect(cache.getColumnWidth(0)).toBe(200)
expect(cache.getRowHeight(0)).toBe(50)
expect(cache.getColumnWidth(1)).toBe(100)
expect(cache.getRowHeight(1)).toBe(25)
expect(cache.getColumnWidth(2)).toBeUndefined()
expect(cache.getRowHeight(2)).toBeUndefined()

// Clear all items
cache.clearAllColumnWidths()
cache.clearAllRowHeights()

// No sizes should be available
expect(cache.getColumnWidth(0)).toBeUndefined()
expect(cache.getRowHeight(0)).toBeUndefined()
expect(cache.getColumnWidth(1)).toBeUndefined()
expect(cache.getRowHeight(1)).toBeUndefined()
expect(cache.getColumnWidth(2)).toBeUndefined()
expect(cache.getRowHeight(2)).toBeUndefined()
})
})
1 change: 1 addition & 0 deletions source/CellMeasurer/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export default from './CellMeasurer'
export CellMeasurer from './CellMeasurer'
export defaultCellSizeCache from './defaultCellSizeCache'
export idCellSizeCache from './idCellSizeCache'
3 changes: 2 additions & 1 deletion source/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ export { AutoSizer } from './AutoSizer'
export {
CellMeasurer,
defaultCellSizeCache as defaultCellMeasurerCellSizeCache,
defaultCellSizeCache as uniformSizeCellMeasurerCellSizeCache // 7.21 backwards compatible export
defaultCellSizeCache as uniformSizeCellMeasurerCellSizeCache, // 7.21 backwards compatible export
idCellSizeCache as idCellMeasurerCellSizeCache
} from './CellMeasurer'
export { Collection } from './Collection'
export { ColumnSizer } from './ColumnSizer'
Expand Down