UNPKG

react-flexigrid

Version:

A React table component designed to allow presenting millions of rows of data.

132 lines (107 loc) 4.47 kB
import _classCallCheck from 'babel-runtime/helpers/classCallCheck'; import invariant from 'invariant'; import Heap from './Heap'; var IntegerBufferSet = function () { function IntegerBufferSet() { _classCallCheck(this, IntegerBufferSet); this.smallerComparator = function (lhs, rhs) { return lhs.value < rhs.value; }; this.greaterComparator = function (lhs, rhs) { return lhs.value > rhs.value; }; this.size = 0; this.smallValues = new Heap([], this.smallerComparator); this.largeValues = new Heap([], this.greaterComparator); this.valuePositionMap = {}; } IntegerBufferSet.prototype.getSize = function getSize() { return this.size; }; IntegerBufferSet.prototype.getPositionForValue = function getPositionForValue(index) { var position = this.valuePositionMap[index]; return position === undefined ? null : position; }; IntegerBufferSet.prototype.getNewPositionForValue = function getNewPositionForValue(index) { invariant(this.valuePositionMap[index] === undefined, "Shouldn't try to find new position for value already stored in BufferSet"); var newPosition = this.size; this.size += 1; this.pushToHeaps(newPosition, index); this.valuePositionMap[index] = newPosition; return newPosition; }; IntegerBufferSet.prototype.replaceFurthestValuePosition = function replaceFurthestValuePosition(smallIndex, bigIndex, newIndex) { invariant(this.valuePositionMap[newIndex] === undefined, "Shouldn't try to replace values with value already stored value in BufferSet"); this.cleanHeaps(); if (this.smallValues.isEmpty() || this.largeValues.isEmpty()) { // Threre are currently no values stored. // We will have to create new position for this value. return null; } var minIndex = this.smallValues.peek().value; var maxIndex = this.largeValues.peek().value; if (minIndex >= smallIndex && maxIndex <= bigIndex) { // All values currently stored are necessary, we can't reuse any of them. return null; } var valueToReplace = void 0; if (smallIndex - minIndex > maxIndex - bigIndex) { // minValue is further from provided range. We will reuse it's position. valueToReplace = minIndex; this.smallValues.pop(); } else { valueToReplace = maxIndex; this.largeValues.pop(); } var position = this.valuePositionMap[valueToReplace]; delete this.valuePositionMap[valueToReplace]; this.valuePositionMap[newIndex] = position; this.pushToHeaps(position, newIndex); return position; }; IntegerBufferSet.prototype.pushToHeaps = function pushToHeaps(position, value) { var item = { position: position, value: value }; this.smallValues.push(item); this.largeValues.push(item); }; IntegerBufferSet.prototype.cleanHeaps = function cleanHeaps() { // We not usually only remove object from one heap while moving value. // Here we make sure that there is no stale data on top of heaps. this.cleanHeap(this.smallValues); this.cleanHeap(this.largeValues); var smallHeapSize = this.smallValues.getSize(); var largeHeapSize = this.largeValues.getSize(); var minHeapSize = Math.min(smallHeapSize, largeHeapSize); var maxHeapSize = Math.max(smallHeapSize, largeHeapSize); if (maxHeapSize > 10 * minHeapSize) { // There are many old values in one of heaps. We nned to // get rid of them to not use too avoid memory leaks this.reBuildHeaps(); } }; IntegerBufferSet.prototype.reBuildHeaps = function reBuildHeaps() { var sourceHeap = this.smallValues.getSize() < this.largeValues.getSize() ? this.smallValues : this.largeValues; var newSmallValues = new Heap([], this.smallerComparator); var newLargeValues = new Heap([], this.greaterComparator); while (!sourceHeap.isEmpty()) { var item = sourceHeap.pop(); // push all stil valid elements to new heaps if (this.valuePositionMap[item.value] !== undefined) { newSmallValues.push(item); newLargeValues.push(item); } } this.smallValues = newSmallValues; this.largeValues = newLargeValues; }; IntegerBufferSet.prototype.cleanHeap = function cleanHeap(heap) { while (!heap.isEmpty() && this.valuePositionMap[heap.peek().value] === undefined) { heap.pop(); } }; return IntegerBufferSet; }(); export default IntegerBufferSet;