@x-oasis/integer-buffer-set 0.1.17 → 0.1.19

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/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ declare class IntegerBufferSet {
8
8
  private _valueToPositionMap;
9
9
  private _smallValues;
10
10
  private _largeValues;
11
+ private _vacantPositions;
11
12
  constructor();
12
13
  getSize(): number;
13
14
  get indices(): any[];
@@ -15,6 +16,7 @@ declare class IntegerBufferSet {
15
16
  getNewPositionForValue(value: number): number;
16
17
  getMinValue(): number;
17
18
  getMaxValue(): number;
19
+ setPositionValue(position: number, value: number): void;
18
20
  replaceFurthestValuePosition(lowValue: number, highValue: number, newValue: number, useMinValueFn?: (options: {
19
21
  safeRange: {
20
22
  lowValue: number;
@@ -57,6 +57,7 @@ var IntegerBufferSet = /*#__PURE__*/function () {
57
57
  this.getValuePosition = this.getValuePosition.bind(this);
58
58
  this.getSize = this.getSize.bind(this);
59
59
  this.replaceFurthestValuePosition = this.replaceFurthestValuePosition.bind(this);
60
+ this._vacantPositions = [];
60
61
  }
61
62
  var _proto = IntegerBufferSet.prototype;
62
63
  _proto.getSize = function getSize() {
@@ -86,6 +87,17 @@ var IntegerBufferSet = /*#__PURE__*/function () {
86
87
  var _this$_largeValues$pe;
87
88
  return (_this$_largeValues$pe = this._largeValues.peek()) == null ? void 0 : _this$_largeValues$pe.value;
88
89
  };
90
+ _proto.setPositionValue = function setPositionValue(position, value) {
91
+ var originalPosition = this._valueToPositionMap[value];
92
+ if (originalPosition !== undefined) {
93
+ var index = this._vacantPositions.findIndex(function (v) {
94
+ return v === originalPosition;
95
+ });
96
+ if (index === -1) this._vacantPositions.push(originalPosition);
97
+ delete this._valueToPositionMap[value];
98
+ this._valueToPositionMap[value] = position;
99
+ }
100
+ };
89
101
  _proto.replaceFurthestValuePosition = function replaceFurthestValuePosition(lowValue, highValue, newValue, useMinValueFn) {
90
102
  if (useMinValueFn === void 0) {
91
103
  useMinValueFn = defaultUseMinValueFn;
@@ -97,6 +109,12 @@ var IntegerBufferSet = /*#__PURE__*/function () {
97
109
  if (this._smallValues.empty() || this._largeValues.empty()) {
98
110
  return null;
99
111
  }
112
+ if (this._vacantPositions.length) {
113
+ var _position = this._vacantPositions.pop();
114
+ this._valueToPositionMap[newValue] = _position;
115
+ this._pushToHeaps(_position, newValue);
116
+ return _position;
117
+ }
100
118
  var minValue = this._smallValues.peek().value;
101
119
  var maxValue = this._largeValues.peek().value;
102
120
  if (minValue >= lowValue && maxValue <= highValue) {
@@ -124,6 +142,10 @@ var IntegerBufferSet = /*#__PURE__*/function () {
124
142
  delete this._valueToPositionMap[valueToReplace];
125
143
  this._valueToPositionMap[newValue] = position;
126
144
  this._pushToHeaps(position, newValue);
145
+ var _i = this._vacantPositions.findIndex(function (v) {
146
+ return v === position;
147
+ });
148
+ if (_i !== -1) this._vacantPositions.splice(_i, 1);
127
149
  return position;
128
150
  };
129
151
  _proto._pushToHeaps = function _pushToHeaps(position, value) {
@@ -1 +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\nconst defaultUseMinValueFn = (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n}) => {\n const { safeRange, bufferSetRange } = options;\n const { lowValue, highValue } = safeRange;\n const { maxValue, minValue } = bufferSetRange;\n return lowValue - minValue > maxValue - highValue;\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 useMinValueFn: (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n }) => boolean = defaultUseMinValueFn\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 (\n useMinValueFn({\n safeRange: {\n lowValue,\n highValue,\n },\n bufferSetRange: {\n minValue,\n maxValue,\n },\n currentIndex: newValue,\n })\n ) {\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":["defaultUseMinValueFn","options","safeRange","bufferSetRange","lowValue","highValue","maxValue","minValue","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","newValue","useMinValueFn","_cleanHeaps","empty","valueToReplace","currentIndex","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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"}
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\nconst defaultUseMinValueFn = (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n}) => {\n const { safeRange, bufferSetRange } = options;\n const { lowValue, highValue } = safeRange;\n const { maxValue, minValue } = bufferSetRange;\n return lowValue - minValue > maxValue - highValue;\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 private _vacantPositions: Array<number>;\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 this._vacantPositions = [];\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 setPositionValue(position: number, value: number) {\n const originalPosition = this._valueToPositionMap[value];\n if (originalPosition !== undefined) {\n const index = this._vacantPositions.findIndex(\n (v) => v === originalPosition\n );\n if (index === -1) this._vacantPositions.push(originalPosition);\n delete this._valueToPositionMap[value];\n this._valueToPositionMap[value] = position;\n }\n }\n\n replaceFurthestValuePosition(\n lowValue: number,\n highValue: number,\n newValue: number,\n useMinValueFn: (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n }) => boolean = defaultUseMinValueFn\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 if (this._vacantPositions.length) {\n const position = this._vacantPositions.pop();\n this._valueToPositionMap[newValue] = position;\n this._pushToHeaps(position, newValue);\n return position;\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 (\n useMinValueFn({\n safeRange: {\n lowValue,\n highValue,\n },\n bufferSetRange: {\n minValue,\n maxValue,\n },\n currentIndex: newValue,\n })\n ) {\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 const _i = this._vacantPositions.findIndex((v) => v === position);\n if (_i !== -1) this._vacantPositions.splice(_i, 1);\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":["defaultUseMinValueFn","options","safeRange","bufferSetRange","lowValue","highValue","maxValue","minValue","IntegerBufferSet","_valueToPositionMap","_size","_smallValues","Heap","_smallerComparator","_largeValues","_greaterComparator","getNewPositionForValue","bind","getValuePosition","getSize","replaceFurthestValuePosition","_vacantPositions","_proto","prototype","value","undefined","console","warn","newPosition","_pushToHeaps","getMinValue","_this$_smallValues$pe","peek","getMaxValue","_this$_largeValues$pe","setPositionValue","position","originalPosition","index","findIndex","v","push","newValue","useMinValueFn","_cleanHeaps","empty","length","pop","valueToReplace","currentIndex","_i","splice","element","_cleanHeap","minHeapSize","Math","min","size","maxHeapSize","max","_recreateHeaps","sourceHeap","newSmallValues","newLargeValues","heap","lhs","rhs","_createClass","key","get","indices"],"mappings":"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"}
@@ -1,2 +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,a=function(e){var t=e.safeRange,a=e.bufferSetRange;return t.lowValue-a.minValue>a.maxValue-t.highValue};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,s,l=e.prototype;return l.getSize=function(){return this._size},l.getValuePosition=function(e){return void 0===this._valueToPositionMap[e]?null:this._valueToPositionMap[e]},l.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},l.getMinValue=function(){var e;return null==(e=this._smallValues.peek())?void 0:e.value},l.getMaxValue=function(){var e;return null==(e=this._largeValues.peek())?void 0:e.value},l.replaceFurthestValuePosition=function(e,t,i,s){if(void 0===s&&(s=a),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 l,o=this._smallValues.peek().value,r=this._largeValues.peek().value;if(o>=e&&r<=t)return null;s({safeRange:{lowValue:e,highValue:t},bufferSetRange:{minValue:o,maxValue:r},currentIndex:i})?(l=o,this._smallValues.pop()):(l=r,this._largeValues.pop());var u=this._valueToPositionMap[l];return delete this._valueToPositionMap[l],this._valueToPositionMap[i]=u,this._pushToHeaps(u,i),u},l._pushToHeaps=function(e,t){var a={position:e,value:t};this._smallValues.push(a),this._largeValues.push(a)},l._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()},l._recreateHeaps=function(){for(var e=this._smallValues.size()<this._largeValues.size()?this._smallValues:this._largeValues,a=new t([],this._smallerComparator),i=new t([],this._greaterComparator);!e.empty();){var s=e.pop();void 0!==this._valueToPositionMap[s.value]&&(a.push(s),i.push(s))}this._smallValues=a,this._largeValues=i},l._cleanHeap=function(e){for(;!e.empty()&&void 0===this._valueToPositionMap[e.peek().value];)e.pop()},l._smallerComparator=function(e,t){return e.value<t.value},l._greaterComparator=function(e,t){return e.value>t.value},i=e,(s=[{key:"indices",get:function(){var e=[];for(var t in this._valueToPositionMap)e[this._valueToPositionMap[t]]=t;return e}}])&&function(e,t){for(var a=0;a<t.length;a++){var i=t[a];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,"symbol"==typeof(s=function(e,t){if("object"!=typeof e||null===e)return e;var a=e[Symbol.toPrimitive];if(void 0!==a){var i=a.call(e,"string");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(i.key))?s:String(s),i)}var s}(i.prototype,s),Object.defineProperty(i,"prototype",{writable:!1}),e}();
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,i=function(e){var t=e.safeRange,i=e.bufferSetRange;return t.lowValue-i.minValue>i.maxValue-t.highValue};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),this._vacantPositions=[]}var a,s,o=e.prototype;return o.getSize=function(){return this._size},o.getValuePosition=function(e){return void 0===this._valueToPositionMap[e]?null:this._valueToPositionMap[e]},o.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},o.getMinValue=function(){var e;return null==(e=this._smallValues.peek())?void 0:e.value},o.getMaxValue=function(){var e;return null==(e=this._largeValues.peek())?void 0:e.value},o.setPositionValue=function(e,t){var i=this._valueToPositionMap[t];void 0!==i&&(-1===this._vacantPositions.findIndex((function(e){return e===i}))&&this._vacantPositions.push(i),delete this._valueToPositionMap[t],this._valueToPositionMap[t]=e)},o.replaceFurthestValuePosition=function(e,t,a,s){if(void 0===s&&(s=i),void 0!==this._valueToPositionMap[a]&&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;if(this._vacantPositions.length){var o=this._vacantPositions.pop();return this._valueToPositionMap[a]=o,this._pushToHeaps(o,a),o}var l,n=this._smallValues.peek().value,r=this._largeValues.peek().value;if(n>=e&&r<=t)return null;s({safeRange:{lowValue:e,highValue:t},bufferSetRange:{minValue:n,maxValue:r},currentIndex:a})?(l=n,this._smallValues.pop()):(l=r,this._largeValues.pop());var u=this._valueToPositionMap[l];delete this._valueToPositionMap[l],this._valueToPositionMap[a]=u,this._pushToHeaps(u,a);var h=this._vacantPositions.findIndex((function(e){return e===u}));return-1!==h&&this._vacantPositions.splice(h,1),u},o._pushToHeaps=function(e,t){var i={position:e,value:t};this._smallValues.push(i),this._largeValues.push(i)},o._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()},o._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},o._cleanHeap=function(e){for(;!e.empty()&&void 0===this._valueToPositionMap[e.peek().value];)e.pop()},o._smallerComparator=function(e,t){return e.value<t.value},o._greaterComparator=function(e,t){return e.value>t.value},a=e,(s=[{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}(a.prototype,s),Object.defineProperty(a,"prototype",{writable:!1}),e}();
2
2
  //# sourceMappingURL=integer-buffer-set.cjs.production.min.js.map
@@ -1 +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\nconst defaultUseMinValueFn = (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n}) => {\n const { safeRange, bufferSetRange } = options;\n const { lowValue, highValue } = safeRange;\n const { maxValue, minValue } = bufferSetRange;\n return lowValue - minValue > maxValue - highValue;\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 useMinValueFn: (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n }) => boolean = defaultUseMinValueFn\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 (\n useMinValueFn({\n safeRange: {\n lowValue,\n highValue,\n },\n bufferSetRange: {\n minValue,\n maxValue,\n },\n currentIndex: newValue,\n })\n ) {\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":["defaultUseMinValueFn","options","safeRange","bufferSetRange","lowValue","minValue","maxValue","highValue","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","newValue","useMinValueFn","_cleanHeaps","empty","valueToReplace","currentIndex","pop","position","element","push","_cleanHeap","minHeapSize","Math","min","size","max","_recreateHeaps","sourceHeap","newSmallValues","newLargeValues","heap","lhs","rhs","key","get","indices"],"mappings":"wJAQMA,EAAuB,SAACC,GAW5B,IAAQC,EAA8BD,EAA9BC,UAAWC,EAAmBF,EAAnBE,eAGnB,OAFgCD,EAAxBE,SACuBD,EAAbE,SAAaF,EAAvBG,SADwBJ,EAAdK,sCAwBlB,SAAAC,IACEC,KAAKC,oBAAsB,GAC3BD,KAAKE,MAAQ,EACbF,KAAKG,aAAe,IAAIC,EAAK,GAAIJ,KAAKK,oBACtCL,KAAKM,aAAe,IAAIF,EAAK,GAAIJ,KAAKO,oBAEtCP,KAAKQ,uBAAyBR,KAAKQ,uBAAuBC,KAAKT,MAC/DA,KAAKU,iBAAmBV,KAAKU,iBAAiBD,KAAKT,MACnDA,KAAKW,QAAUX,KAAKW,QAAQF,KAAKT,MACjCA,KAAKY,6BACHZ,KAAKY,6BAA6BH,KAAKT,MAC1C,QAAAa,EAAAd,EAAAe,UAaA,OAbAD,EAEDF,QAAA,WACE,OAAOX,KAAKE,OACbW,EAWDH,iBAAA,SAAiBK,GACf,YAAwCC,IAApChB,KAAKC,oBAAoBc,GACpB,KAEFf,KAAKC,oBAAoBc,IACjCF,EAEDL,uBAAA,SAAuBO,QACmBC,IAApChB,KAAKC,oBAAoBc,IAC3BE,QAAQC,KACN,4EAOJ,IAAMC,EAAcnB,KAAKE,MAIzB,OAHAF,KAAKE,QACLF,KAAKoB,aAAaD,EAAaJ,GAC/Bf,KAAKC,oBAAoBc,GAASI,EAC3BA,GACRN,EAEDQ,YAAA,iBACE,cAAAC,EAAOtB,KAAKG,aAAaoB,eAAlBD,EAA0BP,OAClCF,EAEDW,YAAA,iBACE,cAAAC,EAAOzB,KAAKM,aAAaiB,eAAlBE,EAA0BV,OAClCF,EAEDD,6BAAA,SACEjB,EACAG,EACA4B,EACAC,GAyBA,YAzBAA,IAAAA,EAUgBpC,QAE2ByB,IAAvChB,KAAKC,oBAAoByB,IAC3BT,QAAQC,KACN,gFAUJlB,KAAK4B,cACD5B,KAAKG,aAAa0B,SAAW7B,KAAKM,aAAauB,QAGjD,OAAO,KAGT,IAOIC,EAPElC,EAAWI,KAAKG,aAAaoB,OAAQR,MACrClB,EAAWG,KAAKM,aAAaiB,OAAQR,MAC3C,GAAInB,GAAYD,GAAYE,GAAYC,EAEtC,OAAO,KAKP6B,EAAc,CACZlC,UAAW,CACTE,SAAAA,EACAG,UAAAA,GAEFJ,eAAgB,CACdE,SAAAA,EACAC,SAAAA,GAEFkC,aAAcL,KAKhBI,EAAiBlC,EACjBI,KAAKG,aAAa6B,QAElBF,EAAiBjC,EACjBG,KAAKM,aAAa0B,OAEpB,IAAMC,EAAWjC,KAAKC,oBAAoB6B,GAK1C,cAJO9B,KAAKC,oBAAoB6B,GAChC9B,KAAKC,oBAAoByB,GAAYO,EACrCjC,KAAKoB,aAAaa,EAAUP,GAErBO,GACRpB,EAEDO,aAAA,SAAaa,EAAkBlB,GAC7B,IAAMmB,EAAU,CACdD,SAAAA,EACAlB,MAAAA,GAGFf,KAAKG,aAAagC,KAAKD,GACvBlC,KAAKM,aAAa6B,KAAKD,IACxBrB,EAEDe,YAAA,WAGE5B,KAAKoC,WAAWpC,KAAKG,cACrBH,KAAKoC,WAAWpC,KAAKM,cACrB,IAAM+B,EAAcC,KAAKC,IACvBvC,KAAKG,aAAaqC,OAClBxC,KAAKM,aAAakC,QAEAF,KAAKG,IACvBzC,KAAKG,aAAaqC,OAClBxC,KAAKM,aAAakC,QAEF,GAAKH,GAGrBrC,KAAK0C,kBAER7B,EAED6B,eAAA,WAaE,IAZA,IAAMC,EACJ3C,KAAKG,aAAaqC,OAASxC,KAAKM,aAAakC,OACzCxC,KAAKG,aACLH,KAAKM,aACLsC,EAAiB,IAAIxC,EACzB,GACAJ,KAAKK,oBAEDwC,EAAiB,IAAIzC,EACzB,GACAJ,KAAKO,qBAECoC,EAAWd,SAAS,CAC1B,IAAMK,EAAUS,EAAWX,WAEqBhB,IAA5ChB,KAAKC,oBAAoBiC,EAAQnB,SACnC6B,EAAeT,KAAKD,GACpBW,EAAeV,KAAKD,IAGxBlC,KAAKG,aAAeyC,EACpB5C,KAAKM,aAAeuC,GACrBhC,EAEDuB,WAAA,SAAWU,GACT,MACGA,EAAKjB,cAC2Cb,IAAjDhB,KAAKC,oBAAoB6C,EAAKvB,OAAQR,QAEtC+B,EAAKd,OAERnB,EAEDR,mBAAA,SAAmB0C,EAAeC,GAChC,OAAOD,EAAIhC,MAAQiC,EAAIjC,OACxBF,EAEDN,mBAAA,SAAmBwC,EAAeC,GAChC,OAAOD,EAAIhC,MAAQiC,EAAIjC,SACxBhB,OAAAkD,cAAAC,IAvLD,WACE,IAAMC,EAAU,GAChB,IAAK,IAAMF,KAAOjD,KAAKC,oBAErBkD,EADcnD,KAAKC,oBAAoBgD,IACtBA,EAEnB,OAAOE,ogBACRpD"}
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\nconst defaultUseMinValueFn = (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n}) => {\n const { safeRange, bufferSetRange } = options;\n const { lowValue, highValue } = safeRange;\n const { maxValue, minValue } = bufferSetRange;\n return lowValue - minValue > maxValue - highValue;\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 private _vacantPositions: Array<number>;\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 this._vacantPositions = [];\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 setPositionValue(position: number, value: number) {\n const originalPosition = this._valueToPositionMap[value];\n if (originalPosition !== undefined) {\n const index = this._vacantPositions.findIndex(\n (v) => v === originalPosition\n );\n if (index === -1) this._vacantPositions.push(originalPosition);\n delete this._valueToPositionMap[value];\n this._valueToPositionMap[value] = position;\n }\n }\n\n replaceFurthestValuePosition(\n lowValue: number,\n highValue: number,\n newValue: number,\n useMinValueFn: (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n }) => boolean = defaultUseMinValueFn\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 if (this._vacantPositions.length) {\n const position = this._vacantPositions.pop();\n this._valueToPositionMap[newValue] = position;\n this._pushToHeaps(position, newValue);\n return position;\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 (\n useMinValueFn({\n safeRange: {\n lowValue,\n highValue,\n },\n bufferSetRange: {\n minValue,\n maxValue,\n },\n currentIndex: newValue,\n })\n ) {\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 const _i = this._vacantPositions.findIndex((v) => v === position);\n if (_i !== -1) this._vacantPositions.splice(_i, 1);\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":["defaultUseMinValueFn","options","safeRange","bufferSetRange","lowValue","minValue","maxValue","highValue","IntegerBufferSet","this","_valueToPositionMap","_size","_smallValues","Heap","_smallerComparator","_largeValues","_greaterComparator","getNewPositionForValue","bind","getValuePosition","getSize","replaceFurthestValuePosition","_vacantPositions","_proto","prototype","value","undefined","console","warn","newPosition","_pushToHeaps","getMinValue","_this$_smallValues$pe","peek","getMaxValue","_this$_largeValues$pe","setPositionValue","position","originalPosition","findIndex","v","push","newValue","useMinValueFn","_cleanHeaps","empty","length","pop","valueToReplace","currentIndex","_i","splice","element","_cleanHeap","minHeapSize","Math","min","size","max","_recreateHeaps","sourceHeap","newSmallValues","newLargeValues","heap","lhs","rhs","key","get","indices"],"mappings":"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"}
@@ -51,6 +51,7 @@ var IntegerBufferSet = /*#__PURE__*/function () {
51
51
  this.getValuePosition = this.getValuePosition.bind(this);
52
52
  this.getSize = this.getSize.bind(this);
53
53
  this.replaceFurthestValuePosition = this.replaceFurthestValuePosition.bind(this);
54
+ this._vacantPositions = [];
54
55
  }
55
56
  var _proto = IntegerBufferSet.prototype;
56
57
  _proto.getSize = function getSize() {
@@ -80,6 +81,17 @@ var IntegerBufferSet = /*#__PURE__*/function () {
80
81
  var _this$_largeValues$pe;
81
82
  return (_this$_largeValues$pe = this._largeValues.peek()) == null ? void 0 : _this$_largeValues$pe.value;
82
83
  };
84
+ _proto.setPositionValue = function setPositionValue(position, value) {
85
+ var originalPosition = this._valueToPositionMap[value];
86
+ if (originalPosition !== undefined) {
87
+ var index = this._vacantPositions.findIndex(function (v) {
88
+ return v === originalPosition;
89
+ });
90
+ if (index === -1) this._vacantPositions.push(originalPosition);
91
+ delete this._valueToPositionMap[value];
92
+ this._valueToPositionMap[value] = position;
93
+ }
94
+ };
83
95
  _proto.replaceFurthestValuePosition = function replaceFurthestValuePosition(lowValue, highValue, newValue, useMinValueFn) {
84
96
  if (useMinValueFn === void 0) {
85
97
  useMinValueFn = defaultUseMinValueFn;
@@ -91,6 +103,12 @@ var IntegerBufferSet = /*#__PURE__*/function () {
91
103
  if (this._smallValues.empty() || this._largeValues.empty()) {
92
104
  return null;
93
105
  }
106
+ if (this._vacantPositions.length) {
107
+ var _position = this._vacantPositions.pop();
108
+ this._valueToPositionMap[newValue] = _position;
109
+ this._pushToHeaps(_position, newValue);
110
+ return _position;
111
+ }
94
112
  var minValue = this._smallValues.peek().value;
95
113
  var maxValue = this._largeValues.peek().value;
96
114
  if (minValue >= lowValue && maxValue <= highValue) {
@@ -118,6 +136,10 @@ var IntegerBufferSet = /*#__PURE__*/function () {
118
136
  delete this._valueToPositionMap[valueToReplace];
119
137
  this._valueToPositionMap[newValue] = position;
120
138
  this._pushToHeaps(position, newValue);
139
+ var _i = this._vacantPositions.findIndex(function (v) {
140
+ return v === position;
141
+ });
142
+ if (_i !== -1) this._vacantPositions.splice(_i, 1);
121
143
  return position;
122
144
  };
123
145
  _proto._pushToHeaps = function _pushToHeaps(position, value) {
@@ -1 +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\nconst defaultUseMinValueFn = (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n}) => {\n const { safeRange, bufferSetRange } = options;\n const { lowValue, highValue } = safeRange;\n const { maxValue, minValue } = bufferSetRange;\n return lowValue - minValue > maxValue - highValue;\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 useMinValueFn: (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n }) => boolean = defaultUseMinValueFn\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 (\n useMinValueFn({\n safeRange: {\n lowValue,\n highValue,\n },\n bufferSetRange: {\n minValue,\n maxValue,\n },\n currentIndex: newValue,\n })\n ) {\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":["defaultUseMinValueFn","options","safeRange","bufferSetRange","lowValue","highValue","maxValue","minValue","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","newValue","useMinValueFn","_cleanHeaps","empty","valueToReplace","currentIndex","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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"}
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\nconst defaultUseMinValueFn = (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n}) => {\n const { safeRange, bufferSetRange } = options;\n const { lowValue, highValue } = safeRange;\n const { maxValue, minValue } = bufferSetRange;\n return lowValue - minValue > maxValue - highValue;\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 private _vacantPositions: Array<number>;\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 this._vacantPositions = [];\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 setPositionValue(position: number, value: number) {\n const originalPosition = this._valueToPositionMap[value];\n if (originalPosition !== undefined) {\n const index = this._vacantPositions.findIndex(\n (v) => v === originalPosition\n );\n if (index === -1) this._vacantPositions.push(originalPosition);\n delete this._valueToPositionMap[value];\n this._valueToPositionMap[value] = position;\n }\n }\n\n replaceFurthestValuePosition(\n lowValue: number,\n highValue: number,\n newValue: number,\n useMinValueFn: (options: {\n safeRange: {\n lowValue: number;\n highValue: number;\n };\n bufferSetRange: {\n maxValue: number;\n minValue: number;\n };\n currentIndex: number;\n }) => boolean = defaultUseMinValueFn\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 if (this._vacantPositions.length) {\n const position = this._vacantPositions.pop();\n this._valueToPositionMap[newValue] = position;\n this._pushToHeaps(position, newValue);\n return position;\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 (\n useMinValueFn({\n safeRange: {\n lowValue,\n highValue,\n },\n bufferSetRange: {\n minValue,\n maxValue,\n },\n currentIndex: newValue,\n })\n ) {\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 const _i = this._vacantPositions.findIndex((v) => v === position);\n if (_i !== -1) this._vacantPositions.splice(_i, 1);\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":["defaultUseMinValueFn","options","safeRange","bufferSetRange","lowValue","highValue","maxValue","minValue","IntegerBufferSet","_valueToPositionMap","_size","_smallValues","Heap","_smallerComparator","_largeValues","_greaterComparator","getNewPositionForValue","bind","getValuePosition","getSize","replaceFurthestValuePosition","_vacantPositions","_proto","prototype","value","undefined","console","warn","newPosition","_pushToHeaps","getMinValue","_this$_smallValues$pe","peek","getMaxValue","_this$_largeValues$pe","setPositionValue","position","originalPosition","index","findIndex","v","push","newValue","useMinValueFn","_cleanHeaps","empty","length","pop","valueToReplace","currentIndex","_i","splice","element","_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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-oasis/integer-buffer-set",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "IntegerBufferSet function",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -16,7 +16,7 @@
16
16
  "tsdx": "^0.14.1"
17
17
  },
18
18
  "dependencies": {
19
- "@x-oasis/heap": "0.1.17"
19
+ "@x-oasis/heap": "0.1.19"
20
20
  },
21
21
  "scripts": {
22
22
  "build": "tsdx build --tsconfig tsconfig.build.json",
package/src/index.ts CHANGED
@@ -41,6 +41,7 @@ class IntegerBufferSet {
41
41
  };
42
42
  private _smallValues: Heap<HeapItem>;
43
43
  private _largeValues: Heap<HeapItem>;
44
+ private _vacantPositions: Array<number>;
44
45
 
45
46
  constructor() {
46
47
  this._valueToPositionMap = {};
@@ -53,6 +54,8 @@ class IntegerBufferSet {
53
54
  this.getSize = this.getSize.bind(this);
54
55
  this.replaceFurthestValuePosition =
55
56
  this.replaceFurthestValuePosition.bind(this);
57
+
58
+ this._vacantPositions = [];
56
59
  }
57
60
 
58
61
  getSize() {
@@ -100,6 +103,18 @@ class IntegerBufferSet {
100
103
  return this._largeValues.peek()?.value;
101
104
  }
102
105
 
106
+ setPositionValue(position: number, value: number) {
107
+ const originalPosition = this._valueToPositionMap[value];
108
+ if (originalPosition !== undefined) {
109
+ const index = this._vacantPositions.findIndex(
110
+ (v) => v === originalPosition
111
+ );
112
+ if (index === -1) this._vacantPositions.push(originalPosition);
113
+ delete this._valueToPositionMap[value];
114
+ this._valueToPositionMap[value] = position;
115
+ }
116
+ }
117
+
103
118
  replaceFurthestValuePosition(
104
119
  lowValue: number,
105
120
  highValue: number,
@@ -135,6 +150,13 @@ class IntegerBufferSet {
135
150
  return null;
136
151
  }
137
152
 
153
+ if (this._vacantPositions.length) {
154
+ const position = this._vacantPositions.pop();
155
+ this._valueToPositionMap[newValue] = position;
156
+ this._pushToHeaps(position, newValue);
157
+ return position;
158
+ }
159
+
138
160
  const minValue = this._smallValues.peek()!.value;
139
161
  const maxValue = this._largeValues.peek()!.value;
140
162
  if (minValue >= lowValue && maxValue <= highValue) {
@@ -169,6 +191,9 @@ class IntegerBufferSet {
169
191
  this._valueToPositionMap[newValue] = position;
170
192
  this._pushToHeaps(position, newValue);
171
193
 
194
+ const _i = this._vacantPositions.findIndex((v) => v === position);
195
+ if (_i !== -1) this._vacantPositions.splice(_i, 1);
196
+
172
197
  return position;
173
198
  }
174
199