react-flexigrid
Version:
A React table component designed to allow presenting millions of rows of data.
132 lines (107 loc) • 4.47 kB
JavaScript
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;