@x-oasis/integer-buffer-set 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # @x-oasis/integer-buffer-set
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ $ npm i @x-oasis/integer-buffer-set
7
+ ```
8
+
9
+ ## How to use
10
+
11
+ ```typescript
12
+ import IntegerBufferSet from '@x-oasis/integer-buffer-set'
13
+ ```
14
+
15
+ ## How to run test
16
+
17
+ ```bash
18
+ $ pnpm test
19
+ ```
@@ -0,0 +1,26 @@
1
+ import Heap from '@x-oasis/heap';
2
+ declare type HeapItem = {
3
+ position: number;
4
+ value: number;
5
+ };
6
+ declare class IntegerBufferSet {
7
+ private _size;
8
+ private _valueToPositionMap;
9
+ private _smallValues;
10
+ private _largeValues;
11
+ constructor();
12
+ getSize(): number;
13
+ get indices(): any[];
14
+ getValuePosition(value: number): null | number;
15
+ getNewPositionForValue(value: number): number;
16
+ getMinValue(): number;
17
+ getMaxValue(): number;
18
+ replaceFurthestValuePosition(lowValue: number, highValue: number, newValue: number): null | number;
19
+ _pushToHeaps(position: number, value: number): void;
20
+ _cleanHeaps(): void;
21
+ _recreateHeaps(): void;
22
+ _cleanHeap(heap: Heap<HeapItem>): void;
23
+ _smallerComparator(lhs: HeapItem, rhs: HeapItem): boolean;
24
+ _greaterComparator(lhs: HeapItem, rhs: HeapItem): boolean;
25
+ }
26
+ export default IntegerBufferSet;
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+
2
+ 'use strict'
3
+
4
+ if (process.env.NODE_ENV === 'production') {
5
+ module.exports = require('./integer-buffer-set.cjs.production.min.js')
6
+ } else {
7
+ module.exports = require('./integer-buffer-set.cjs.development.js')
8
+ }
@@ -0,0 +1,164 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
+
7
+ var Heap = _interopDefault(require('@x-oasis/heap'));
8
+
9
+ function _defineProperties(target, props) {
10
+ for (var i = 0; i < props.length; i++) {
11
+ var descriptor = props[i];
12
+ descriptor.enumerable = descriptor.enumerable || false;
13
+ descriptor.configurable = true;
14
+ if ("value" in descriptor) descriptor.writable = true;
15
+ Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
16
+ }
17
+ }
18
+ function _createClass(Constructor, protoProps, staticProps) {
19
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
20
+ if (staticProps) _defineProperties(Constructor, staticProps);
21
+ Object.defineProperty(Constructor, "prototype", {
22
+ writable: false
23
+ });
24
+ return Constructor;
25
+ }
26
+ function _toPrimitive(input, hint) {
27
+ if (typeof input !== "object" || input === null) return input;
28
+ var prim = input[Symbol.toPrimitive];
29
+ if (prim !== undefined) {
30
+ var res = prim.call(input, hint || "default");
31
+ if (typeof res !== "object") return res;
32
+ throw new TypeError("@@toPrimitive must return a primitive value.");
33
+ }
34
+ return (hint === "string" ? String : Number)(input);
35
+ }
36
+ function _toPropertyKey(arg) {
37
+ var key = _toPrimitive(arg, "string");
38
+ return typeof key === "symbol" ? key : String(key);
39
+ }
40
+
41
+ var IntegerBufferSet = /*#__PURE__*/function () {
42
+ function IntegerBufferSet() {
43
+ this._valueToPositionMap = {};
44
+ this._size = 0;
45
+ this._smallValues = new Heap([], this._smallerComparator);
46
+ this._largeValues = new Heap([], this._greaterComparator);
47
+ this.getNewPositionForValue = this.getNewPositionForValue.bind(this);
48
+ this.getValuePosition = this.getValuePosition.bind(this);
49
+ this.getSize = this.getSize.bind(this);
50
+ this.replaceFurthestValuePosition = this.replaceFurthestValuePosition.bind(this);
51
+ }
52
+ var _proto = IntegerBufferSet.prototype;
53
+ _proto.getSize = function getSize() {
54
+ return this._size;
55
+ };
56
+ _proto.getValuePosition = function getValuePosition(value) {
57
+ if (this._valueToPositionMap[value] === undefined) {
58
+ return null;
59
+ }
60
+ return this._valueToPositionMap[value];
61
+ };
62
+ _proto.getNewPositionForValue = function getNewPositionForValue(value) {
63
+ if (this._valueToPositionMap[value] !== undefined) {
64
+ console.warn("Shouldn't try to find new position for value already stored in BufferSet");
65
+ }
66
+ var newPosition = this._size;
67
+ this._size++;
68
+ this._pushToHeaps(newPosition, value);
69
+ this._valueToPositionMap[value] = newPosition;
70
+ return newPosition;
71
+ };
72
+ _proto.getMinValue = function getMinValue() {
73
+ var _this$_smallValues$pe;
74
+ return (_this$_smallValues$pe = this._smallValues.peek()) == null ? void 0 : _this$_smallValues$pe.value;
75
+ };
76
+ _proto.getMaxValue = function getMaxValue() {
77
+ var _this$_largeValues$pe;
78
+ return (_this$_largeValues$pe = this._largeValues.peek()) == null ? void 0 : _this$_largeValues$pe.value;
79
+ };
80
+ _proto.replaceFurthestValuePosition = function replaceFurthestValuePosition(lowValue, highValue, newValue) {
81
+ if (this._valueToPositionMap[newValue] !== undefined) {
82
+ console.warn("Shouldn't try to replace values with value already stored value in " + 'BufferSet');
83
+ }
84
+ this._cleanHeaps();
85
+ if (this._smallValues.empty() || this._largeValues.empty()) {
86
+ return null;
87
+ }
88
+ var minValue = this._smallValues.peek().value;
89
+ var maxValue = this._largeValues.peek().value;
90
+ if (minValue >= lowValue && maxValue <= highValue) {
91
+ return null;
92
+ }
93
+ var valueToReplace;
94
+ if (lowValue - minValue > maxValue - highValue) {
95
+ valueToReplace = minValue;
96
+ this._smallValues.pop();
97
+ } else {
98
+ valueToReplace = maxValue;
99
+ this._largeValues.pop();
100
+ }
101
+ var position = this._valueToPositionMap[valueToReplace];
102
+ delete this._valueToPositionMap[valueToReplace];
103
+ this._valueToPositionMap[newValue] = position;
104
+ this._pushToHeaps(position, newValue);
105
+ return position;
106
+ };
107
+ _proto._pushToHeaps = function _pushToHeaps(position, value) {
108
+ var element = {
109
+ position: position,
110
+ value: value
111
+ };
112
+ this._smallValues.push(element);
113
+ this._largeValues.push(element);
114
+ };
115
+ _proto._cleanHeaps = function _cleanHeaps() {
116
+ this._cleanHeap(this._smallValues);
117
+ this._cleanHeap(this._largeValues);
118
+ var minHeapSize = Math.min(this._smallValues.size(), this._largeValues.size());
119
+ var maxHeapSize = Math.max(this._smallValues.size(), this._largeValues.size());
120
+ if (maxHeapSize > 10 * minHeapSize) {
121
+ this._recreateHeaps();
122
+ }
123
+ };
124
+ _proto._recreateHeaps = function _recreateHeaps() {
125
+ var sourceHeap = this._smallValues.size() < this._largeValues.size() ? this._smallValues : this._largeValues;
126
+ var newSmallValues = new Heap([], this._smallerComparator);
127
+ var newLargeValues = new Heap([], this._greaterComparator);
128
+ while (!sourceHeap.empty()) {
129
+ var element = sourceHeap.pop();
130
+ if (this._valueToPositionMap[element.value] !== undefined) {
131
+ newSmallValues.push(element);
132
+ newLargeValues.push(element);
133
+ }
134
+ }
135
+ this._smallValues = newSmallValues;
136
+ this._largeValues = newLargeValues;
137
+ };
138
+ _proto._cleanHeap = function _cleanHeap(heap) {
139
+ while (!heap.empty() && this._valueToPositionMap[heap.peek().value] === undefined) {
140
+ heap.pop();
141
+ }
142
+ };
143
+ _proto._smallerComparator = function _smallerComparator(lhs, rhs) {
144
+ return lhs.value < rhs.value;
145
+ };
146
+ _proto._greaterComparator = function _greaterComparator(lhs, rhs) {
147
+ return lhs.value > rhs.value;
148
+ };
149
+ _createClass(IntegerBufferSet, [{
150
+ key: "indices",
151
+ get: function get() {
152
+ var indices = [];
153
+ for (var key in this._valueToPositionMap) {
154
+ var value = this._valueToPositionMap[key];
155
+ indices[value] = key;
156
+ }
157
+ return indices;
158
+ }
159
+ }]);
160
+ return IntegerBufferSet;
161
+ }();
162
+
163
+ exports.default = IntegerBufferSet;
164
+ //# sourceMappingURL=integer-buffer-set.cjs.development.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integer-buffer-set.cjs.development.js","sources":["../src/index.ts"],"sourcesContent":["// import invariant from 'invariant';\nimport Heap from '@x-oasis/heap';\n\ntype HeapItem = {\n position: number;\n value: number;\n};\n\n// Data structure that allows to store values and assign positions to them\n// in a way to minimize changing positions of stored values when new ones are\n// added or when some values are replaced. Stored elements are alwasy assigned\n// a consecutive set of positoins startin from 0 up to count of elements less 1\n// Following actions can be executed\n// * get position assigned to given value (null if value is not stored)\n// * create new entry for new value and get assigned position back\n// * replace value that is furthest from specified value range with new value\n// and get it's position back\n// All operations take amortized log(n) time where n is number of elements in\n// the set.\nclass IntegerBufferSet {\n private _size: number;\n private _valueToPositionMap: {\n [key: string]: number;\n };\n private _smallValues: Heap<HeapItem>;\n private _largeValues: Heap<HeapItem>;\n\n constructor() {\n this._valueToPositionMap = {};\n this._size = 0;\n this._smallValues = new Heap([], this._smallerComparator);\n this._largeValues = new Heap([], this._greaterComparator);\n\n this.getNewPositionForValue = this.getNewPositionForValue.bind(this);\n this.getValuePosition = this.getValuePosition.bind(this);\n this.getSize = this.getSize.bind(this);\n this.replaceFurthestValuePosition =\n this.replaceFurthestValuePosition.bind(this);\n }\n\n getSize() {\n return this._size;\n }\n\n get indices() {\n const indices = [];\n for (const key in this._valueToPositionMap) {\n const value = this._valueToPositionMap[key];\n indices[value] = key;\n }\n return indices;\n }\n\n getValuePosition(value: number): null | number {\n if (this._valueToPositionMap[value] === undefined) {\n return null;\n }\n return this._valueToPositionMap[value];\n }\n\n getNewPositionForValue(value: number) {\n if (this._valueToPositionMap[value] !== undefined) {\n console.warn(\n \"Shouldn't try to find new position for value already stored in BufferSet\"\n );\n }\n // invariant(\n // this._valueToPositionMap[value] === undefined,\n // \"Shouldn't try to find new position for value already stored in BufferSet\"\n // );\n const newPosition = this._size;\n this._size++;\n this._pushToHeaps(newPosition, value);\n this._valueToPositionMap[value] = newPosition;\n return newPosition;\n }\n\n getMinValue() {\n return this._smallValues.peek()?.value;\n }\n\n getMaxValue() {\n return this._largeValues.peek()?.value;\n }\n\n replaceFurthestValuePosition(\n lowValue: number,\n highValue: number,\n newValue: number\n ): null | number {\n if (this._valueToPositionMap[newValue] !== undefined) {\n console.warn(\n \"Shouldn't try to replace values with value already stored value in \" +\n 'BufferSet'\n );\n }\n // invariant(\n // this._valueToPositionMap[newValue] === undefined,\n // \"Shouldn't try to replace values with value already stored value in \" +\n // 'BufferSet'\n // );\n\n this._cleanHeaps();\n if (this._smallValues.empty() || this._largeValues.empty()) {\n // Threre are currently no values stored. We will have to create new\n // position for this value.\n return null;\n }\n\n const minValue = this._smallValues.peek()!.value;\n const maxValue = this._largeValues.peek()!.value;\n if (minValue >= lowValue && maxValue <= highValue) {\n // All values currently stored are necessary, we can't reuse any of them.\n return null;\n }\n\n let valueToReplace;\n if (lowValue - minValue > maxValue - highValue) {\n // minValue is further from provided range. We will reuse it's position.\n valueToReplace = minValue;\n this._smallValues.pop();\n } else {\n valueToReplace = maxValue;\n this._largeValues.pop();\n }\n const position = this._valueToPositionMap[valueToReplace];\n delete this._valueToPositionMap[valueToReplace];\n this._valueToPositionMap[newValue] = position;\n this._pushToHeaps(position, newValue);\n\n return position;\n }\n\n _pushToHeaps(position: number, value: number) {\n const element = {\n position,\n value,\n };\n // We can reuse the same object in both heaps, because we don't mutate them\n this._smallValues.push(element);\n this._largeValues.push(element);\n }\n\n _cleanHeaps() {\n // We not usually only remove object from one heap while moving value.\n // Here we make sure that there is no stale data on top of heaps.\n this._cleanHeap(this._smallValues);\n this._cleanHeap(this._largeValues);\n const minHeapSize = Math.min(\n this._smallValues.size(),\n this._largeValues.size()\n );\n const maxHeapSize = Math.max(\n this._smallValues.size(),\n this._largeValues.size()\n );\n if (maxHeapSize > 10 * minHeapSize) {\n // There are many old values in one of heaps. We need to get rid of them\n // to not use too avoid memory leaks\n this._recreateHeaps();\n }\n }\n\n _recreateHeaps() {\n const sourceHeap =\n this._smallValues.size() < this._largeValues.size()\n ? this._smallValues\n : this._largeValues;\n const newSmallValues = new Heap<HeapItem>(\n [], // Initial data in the heap\n this._smallerComparator\n );\n const newLargeValues = new Heap<HeapItem>(\n [], // Initial datat in the heap\n this._greaterComparator\n );\n while (!sourceHeap.empty()) {\n const element = sourceHeap.pop()!;\n // Push all stil valid elements to new heaps\n if (this._valueToPositionMap[element.value] !== undefined) {\n newSmallValues.push(element);\n newLargeValues.push(element);\n }\n }\n this._smallValues = newSmallValues;\n this._largeValues = newLargeValues;\n }\n\n _cleanHeap(heap: Heap<HeapItem>) {\n while (\n !heap.empty() &&\n this._valueToPositionMap[heap.peek()!.value] === undefined\n ) {\n heap.pop();\n }\n }\n\n _smallerComparator(lhs: HeapItem, rhs: HeapItem) {\n return lhs.value < rhs.value;\n }\n\n _greaterComparator(lhs: HeapItem, rhs: HeapItem) {\n return lhs.value > rhs.value;\n }\n}\n\nexport default IntegerBufferSet;\n"],"names":["IntegerBufferSet","_valueToPositionMap","_size","_smallValues","Heap","_smallerComparator","_largeValues","_greaterComparator","getNewPositionForValue","bind","getValuePosition","getSize","replaceFurthestValuePosition","_proto","prototype","value","undefined","console","warn","newPosition","_pushToHeaps","getMinValue","_this$_smallValues$pe","peek","getMaxValue","_this$_largeValues$pe","lowValue","highValue","newValue","_cleanHeaps","empty","minValue","maxValue","valueToReplace","pop","position","element","push","_cleanHeap","minHeapSize","Math","min","size","maxHeapSize","max","_recreateHeaps","sourceHeap","newSmallValues","newLargeValues","heap","lhs","rhs","_createClass","key","get","indices"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=(e=require("@x-oasis/heap"))&&"object"==typeof e&&"default"in e?e.default:e;exports.default=function(){function e(){this._valueToPositionMap={},this._size=0,this._smallValues=new t([],this._smallerComparator),this._largeValues=new t([],this._greaterComparator),this.getNewPositionForValue=this.getNewPositionForValue.bind(this),this.getValuePosition=this.getValuePosition.bind(this),this.getSize=this.getSize.bind(this),this.replaceFurthestValuePosition=this.replaceFurthestValuePosition.bind(this)}var i,a,s=e.prototype;return s.getSize=function(){return this._size},s.getValuePosition=function(e){return void 0===this._valueToPositionMap[e]?null:this._valueToPositionMap[e]},s.getNewPositionForValue=function(e){void 0!==this._valueToPositionMap[e]&&console.warn("Shouldn't try to find new position for value already stored in BufferSet");var t=this._size;return this._size++,this._pushToHeaps(t,e),this._valueToPositionMap[e]=t,t},s.getMinValue=function(){var e;return null==(e=this._smallValues.peek())?void 0:e.value},s.getMaxValue=function(){var e;return null==(e=this._largeValues.peek())?void 0:e.value},s.replaceFurthestValuePosition=function(e,t,i){if(void 0!==this._valueToPositionMap[i]&&console.warn("Shouldn't try to replace values with value already stored value in BufferSet"),this._cleanHeaps(),this._smallValues.empty()||this._largeValues.empty())return null;var a,s=this._smallValues.peek().value,l=this._largeValues.peek().value;if(s>=e&&l<=t)return null;e-s>l-t?(a=s,this._smallValues.pop()):(a=l,this._largeValues.pop());var o=this._valueToPositionMap[a];return delete this._valueToPositionMap[a],this._valueToPositionMap[i]=o,this._pushToHeaps(o,i),o},s._pushToHeaps=function(e,t){var i={position:e,value:t};this._smallValues.push(i),this._largeValues.push(i)},s._cleanHeaps=function(){this._cleanHeap(this._smallValues),this._cleanHeap(this._largeValues);var e=Math.min(this._smallValues.size(),this._largeValues.size());Math.max(this._smallValues.size(),this._largeValues.size())>10*e&&this._recreateHeaps()},s._recreateHeaps=function(){for(var e=this._smallValues.size()<this._largeValues.size()?this._smallValues:this._largeValues,i=new t([],this._smallerComparator),a=new t([],this._greaterComparator);!e.empty();){var s=e.pop();void 0!==this._valueToPositionMap[s.value]&&(i.push(s),a.push(s))}this._smallValues=i,this._largeValues=a},s._cleanHeap=function(e){for(;!e.empty()&&void 0===this._valueToPositionMap[e.peek().value];)e.pop()},s._smallerComparator=function(e,t){return e.value<t.value},s._greaterComparator=function(e,t){return e.value>t.value},i=e,(a=[{key:"indices",get:function(){var e=[];for(var t in this._valueToPositionMap)e[this._valueToPositionMap[t]]=t;return e}}])&&function(e,t){for(var i=0;i<t.length;i++){var a=t[i];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,"symbol"==typeof(s=function(e,t){if("object"!=typeof e||null===e)return e;var i=e[Symbol.toPrimitive];if(void 0!==i){var a=i.call(e,"string");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(a.key))?s:String(s),a)}var s}(i.prototype,a),Object.defineProperty(i,"prototype",{writable:!1}),e}();
2
+ //# sourceMappingURL=integer-buffer-set.cjs.production.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integer-buffer-set.cjs.production.min.js","sources":["../src/index.ts"],"sourcesContent":["// import invariant from 'invariant';\nimport Heap from '@x-oasis/heap';\n\ntype HeapItem = {\n position: number;\n value: number;\n};\n\n// Data structure that allows to store values and assign positions to them\n// in a way to minimize changing positions of stored values when new ones are\n// added or when some values are replaced. Stored elements are alwasy assigned\n// a consecutive set of positoins startin from 0 up to count of elements less 1\n// Following actions can be executed\n// * get position assigned to given value (null if value is not stored)\n// * create new entry for new value and get assigned position back\n// * replace value that is furthest from specified value range with new value\n// and get it's position back\n// All operations take amortized log(n) time where n is number of elements in\n// the set.\nclass IntegerBufferSet {\n private _size: number;\n private _valueToPositionMap: {\n [key: string]: number;\n };\n private _smallValues: Heap<HeapItem>;\n private _largeValues: Heap<HeapItem>;\n\n constructor() {\n this._valueToPositionMap = {};\n this._size = 0;\n this._smallValues = new Heap([], this._smallerComparator);\n this._largeValues = new Heap([], this._greaterComparator);\n\n this.getNewPositionForValue = this.getNewPositionForValue.bind(this);\n this.getValuePosition = this.getValuePosition.bind(this);\n this.getSize = this.getSize.bind(this);\n this.replaceFurthestValuePosition =\n this.replaceFurthestValuePosition.bind(this);\n }\n\n getSize() {\n return this._size;\n }\n\n get indices() {\n const indices = [];\n for (const key in this._valueToPositionMap) {\n const value = this._valueToPositionMap[key];\n indices[value] = key;\n }\n return indices;\n }\n\n getValuePosition(value: number): null | number {\n if (this._valueToPositionMap[value] === undefined) {\n return null;\n }\n return this._valueToPositionMap[value];\n }\n\n getNewPositionForValue(value: number) {\n if (this._valueToPositionMap[value] !== undefined) {\n console.warn(\n \"Shouldn't try to find new position for value already stored in BufferSet\"\n );\n }\n // invariant(\n // this._valueToPositionMap[value] === undefined,\n // \"Shouldn't try to find new position for value already stored in BufferSet\"\n // );\n const newPosition = this._size;\n this._size++;\n this._pushToHeaps(newPosition, value);\n this._valueToPositionMap[value] = newPosition;\n return newPosition;\n }\n\n getMinValue() {\n return this._smallValues.peek()?.value;\n }\n\n getMaxValue() {\n return this._largeValues.peek()?.value;\n }\n\n replaceFurthestValuePosition(\n lowValue: number,\n highValue: number,\n newValue: number\n ): null | number {\n if (this._valueToPositionMap[newValue] !== undefined) {\n console.warn(\n \"Shouldn't try to replace values with value already stored value in \" +\n 'BufferSet'\n );\n }\n // invariant(\n // this._valueToPositionMap[newValue] === undefined,\n // \"Shouldn't try to replace values with value already stored value in \" +\n // 'BufferSet'\n // );\n\n this._cleanHeaps();\n if (this._smallValues.empty() || this._largeValues.empty()) {\n // Threre are currently no values stored. We will have to create new\n // position for this value.\n return null;\n }\n\n const minValue = this._smallValues.peek()!.value;\n const maxValue = this._largeValues.peek()!.value;\n if (minValue >= lowValue && maxValue <= highValue) {\n // All values currently stored are necessary, we can't reuse any of them.\n return null;\n }\n\n let valueToReplace;\n if (lowValue - minValue > maxValue - highValue) {\n // minValue is further from provided range. We will reuse it's position.\n valueToReplace = minValue;\n this._smallValues.pop();\n } else {\n valueToReplace = maxValue;\n this._largeValues.pop();\n }\n const position = this._valueToPositionMap[valueToReplace];\n delete this._valueToPositionMap[valueToReplace];\n this._valueToPositionMap[newValue] = position;\n this._pushToHeaps(position, newValue);\n\n return position;\n }\n\n _pushToHeaps(position: number, value: number) {\n const element = {\n position,\n value,\n };\n // We can reuse the same object in both heaps, because we don't mutate them\n this._smallValues.push(element);\n this._largeValues.push(element);\n }\n\n _cleanHeaps() {\n // We not usually only remove object from one heap while moving value.\n // Here we make sure that there is no stale data on top of heaps.\n this._cleanHeap(this._smallValues);\n this._cleanHeap(this._largeValues);\n const minHeapSize = Math.min(\n this._smallValues.size(),\n this._largeValues.size()\n );\n const maxHeapSize = Math.max(\n this._smallValues.size(),\n this._largeValues.size()\n );\n if (maxHeapSize > 10 * minHeapSize) {\n // There are many old values in one of heaps. We need to get rid of them\n // to not use too avoid memory leaks\n this._recreateHeaps();\n }\n }\n\n _recreateHeaps() {\n const sourceHeap =\n this._smallValues.size() < this._largeValues.size()\n ? this._smallValues\n : this._largeValues;\n const newSmallValues = new Heap<HeapItem>(\n [], // Initial data in the heap\n this._smallerComparator\n );\n const newLargeValues = new Heap<HeapItem>(\n [], // Initial datat in the heap\n this._greaterComparator\n );\n while (!sourceHeap.empty()) {\n const element = sourceHeap.pop()!;\n // Push all stil valid elements to new heaps\n if (this._valueToPositionMap[element.value] !== undefined) {\n newSmallValues.push(element);\n newLargeValues.push(element);\n }\n }\n this._smallValues = newSmallValues;\n this._largeValues = newLargeValues;\n }\n\n _cleanHeap(heap: Heap<HeapItem>) {\n while (\n !heap.empty() &&\n this._valueToPositionMap[heap.peek()!.value] === undefined\n ) {\n heap.pop();\n }\n }\n\n _smallerComparator(lhs: HeapItem, rhs: HeapItem) {\n return lhs.value < rhs.value;\n }\n\n _greaterComparator(lhs: HeapItem, rhs: HeapItem) {\n return lhs.value > rhs.value;\n }\n}\n\nexport default IntegerBufferSet;\n"],"names":["IntegerBufferSet","this","_valueToPositionMap","_size","_smallValues","Heap","_smallerComparator","_largeValues","_greaterComparator","getNewPositionForValue","bind","getValuePosition","getSize","replaceFurthestValuePosition","_proto","prototype","value","undefined","console","warn","newPosition","_pushToHeaps","getMinValue","_this$_smallValues$pe","peek","getMaxValue","_this$_largeValues$pe","lowValue","highValue","newValue","_cleanHeaps","empty","valueToReplace","minValue","maxValue","pop","position","element","push","_cleanHeap","minHeapSize","Math","min","size","max","_recreateHeaps","sourceHeap","newSmallValues","newLargeValues","heap","lhs","rhs","key","get","indices"],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ import Heap from '@x-oasis/heap';
2
+
3
+ function _defineProperties(target, props) {
4
+ for (var i = 0; i < props.length; i++) {
5
+ var descriptor = props[i];
6
+ descriptor.enumerable = descriptor.enumerable || false;
7
+ descriptor.configurable = true;
8
+ if ("value" in descriptor) descriptor.writable = true;
9
+ Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
10
+ }
11
+ }
12
+ function _createClass(Constructor, protoProps, staticProps) {
13
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
14
+ if (staticProps) _defineProperties(Constructor, staticProps);
15
+ Object.defineProperty(Constructor, "prototype", {
16
+ writable: false
17
+ });
18
+ return Constructor;
19
+ }
20
+ function _toPrimitive(input, hint) {
21
+ if (typeof input !== "object" || input === null) return input;
22
+ var prim = input[Symbol.toPrimitive];
23
+ if (prim !== undefined) {
24
+ var res = prim.call(input, hint || "default");
25
+ if (typeof res !== "object") return res;
26
+ throw new TypeError("@@toPrimitive must return a primitive value.");
27
+ }
28
+ return (hint === "string" ? String : Number)(input);
29
+ }
30
+ function _toPropertyKey(arg) {
31
+ var key = _toPrimitive(arg, "string");
32
+ return typeof key === "symbol" ? key : String(key);
33
+ }
34
+
35
+ var IntegerBufferSet = /*#__PURE__*/function () {
36
+ function IntegerBufferSet() {
37
+ this._valueToPositionMap = {};
38
+ this._size = 0;
39
+ this._smallValues = new Heap([], this._smallerComparator);
40
+ this._largeValues = new Heap([], this._greaterComparator);
41
+ this.getNewPositionForValue = this.getNewPositionForValue.bind(this);
42
+ this.getValuePosition = this.getValuePosition.bind(this);
43
+ this.getSize = this.getSize.bind(this);
44
+ this.replaceFurthestValuePosition = this.replaceFurthestValuePosition.bind(this);
45
+ }
46
+ var _proto = IntegerBufferSet.prototype;
47
+ _proto.getSize = function getSize() {
48
+ return this._size;
49
+ };
50
+ _proto.getValuePosition = function getValuePosition(value) {
51
+ if (this._valueToPositionMap[value] === undefined) {
52
+ return null;
53
+ }
54
+ return this._valueToPositionMap[value];
55
+ };
56
+ _proto.getNewPositionForValue = function getNewPositionForValue(value) {
57
+ if (this._valueToPositionMap[value] !== undefined) {
58
+ console.warn("Shouldn't try to find new position for value already stored in BufferSet");
59
+ }
60
+ var newPosition = this._size;
61
+ this._size++;
62
+ this._pushToHeaps(newPosition, value);
63
+ this._valueToPositionMap[value] = newPosition;
64
+ return newPosition;
65
+ };
66
+ _proto.getMinValue = function getMinValue() {
67
+ var _this$_smallValues$pe;
68
+ return (_this$_smallValues$pe = this._smallValues.peek()) == null ? void 0 : _this$_smallValues$pe.value;
69
+ };
70
+ _proto.getMaxValue = function getMaxValue() {
71
+ var _this$_largeValues$pe;
72
+ return (_this$_largeValues$pe = this._largeValues.peek()) == null ? void 0 : _this$_largeValues$pe.value;
73
+ };
74
+ _proto.replaceFurthestValuePosition = function replaceFurthestValuePosition(lowValue, highValue, newValue) {
75
+ if (this._valueToPositionMap[newValue] !== undefined) {
76
+ console.warn("Shouldn't try to replace values with value already stored value in " + 'BufferSet');
77
+ }
78
+ this._cleanHeaps();
79
+ if (this._smallValues.empty() || this._largeValues.empty()) {
80
+ return null;
81
+ }
82
+ var minValue = this._smallValues.peek().value;
83
+ var maxValue = this._largeValues.peek().value;
84
+ if (minValue >= lowValue && maxValue <= highValue) {
85
+ return null;
86
+ }
87
+ var valueToReplace;
88
+ if (lowValue - minValue > maxValue - highValue) {
89
+ valueToReplace = minValue;
90
+ this._smallValues.pop();
91
+ } else {
92
+ valueToReplace = maxValue;
93
+ this._largeValues.pop();
94
+ }
95
+ var position = this._valueToPositionMap[valueToReplace];
96
+ delete this._valueToPositionMap[valueToReplace];
97
+ this._valueToPositionMap[newValue] = position;
98
+ this._pushToHeaps(position, newValue);
99
+ return position;
100
+ };
101
+ _proto._pushToHeaps = function _pushToHeaps(position, value) {
102
+ var element = {
103
+ position: position,
104
+ value: value
105
+ };
106
+ this._smallValues.push(element);
107
+ this._largeValues.push(element);
108
+ };
109
+ _proto._cleanHeaps = function _cleanHeaps() {
110
+ this._cleanHeap(this._smallValues);
111
+ this._cleanHeap(this._largeValues);
112
+ var minHeapSize = Math.min(this._smallValues.size(), this._largeValues.size());
113
+ var maxHeapSize = Math.max(this._smallValues.size(), this._largeValues.size());
114
+ if (maxHeapSize > 10 * minHeapSize) {
115
+ this._recreateHeaps();
116
+ }
117
+ };
118
+ _proto._recreateHeaps = function _recreateHeaps() {
119
+ var sourceHeap = this._smallValues.size() < this._largeValues.size() ? this._smallValues : this._largeValues;
120
+ var newSmallValues = new Heap([], this._smallerComparator);
121
+ var newLargeValues = new Heap([], this._greaterComparator);
122
+ while (!sourceHeap.empty()) {
123
+ var element = sourceHeap.pop();
124
+ if (this._valueToPositionMap[element.value] !== undefined) {
125
+ newSmallValues.push(element);
126
+ newLargeValues.push(element);
127
+ }
128
+ }
129
+ this._smallValues = newSmallValues;
130
+ this._largeValues = newLargeValues;
131
+ };
132
+ _proto._cleanHeap = function _cleanHeap(heap) {
133
+ while (!heap.empty() && this._valueToPositionMap[heap.peek().value] === undefined) {
134
+ heap.pop();
135
+ }
136
+ };
137
+ _proto._smallerComparator = function _smallerComparator(lhs, rhs) {
138
+ return lhs.value < rhs.value;
139
+ };
140
+ _proto._greaterComparator = function _greaterComparator(lhs, rhs) {
141
+ return lhs.value > rhs.value;
142
+ };
143
+ _createClass(IntegerBufferSet, [{
144
+ key: "indices",
145
+ get: function get() {
146
+ var indices = [];
147
+ for (var key in this._valueToPositionMap) {
148
+ var value = this._valueToPositionMap[key];
149
+ indices[value] = key;
150
+ }
151
+ return indices;
152
+ }
153
+ }]);
154
+ return IntegerBufferSet;
155
+ }();
156
+
157
+ export default IntegerBufferSet;
158
+ //# sourceMappingURL=integer-buffer-set.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integer-buffer-set.esm.js","sources":["../src/index.ts"],"sourcesContent":["// import invariant from 'invariant';\nimport Heap from '@x-oasis/heap';\n\ntype HeapItem = {\n position: number;\n value: number;\n};\n\n// Data structure that allows to store values and assign positions to them\n// in a way to minimize changing positions of stored values when new ones are\n// added or when some values are replaced. Stored elements are alwasy assigned\n// a consecutive set of positoins startin from 0 up to count of elements less 1\n// Following actions can be executed\n// * get position assigned to given value (null if value is not stored)\n// * create new entry for new value and get assigned position back\n// * replace value that is furthest from specified value range with new value\n// and get it's position back\n// All operations take amortized log(n) time where n is number of elements in\n// the set.\nclass IntegerBufferSet {\n private _size: number;\n private _valueToPositionMap: {\n [key: string]: number;\n };\n private _smallValues: Heap<HeapItem>;\n private _largeValues: Heap<HeapItem>;\n\n constructor() {\n this._valueToPositionMap = {};\n this._size = 0;\n this._smallValues = new Heap([], this._smallerComparator);\n this._largeValues = new Heap([], this._greaterComparator);\n\n this.getNewPositionForValue = this.getNewPositionForValue.bind(this);\n this.getValuePosition = this.getValuePosition.bind(this);\n this.getSize = this.getSize.bind(this);\n this.replaceFurthestValuePosition =\n this.replaceFurthestValuePosition.bind(this);\n }\n\n getSize() {\n return this._size;\n }\n\n get indices() {\n const indices = [];\n for (const key in this._valueToPositionMap) {\n const value = this._valueToPositionMap[key];\n indices[value] = key;\n }\n return indices;\n }\n\n getValuePosition(value: number): null | number {\n if (this._valueToPositionMap[value] === undefined) {\n return null;\n }\n return this._valueToPositionMap[value];\n }\n\n getNewPositionForValue(value: number) {\n if (this._valueToPositionMap[value] !== undefined) {\n console.warn(\n \"Shouldn't try to find new position for value already stored in BufferSet\"\n );\n }\n // invariant(\n // this._valueToPositionMap[value] === undefined,\n // \"Shouldn't try to find new position for value already stored in BufferSet\"\n // );\n const newPosition = this._size;\n this._size++;\n this._pushToHeaps(newPosition, value);\n this._valueToPositionMap[value] = newPosition;\n return newPosition;\n }\n\n getMinValue() {\n return this._smallValues.peek()?.value;\n }\n\n getMaxValue() {\n return this._largeValues.peek()?.value;\n }\n\n replaceFurthestValuePosition(\n lowValue: number,\n highValue: number,\n newValue: number\n ): null | number {\n if (this._valueToPositionMap[newValue] !== undefined) {\n console.warn(\n \"Shouldn't try to replace values with value already stored value in \" +\n 'BufferSet'\n );\n }\n // invariant(\n // this._valueToPositionMap[newValue] === undefined,\n // \"Shouldn't try to replace values with value already stored value in \" +\n // 'BufferSet'\n // );\n\n this._cleanHeaps();\n if (this._smallValues.empty() || this._largeValues.empty()) {\n // Threre are currently no values stored. We will have to create new\n // position for this value.\n return null;\n }\n\n const minValue = this._smallValues.peek()!.value;\n const maxValue = this._largeValues.peek()!.value;\n if (minValue >= lowValue && maxValue <= highValue) {\n // All values currently stored are necessary, we can't reuse any of them.\n return null;\n }\n\n let valueToReplace;\n if (lowValue - minValue > maxValue - highValue) {\n // minValue is further from provided range. We will reuse it's position.\n valueToReplace = minValue;\n this._smallValues.pop();\n } else {\n valueToReplace = maxValue;\n this._largeValues.pop();\n }\n const position = this._valueToPositionMap[valueToReplace];\n delete this._valueToPositionMap[valueToReplace];\n this._valueToPositionMap[newValue] = position;\n this._pushToHeaps(position, newValue);\n\n return position;\n }\n\n _pushToHeaps(position: number, value: number) {\n const element = {\n position,\n value,\n };\n // We can reuse the same object in both heaps, because we don't mutate them\n this._smallValues.push(element);\n this._largeValues.push(element);\n }\n\n _cleanHeaps() {\n // We not usually only remove object from one heap while moving value.\n // Here we make sure that there is no stale data on top of heaps.\n this._cleanHeap(this._smallValues);\n this._cleanHeap(this._largeValues);\n const minHeapSize = Math.min(\n this._smallValues.size(),\n this._largeValues.size()\n );\n const maxHeapSize = Math.max(\n this._smallValues.size(),\n this._largeValues.size()\n );\n if (maxHeapSize > 10 * minHeapSize) {\n // There are many old values in one of heaps. We need to get rid of them\n // to not use too avoid memory leaks\n this._recreateHeaps();\n }\n }\n\n _recreateHeaps() {\n const sourceHeap =\n this._smallValues.size() < this._largeValues.size()\n ? this._smallValues\n : this._largeValues;\n const newSmallValues = new Heap<HeapItem>(\n [], // Initial data in the heap\n this._smallerComparator\n );\n const newLargeValues = new Heap<HeapItem>(\n [], // Initial datat in the heap\n this._greaterComparator\n );\n while (!sourceHeap.empty()) {\n const element = sourceHeap.pop()!;\n // Push all stil valid elements to new heaps\n if (this._valueToPositionMap[element.value] !== undefined) {\n newSmallValues.push(element);\n newLargeValues.push(element);\n }\n }\n this._smallValues = newSmallValues;\n this._largeValues = newLargeValues;\n }\n\n _cleanHeap(heap: Heap<HeapItem>) {\n while (\n !heap.empty() &&\n this._valueToPositionMap[heap.peek()!.value] === undefined\n ) {\n heap.pop();\n }\n }\n\n _smallerComparator(lhs: HeapItem, rhs: HeapItem) {\n return lhs.value < rhs.value;\n }\n\n _greaterComparator(lhs: HeapItem, rhs: HeapItem) {\n return lhs.value > rhs.value;\n }\n}\n\nexport default IntegerBufferSet;\n"],"names":["IntegerBufferSet","_valueToPositionMap","_size","_smallValues","Heap","_smallerComparator","_largeValues","_greaterComparator","getNewPositionForValue","bind","getValuePosition","getSize","replaceFurthestValuePosition","_proto","prototype","value","undefined","console","warn","newPosition","_pushToHeaps","getMinValue","_this$_smallValues$pe","peek","getMaxValue","_this$_largeValues$pe","lowValue","highValue","newValue","_cleanHeaps","empty","minValue","maxValue","valueToReplace","pop","position","element","push","_cleanHeap","minHeapSize","Math","min","size","maxHeapSize","max","_recreateHeaps","sourceHeap","newSmallValues","newLargeValues","heap","lhs","rhs","_createClass","key","get","indices"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@x-oasis/integer-buffer-set",
3
+ "version": "0.0.18",
4
+ "description": "IntegerBufferSet function",
5
+ "main": "dist/index.js",
6
+ "typings": "dist/index.d.ts",
7
+ "module": "dist/integer-buffer-set.esm.js",
8
+ "files": [
9
+ "dist",
10
+ "index.ts",
11
+ "src"
12
+ ],
13
+ "author": "",
14
+ "license": "ISC",
15
+ "devDependencies": {
16
+ "tsdx": "^0.14.1",
17
+ "@x-oasis/heap": "0.0.18"
18
+ },
19
+ "scripts": {
20
+ "build": "tsdx build --tsconfig tsconfig.build.json",
21
+ "clean": "rimraf ./dist",
22
+ "test": "vitest",
23
+ "compile": "tsc -p tsconfig.build.json"
24
+ }
25
+ }
package/src/index.ts ADDED
@@ -0,0 +1,207 @@
1
+ // import invariant from 'invariant';
2
+ import Heap from '@x-oasis/heap';
3
+
4
+ type HeapItem = {
5
+ position: number;
6
+ value: number;
7
+ };
8
+
9
+ // Data structure that allows to store values and assign positions to them
10
+ // in a way to minimize changing positions of stored values when new ones are
11
+ // added or when some values are replaced. Stored elements are alwasy assigned
12
+ // a consecutive set of positoins startin from 0 up to count of elements less 1
13
+ // Following actions can be executed
14
+ // * get position assigned to given value (null if value is not stored)
15
+ // * create new entry for new value and get assigned position back
16
+ // * replace value that is furthest from specified value range with new value
17
+ // and get it's position back
18
+ // All operations take amortized log(n) time where n is number of elements in
19
+ // the set.
20
+ class IntegerBufferSet {
21
+ private _size: number;
22
+ private _valueToPositionMap: {
23
+ [key: string]: number;
24
+ };
25
+ private _smallValues: Heap<HeapItem>;
26
+ private _largeValues: Heap<HeapItem>;
27
+
28
+ constructor() {
29
+ this._valueToPositionMap = {};
30
+ this._size = 0;
31
+ this._smallValues = new Heap([], this._smallerComparator);
32
+ this._largeValues = new Heap([], this._greaterComparator);
33
+
34
+ this.getNewPositionForValue = this.getNewPositionForValue.bind(this);
35
+ this.getValuePosition = this.getValuePosition.bind(this);
36
+ this.getSize = this.getSize.bind(this);
37
+ this.replaceFurthestValuePosition =
38
+ this.replaceFurthestValuePosition.bind(this);
39
+ }
40
+
41
+ getSize() {
42
+ return this._size;
43
+ }
44
+
45
+ get indices() {
46
+ const indices = [];
47
+ for (const key in this._valueToPositionMap) {
48
+ const value = this._valueToPositionMap[key];
49
+ indices[value] = key;
50
+ }
51
+ return indices;
52
+ }
53
+
54
+ getValuePosition(value: number): null | number {
55
+ if (this._valueToPositionMap[value] === undefined) {
56
+ return null;
57
+ }
58
+ return this._valueToPositionMap[value];
59
+ }
60
+
61
+ getNewPositionForValue(value: number) {
62
+ if (this._valueToPositionMap[value] !== undefined) {
63
+ console.warn(
64
+ "Shouldn't try to find new position for value already stored in BufferSet"
65
+ );
66
+ }
67
+ // invariant(
68
+ // this._valueToPositionMap[value] === undefined,
69
+ // "Shouldn't try to find new position for value already stored in BufferSet"
70
+ // );
71
+ const newPosition = this._size;
72
+ this._size++;
73
+ this._pushToHeaps(newPosition, value);
74
+ this._valueToPositionMap[value] = newPosition;
75
+ return newPosition;
76
+ }
77
+
78
+ getMinValue() {
79
+ return this._smallValues.peek()?.value;
80
+ }
81
+
82
+ getMaxValue() {
83
+ return this._largeValues.peek()?.value;
84
+ }
85
+
86
+ replaceFurthestValuePosition(
87
+ lowValue: number,
88
+ highValue: number,
89
+ newValue: number
90
+ ): null | number {
91
+ if (this._valueToPositionMap[newValue] !== undefined) {
92
+ console.warn(
93
+ "Shouldn't try to replace values with value already stored value in " +
94
+ 'BufferSet'
95
+ );
96
+ }
97
+ // invariant(
98
+ // this._valueToPositionMap[newValue] === undefined,
99
+ // "Shouldn't try to replace values with value already stored value in " +
100
+ // 'BufferSet'
101
+ // );
102
+
103
+ this._cleanHeaps();
104
+ if (this._smallValues.empty() || this._largeValues.empty()) {
105
+ // Threre are currently no values stored. We will have to create new
106
+ // position for this value.
107
+ return null;
108
+ }
109
+
110
+ const minValue = this._smallValues.peek()!.value;
111
+ const maxValue = this._largeValues.peek()!.value;
112
+ if (minValue >= lowValue && maxValue <= highValue) {
113
+ // All values currently stored are necessary, we can't reuse any of them.
114
+ return null;
115
+ }
116
+
117
+ let valueToReplace;
118
+ if (lowValue - minValue > maxValue - highValue) {
119
+ // minValue is further from provided range. We will reuse it's position.
120
+ valueToReplace = minValue;
121
+ this._smallValues.pop();
122
+ } else {
123
+ valueToReplace = maxValue;
124
+ this._largeValues.pop();
125
+ }
126
+ const position = this._valueToPositionMap[valueToReplace];
127
+ delete this._valueToPositionMap[valueToReplace];
128
+ this._valueToPositionMap[newValue] = position;
129
+ this._pushToHeaps(position, newValue);
130
+
131
+ return position;
132
+ }
133
+
134
+ _pushToHeaps(position: number, value: number) {
135
+ const element = {
136
+ position,
137
+ value,
138
+ };
139
+ // We can reuse the same object in both heaps, because we don't mutate them
140
+ this._smallValues.push(element);
141
+ this._largeValues.push(element);
142
+ }
143
+
144
+ _cleanHeaps() {
145
+ // We not usually only remove object from one heap while moving value.
146
+ // Here we make sure that there is no stale data on top of heaps.
147
+ this._cleanHeap(this._smallValues);
148
+ this._cleanHeap(this._largeValues);
149
+ const minHeapSize = Math.min(
150
+ this._smallValues.size(),
151
+ this._largeValues.size()
152
+ );
153
+ const maxHeapSize = Math.max(
154
+ this._smallValues.size(),
155
+ this._largeValues.size()
156
+ );
157
+ if (maxHeapSize > 10 * minHeapSize) {
158
+ // There are many old values in one of heaps. We need to get rid of them
159
+ // to not use too avoid memory leaks
160
+ this._recreateHeaps();
161
+ }
162
+ }
163
+
164
+ _recreateHeaps() {
165
+ const sourceHeap =
166
+ this._smallValues.size() < this._largeValues.size()
167
+ ? this._smallValues
168
+ : this._largeValues;
169
+ const newSmallValues = new Heap<HeapItem>(
170
+ [], // Initial data in the heap
171
+ this._smallerComparator
172
+ );
173
+ const newLargeValues = new Heap<HeapItem>(
174
+ [], // Initial datat in the heap
175
+ this._greaterComparator
176
+ );
177
+ while (!sourceHeap.empty()) {
178
+ const element = sourceHeap.pop()!;
179
+ // Push all stil valid elements to new heaps
180
+ if (this._valueToPositionMap[element.value] !== undefined) {
181
+ newSmallValues.push(element);
182
+ newLargeValues.push(element);
183
+ }
184
+ }
185
+ this._smallValues = newSmallValues;
186
+ this._largeValues = newLargeValues;
187
+ }
188
+
189
+ _cleanHeap(heap: Heap<HeapItem>) {
190
+ while (
191
+ !heap.empty() &&
192
+ this._valueToPositionMap[heap.peek()!.value] === undefined
193
+ ) {
194
+ heap.pop();
195
+ }
196
+ }
197
+
198
+ _smallerComparator(lhs: HeapItem, rhs: HeapItem) {
199
+ return lhs.value < rhs.value;
200
+ }
201
+
202
+ _greaterComparator(lhs: HeapItem, rhs: HeapItem) {
203
+ return lhs.value > rhs.value;
204
+ }
205
+ }
206
+
207
+ export default IntegerBufferSet;