@x-oasis/integer-buffer-set 0.1.20 → 0.1.24

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/src/index.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
 
16
16
  const defaultMetaExtractor = (value) => value;
17
17
  export const defaultBufferSize = 10;
18
+ const thresholdNumber = Number.MAX_SAFE_INTEGER - 100000;
18
19
 
19
20
  // !!!!! should do meta validation...meta should has an index...
20
21
  // value: original data `index` value
@@ -34,10 +35,8 @@ export const defaultBufferSize = 10;
34
35
  // the set.
35
36
  // feature: add / delete / update item will also in consider..
36
37
  class IntegerBufferSet<Meta = any> {
37
- private _size: number;
38
38
  private _name: string;
39
39
  private _bufferSize: number;
40
- // private _positionToValueObject: ValueToPositionObject;
41
40
 
42
41
  private _indexToMetaMap: IndexToMetaMap<Meta>;
43
42
  private _metaToPositionMap: MetaToPositionMap<Meta>;
@@ -68,7 +67,6 @@ class IntegerBufferSet<Meta = any> {
68
67
  this._indexExtractor = indexExtractor;
69
68
 
70
69
  this._name = name;
71
- // this._positionToValueObject = {};
72
70
 
73
71
  /**
74
72
  * this._indexToMetaMap is used to find the prev meta when finding a position for index.
@@ -79,7 +77,6 @@ class IntegerBufferSet<Meta = any> {
79
77
  this._metaToIndexMap = new Map();
80
78
  this._onTheFlyIndices = [];
81
79
 
82
- this._size = 0;
83
80
  this._bufferSize = bufferSize;
84
81
 
85
82
  this._smallValues = new Heap([], this._smallerComparator);
@@ -87,9 +84,6 @@ class IntegerBufferSet<Meta = any> {
87
84
 
88
85
  this.getNewPositionForIndex = this.getNewPositionForIndex.bind(this);
89
86
  this.getIndexPosition = this.getIndexPosition.bind(this);
90
- this.getSize = this.getSize.bind(this);
91
- this.replacePositionInFliedIndices =
92
- this.replacePositionInFliedIndices.bind(this);
93
87
  this.replaceFurthestIndexPosition =
94
88
  this.replaceFurthestIndexPosition.bind(this);
95
89
  this._isOnTheFlyFullReturnHook = returnHook(
@@ -100,21 +94,28 @@ class IntegerBufferSet<Meta = any> {
100
94
  this._lastUpdatedMS = this._loopMS;
101
95
  }
102
96
 
103
- getSize() {
104
- return this._size;
105
- }
106
-
107
97
  get bufferSize() {
108
98
  return this._bufferSize;
109
99
  }
110
100
 
101
+ isThresholdMeta(meta) {
102
+ if (typeof meta === 'number' && meta > thresholdNumber) return true;
103
+ return false;
104
+ }
105
+
111
106
  setIsOnTheFlyFull(val: any) {
112
107
  if (val != null) {
113
- const data = this._onTheFlyIndices.filter((v) => v);
108
+ const data = this._onTheFlyIndices.filter((v) => v != null);
114
109
  this._isOnTheFlyFull = data.length === this._bufferSize;
110
+ // console.log('fly ', this._isOnTheFlyFull, data.length, this._bufferSize);
115
111
  }
116
112
  }
117
113
 
114
+ resetOnTheFlies() {
115
+ this._isOnTheFlyFull = false;
116
+ this._onTheFlyIndices = [];
117
+ }
118
+
118
119
  get isBufferFull() {
119
120
  return this._positionToMetaList.length >= this._bufferSize;
120
121
  }
@@ -123,7 +124,7 @@ class IntegerBufferSet<Meta = any> {
123
124
  const { startIndex, endIndex } = safeRange;
124
125
  for (let idx = 0; idx < this._onTheFlyIndices.length; idx++) {
125
126
  const meta = this._onTheFlyIndices[idx];
126
- const metaIndex = this._metaToIndexMap.get(meta);
127
+ const metaIndex = this.getMetaIndex(meta);
127
128
  if (!isClamped(startIndex, metaIndex, endIndex)) {
128
129
  return idx;
129
130
  }
@@ -135,15 +136,17 @@ class IntegerBufferSet<Meta = any> {
135
136
  return {
136
137
  smallValues: new Heap([], this._smallerComparator),
137
138
  largeValues: new Heap([], this._greaterComparator),
138
- valueToPositionObject: {},
139
139
  };
140
140
  }
141
141
 
142
142
  getIndexMeta(index: number) {
143
+ if (index == null || index < 0) return null;
143
144
  return this._metaExtractor(index);
144
145
  }
145
146
 
146
147
  getMetaIndex(meta: Meta) {
148
+ if (meta == null) return -1;
149
+ if (this.isThresholdMeta(meta)) return -1;
147
150
  if (this._indexExtractor) return this._indexExtractor(meta);
148
151
  return this._metaToIndexMap.get(meta);
149
152
  }
@@ -193,140 +196,19 @@ class IntegerBufferSet<Meta = any> {
193
196
  return this._largeValues.peek()?.value;
194
197
  }
195
198
 
196
- /**
197
- * values actually is the position of original data.
198
- */
199
- setValuePosition(value: number, position: number) {}
200
-
201
- findPositionMeta(position: number) {
202
- for (const [meta, pos] of this._metaToPositionMap) {
203
- if (pos === position) return meta;
204
- }
205
- return null;
206
- }
207
-
208
- rebuildHeapsWithMeta(metaToPositionMap: MetaToPositionMap<Meta>) {
209
- const { smallValues, largeValues } = this.initialize();
210
-
211
- for (const [meta, position] of metaToPositionMap) {
212
- const index = this.getMetaIndex(meta);
213
- const token = { index, position };
214
- smallValues.push(token);
215
- largeValues.push(token);
216
- }
217
-
218
- this._smallValues = smallValues;
219
- this._largeValues = largeValues;
220
- }
221
-
222
- /**
223
- *
224
- * @param position
225
- * @param value
226
- *
227
- *
228
- */
229
- setPositionIndex(position: number, index: number) {
230
- const meta = this._metaExtractor(index);
231
- const originalPosition = this._metaToPositionMap.get(meta);
232
-
233
- // current index has a position
234
- if (originalPosition !== undefined) {
235
- if (originalPosition === position) return true;
236
- this.deleteMetaIndex(meta);
237
- }
238
-
239
- const metaToReplace = this.findPositionMeta(position);
240
- if (metaToReplace) this._metaToPositionMap.delete(metaToReplace);
241
- this._metaToPositionMap.set(meta, position);
242
-
243
- this.rebuildHeapsWithMeta(this._metaToPositionMap);
244
- return true;
245
- }
246
-
247
- getMetaPosition(meta: Meta) {
248
- return this._metaToPositionMap.get(meta);
249
- }
250
-
251
- // performRangeUpdate(
252
- // startIndex: number,
253
- // endIndex: number,
254
- // safeRange: {
255
- // startIndex: number;
256
- // endIndex: number;
257
- // }
258
- // ) {
259
- // const _start = Math.max(startIndex, safeRange.startIndex);
260
- // const _end = Math.min(endIndex, safeRange.endIndex);
261
- // const primaryMetaList = [];
262
- // const secondaryMetaList = [];
263
- // const locationStartIndex = startIndex;
264
- // const targetIndices = new Array(this._bufferSize);
265
-
266
- // const _valueToPositionObject = {};
267
- // const _positionToValueObject = {};
268
-
269
- // const _valueToMetaObject = {};
270
- // const _metaToIndexMap = new Map();
271
-
272
- // for (let value = startIndex; value <= endIndex; value++) {
273
- // const meta = this._metaExtractor(value);
274
- // if (meta) {
275
- // const _i = value - locationStartIndex;
276
- // if (isClamped(value, safeRange.startIndex, safeRange.endIndex)) {
277
- // primaryMetaList[_i] = meta;
278
- // const targetIndex = this.getMetaPosition(meta);
279
- // if (isNumber(targetIndex)) {
280
- // targetIndices[targetIndex] = value;
281
- // _valueToPositionObject[value] = targetIndex;
282
- // _valueToMetaObject[value] = meta;
283
- // _metaToIndexMap.set(meta, value);
284
- // _positionToValueObject[targetIndex] = value;
285
- // }
286
- // } else {
287
- // secondaryMetaList[_i] = meta;
288
- // }
289
- // }
290
- // }
291
-
292
- // for (let idx = _start; idx <= _end; idx++) {
293
- // const meta = this._metaExtractor(idx);
294
- // if (_metaToIndexMap.get(meta) !== undefined) continue;
295
- // let p;
296
- // while (
297
- // (p =
298
- // targetIndices[
299
- // this.resolvePosition(safeRange.startIndex, safeRange.endIndex, idx)
300
- // ]) === undefined
301
- // ) {
302
- // targetIndices[p] = idx;
303
- // }
304
- // }
305
- // }
306
-
307
- replacePositionInFliedIndices(newIndex: number, safeRange: SafeRange) {
308
- const { startIndex, endIndex } = safeRange;
309
-
199
+ getFliedPosition(newIndex: number, safeRange: SafeRange) {
310
200
  if (this._isOnTheFlyFull) {
311
201
  // newIndex is not critical index, do nothing
312
- if (!isClamped(startIndex, newIndex, endIndex)) {
313
- return null;
202
+ if (
203
+ safeRange &&
204
+ isClamped(safeRange.startIndex, newIndex, safeRange.endIndex)
205
+ ) {
206
+ return this.getOnTheFlyUncriticalPosition(safeRange);
314
207
  }
315
208
  // if `newIndex` is critical index, replace an un-committed
316
209
  // index value from _onTheFlyIndices.
317
- const pos = this.getOnTheFlyUncriticalPosition(safeRange);
318
- if (pos != null) return pos;
319
- }
320
- return null;
321
- }
322
-
323
- getFliedPosition(newIndex: number, safeRange: SafeRange) {
324
- const pos = this.replacePositionInFliedIndices(newIndex, safeRange);
325
- if (pos != null) {
326
- const meta = this.getIndexMeta(newIndex);
327
- this._onTheFlyIndices[pos] = meta;
328
- this._setMetaIndex(meta, newIndex);
329
- return this._isOnTheFlyFullReturnHook(pos);
210
+ // const pos = this.getOnTheFlyUncriticalPosition(safeRange);
211
+ // if (pos != null) return pos;
330
212
  }
331
213
  return null;
332
214
  }
@@ -343,74 +225,73 @@ class IntegerBufferSet<Meta = any> {
343
225
  getPosition(newIndex: number, safeRange?: SafeRange) {
344
226
  this.prepare();
345
227
  const meta = this.getIndexMeta(newIndex);
346
- const prevMetaPosition = this._metaToPositionMap.get(meta);
347
-
348
- if (prevMetaPosition !== undefined) {
349
- const onTheFlyPositionMeta = this._onTheFlyIndices[prevMetaPosition];
350
- // the occupied meta should change position
351
- if (onTheFlyPositionMeta) {
352
- // such as place item 11 twice...
353
- if (onTheFlyPositionMeta === meta) {
354
- return prevMetaPosition;
355
- }
356
- let positionToReplace = this._replaceFurthestIndexPosition(
357
- newIndex,
358
- safeRange
359
- );
360
- if (this._isOnTheFlyFull)
361
- return this.getFliedPosition(newIndex, safeRange);
362
-
363
- while (this._onTheFlyIndices[positionToReplace]) {
364
- positionToReplace = this._replaceFurthestIndexPosition(
365
- newIndex,
366
- safeRange
367
- );
368
- }
369
-
370
- if (positionToReplace != null) {
371
- this._setMetaIndex(meta, newIndex);
372
- this._onTheFlyIndices[positionToReplace] = onTheFlyPositionMeta;
373
- return this._isOnTheFlyFullReturnHook(positionToReplace);
374
- }
375
- }
376
- this._onTheFlyIndices[prevMetaPosition] = meta;
377
- return this._isOnTheFlyFullReturnHook(prevMetaPosition);
228
+ const metaPosition = this._metaToPositionMap.get(meta);
229
+ let position, indexMeta;
230
+
231
+ // if (this._name === 'normal_goods')
232
+ // console.log(
233
+ // 'getPosition ',
234
+ // newIndex,
235
+ // !this.isBufferFull,
236
+ // this._isOnTheFlyFull,
237
+ // this._onTheFlyIndices.slice(),
238
+ // this._indexToMetaMap.get(newIndex),
239
+ // this._metaToPositionMap.get(this._indexToMetaMap.get(newIndex))
240
+ // );
241
+
242
+ if (metaPosition !== undefined) {
243
+ position = this.commitPosition({
244
+ newIndex,
245
+ meta,
246
+ safeRange,
247
+ position: metaPosition,
248
+ });
249
+ } else if (!this.isBufferFull) {
250
+ /** placed on new buffered position */
251
+ position = this.getNewPositionForIndex(newIndex);
252
+ } else if (this._isOnTheFlyFull) {
253
+ position = this.getFliedPosition(newIndex, safeRange);
254
+ } else if (
255
+ (indexMeta = this._indexToMetaMap.get(newIndex)) &&
256
+ this._metaToPositionMap.get(indexMeta)
257
+ ) {
258
+ /**
259
+ Index has already been stored, but we cant use its old position directly...
260
+ 1:index -> meta, meta may be reused later
261
+ 2: temp use index -> meta -> position, this issue should exist for follows...
262
+ */
263
+ position = this.commitPosition({
264
+ newIndex,
265
+ meta,
266
+ safeRange,
267
+ position: this._metaToPositionMap.get(indexMeta),
268
+ });
269
+ } else {
270
+ this._cleanHeaps();
271
+ // console.log('commeit ---')
272
+ position = this.commitPosition({
273
+ newIndex,
274
+ meta,
275
+ safeRange,
276
+ position: this._replaceFurthestIndexPosition(newIndex, safeRange),
277
+ });
378
278
  }
379
279
 
380
- // placed on new buffered position
381
- if (!this.isBufferFull)
382
- return this._isOnTheFlyFullReturnHook(
383
- this.getNewPositionForIndex(newIndex)
384
- );
385
-
386
- // console.log('this. fly ', this._isOnTheFlyFull)
387
- if (this._isOnTheFlyFull) return this.getFliedPosition(newIndex, safeRange);
280
+ // console.log('position ', position)
388
281
 
389
- let positionToReplace;
390
- const prevIndexMeta = this._indexToMetaMap.get(newIndex);
391
- // console.log('this. is ', this.isBufferFull, prevIndexMeta);
282
+ if (position != null) {
283
+ this._onTheFlyIndices[position] = meta;
284
+ this._setMetaIndex(meta, newIndex);
285
+ this._metaToPositionMap.set(meta, position);
392
286
 
393
- // Index has already been stored, but we cant use its old position directly...
394
- // 1:index -> meta, meta may be reused later
287
+ // this._setMetaPosition(meta, position);
288
+ // should not push to heap, pop only
289
+ // this._pushToHeaps(position, newIndex)
395
290
 
396
- // 2: temp use index -> meta -> position, this issue should exist for follows...
397
- if (!prevIndexMeta) {
398
- this._cleanHeaps();
399
- positionToReplace = this._replaceFurthestIndexPosition(
400
- newIndex,
401
- safeRange
402
- );
403
- } else {
404
- positionToReplace = this._metaToPositionMap.get(prevIndexMeta);
291
+ return this._isOnTheFlyFullReturnHook(position);
405
292
  }
406
293
 
407
- this._onTheFlyIndices[positionToReplace] = meta;
408
- this._setMetaIndex(meta, newIndex);
409
- this._setMetaPosition(meta, positionToReplace);
410
- // should not push to heap, pop only
411
- // this._pushToHeaps(positionToReplace, newIndex)
412
-
413
- return this._isOnTheFlyFullReturnHook(positionToReplace);
294
+ return null;
414
295
  }
415
296
 
416
297
  replaceFurthestIndexPosition(
@@ -442,11 +323,19 @@ class IntegerBufferSet<Meta = any> {
442
323
  );
443
324
  }
444
325
 
326
+ let indexToReplace;
327
+
445
328
  const minValue = this._smallValues.peek()!.value;
446
329
  const maxValue = this._largeValues.peek()!.value;
447
330
 
448
- // console.log('mxa ', maxValue, minValue);
449
- let indexToReplace;
331
+ // console.log('mathc ', maxValue, maxValue > thresholdNumber)
332
+ if (maxValue > thresholdNumber) {
333
+ indexToReplace = maxValue;
334
+ this._largeValues.pop();
335
+ const replacedMeta = this._indexToMetaMap.get(indexToReplace);
336
+ const position = this._metaToPositionMap.get(replacedMeta);
337
+ return position;
338
+ }
450
339
 
451
340
  if (!safeRange) {
452
341
  // far from min
@@ -495,6 +384,8 @@ class IntegerBufferSet<Meta = any> {
495
384
  const replacedMeta = this._indexToMetaMap.get(indexToReplace);
496
385
  const position = this._metaToPositionMap.get(replacedMeta);
497
386
 
387
+ // console.log('index ', indexToReplace, replacedMeta, position)
388
+
498
389
  return position;
499
390
  }
500
391
 
@@ -502,29 +393,30 @@ class IntegerBufferSet<Meta = any> {
502
393
  const indices = new Array(this.bufferSize);
503
394
  for (let idx = 0; idx < indices.length; idx++) {
504
395
  const meta = this._onTheFlyIndices[idx] || this._positionToMetaList[idx];
396
+ // console.log('ix ', idx,this.getMetaIndex(meta) )
505
397
  const targetIndex = this.getMetaIndex(meta);
506
398
  indices[idx] = targetIndex;
507
399
  }
508
400
 
509
401
  // console.log(
510
- // 'position xxx ',
402
+ // 'indices ',
511
403
  // this._positionToMetaList,
512
- // this._onTheFlyIndices
404
+ // this._onTheFlyIndices.slice(),
405
+ // indices
513
406
  // );
514
407
 
515
408
  const _arr = new Array(indices.length);
516
409
  const _available = [];
517
410
  const indexToMetaMap = new Map();
518
411
  const metaToIndexMap = new Map();
519
- const metaToPositionMap = new Map();
412
+
520
413
  for (let idx = 0; idx < indices.length; idx++) {
521
414
  const currentIndex = indices[idx];
522
415
  const currentMeta = this._metaExtractor(currentIndex);
416
+ // console.log("current ", currentIndex, currentMeta)
523
417
  if (currentMeta == null) continue;
524
-
525
418
  indexToMetaMap.set(currentIndex, currentMeta);
526
419
  metaToIndexMap.set(currentMeta, currentIndex);
527
-
528
420
  if (currentMeta === this._positionToMetaList[idx]) {
529
421
  _arr[idx] = currentMeta;
530
422
  continue;
@@ -538,74 +430,49 @@ class IntegerBufferSet<Meta = any> {
538
430
  _available.push(currentMeta);
539
431
  }
540
432
 
541
- const { smallValues, largeValues } = this.initialize();
542
433
  const positionToMetaList = [];
434
+ this._indexToMetaMap = indexToMetaMap;
435
+ this.replaceMetaToIndexMap(metaToIndexMap);
543
436
 
544
437
  for (let position = 0; position < indices.length; position++) {
545
- const value = indices[position];
546
438
  if (_arr[position] != null) {
547
439
  positionToMetaList[position] = _arr[position];
548
- metaToPositionMap.set(_arr[position], position);
549
- const element = { position, value };
550
- smallValues.push(element);
551
- largeValues.push(element);
552
440
  continue;
553
441
  }
554
442
  const meta = _available.shift();
555
443
  if (meta != null) {
556
444
  positionToMetaList[position] = meta;
557
- metaToPositionMap.set(meta, position);
558
-
559
- const element = { position, value };
560
- smallValues.push(element);
561
- largeValues.push(element);
562
445
  }
563
446
  }
564
447
 
565
- // console.log('position ', positionToMetaList, largeValues.peek().value);
566
-
567
448
  this._positionToMetaList = positionToMetaList;
568
- this._smallValues = smallValues;
569
- this._largeValues = largeValues;
570
- this._indexToMetaMap = indexToMetaMap;
571
- this.replaceMetaToIndexMap(metaToIndexMap);
572
- this._metaToPositionMap = metaToPositionMap;
573
- this._onTheFlyIndices = [];
574
449
 
575
- try {
576
- const indices = new Array(this.bufferSize);
577
- for (let idx = 0; idx < indices.length; idx++) {
578
- const meta =
579
- this._onTheFlyIndices[idx] || this._positionToMetaList[idx];
580
- const targetIndex = this.getMetaIndex(meta);
581
- if (meta != null) {
582
- indices[idx] = {
583
- meta,
584
- targetIndex,
585
- recyclerKey: `${this._name}_${idx}`,
586
- };
587
- }
588
- }
589
- return indices;
590
- } catch (err) {
591
- this.readyToStartNextLoop();
592
- return this._positionToMetaList;
593
- }
450
+ return this.getIndices();
594
451
  }
595
452
 
596
453
  // key point: `meta` should be preserved..
597
454
  getIndices() {
455
+ const { smallValues, largeValues } = this.initialize();
456
+
598
457
  try {
599
- const indices = new Array(this.bufferSize);
458
+ const indices = new Array(this._positionToMetaList.length);
459
+ const metaToPositionMap = new Map();
600
460
  for (let idx = 0; idx < indices.length; idx++) {
601
461
  const meta =
602
462
  this._onTheFlyIndices[idx] || this._positionToMetaList[idx];
603
463
  const targetIndex = this.getMetaIndex(meta);
604
464
  // which means source data has changed. such as one element has been deleted
605
- if (meta !== this.getIndexMeta(targetIndex)) {
465
+ if (
466
+ !this.isThresholdMeta(meta) &&
467
+ meta != this.getIndexMeta(targetIndex)
468
+ ) {
606
469
  return this.shuffle();
607
470
  }
608
- if (meta != null) {
471
+ if (meta != null && !this.isThresholdMeta(meta)) {
472
+ const element = { position: idx, value: targetIndex };
473
+ smallValues.push(element);
474
+ largeValues.push(element);
475
+ metaToPositionMap.set(meta, idx);
609
476
  indices[idx] = {
610
477
  meta,
611
478
  targetIndex,
@@ -613,13 +480,19 @@ class IntegerBufferSet<Meta = any> {
613
480
  };
614
481
  }
615
482
  }
616
- // clear on the fly indices after return indices.
617
- this._onTheFlyIndices = [];
483
+ this._smallValues = smallValues;
484
+ this._largeValues = largeValues;
485
+ this._metaToPositionMap = metaToPositionMap;
486
+ this._positionToMetaList = indices.map((v) => v?.meta);
487
+ this.resetOnTheFlies();
618
488
 
619
489
  return indices;
620
490
  } catch (err) {
621
- this.readyToStartNextLoop();
491
+ console.log('err ', err);
622
492
  return this._positionToMetaList;
493
+ } finally {
494
+ this.readyToStartNextLoop();
495
+ // clear on the fly indices after return indices.
623
496
  }
624
497
  }
625
498
 
@@ -631,12 +504,45 @@ class IntegerBufferSet<Meta = any> {
631
504
  }
632
505
 
633
506
  _setMetaPosition(meta: Meta, position: number) {
634
- const prevMetaOnPosition = this._positionToMetaList[position];
635
- if (prevMetaOnPosition) this._metaToPositionMap.delete(prevMetaOnPosition);
507
+ // do not delete meta2position; because getPosition will get by meta first...
508
+ // const prevMetaOnPosition = this._positionToMetaList[position];
509
+ // if (prevMetaOnPosition) this._metaToPositionMap.delete(prevMetaOnPosition);
636
510
  this._positionToMetaList[position] = meta;
637
511
  this._metaToPositionMap.set(meta, position);
638
512
  }
639
513
 
514
+ commitPosition(props: {
515
+ newIndex: number;
516
+ position: number;
517
+ meta: Meta;
518
+ safeRange: SafeRange;
519
+ }) {
520
+ const { newIndex, safeRange, position, meta } = props;
521
+ const onTheFlyPositionMeta = this._onTheFlyIndices[position];
522
+ let positionToReplace = position;
523
+
524
+ // console.log('position ', newIndex, position);
525
+
526
+ if (onTheFlyPositionMeta) {
527
+ // such as place item 11 twice...
528
+ if (onTheFlyPositionMeta === meta) return position;
529
+ if (this._isOnTheFlyFull)
530
+ return this.getFliedPosition(newIndex, safeRange);
531
+ positionToReplace = this._replaceFurthestIndexPosition(
532
+ newIndex,
533
+ safeRange
534
+ );
535
+
536
+ while (this._onTheFlyIndices[positionToReplace]) {
537
+ positionToReplace = this._replaceFurthestIndexPosition(
538
+ newIndex,
539
+ safeRange
540
+ );
541
+ }
542
+ }
543
+ return positionToReplace;
544
+ }
545
+
640
546
  /**
641
547
  *
642
548
  * @param meta
@@ -665,16 +571,21 @@ class IntegerBufferSet<Meta = any> {
665
571
 
666
572
  this._onTheFlyIndices = [];
667
573
  this._isOnTheFlyFull = false;
668
- const len = this._positionToMetaList.length;
669
-
670
- for (let index = 0; index < len; index++) {}
671
574
  }
672
575
 
673
576
  _cleanHeaps() {
674
577
  // We not usually only remove object from one heap while moving value.
675
578
  // Here we make sure that there is no stale data on top of heaps.
676
- this._cleanHeap(this._smallValues);
677
- this._cleanHeap(this._largeValues);
579
+ // this._cleanHeap(this._smallValues);
580
+ // this._cleanHeap(this._largeValues);
581
+
582
+ for (let idx = 0; idx < this._positionToMetaList.length; idx++) {
583
+ if (this._positionToMetaList[idx] == null) {
584
+ this._recreateHeaps();
585
+ return;
586
+ }
587
+ }
588
+
678
589
  const minHeapSize = Math.min(
679
590
  this._smallValues.size(),
680
591
  this._largeValues.size()
@@ -689,112 +600,49 @@ class IntegerBufferSet<Meta = any> {
689
600
  this._recreateHeaps();
690
601
  }
691
602
  }
603
+ _recreateHeaps() {
604
+ const { smallValues, largeValues } = this.initialize();
605
+ for (
606
+ let position = 0;
607
+ position < this._positionToMetaList.length;
608
+ position++
609
+ ) {
610
+ const meta = this._positionToMetaList[position];
611
+ let value = this.getMetaIndex(meta);
692
612
 
693
- rebuildHeapsWithValues(
694
- arr: Array<{
695
- position: number;
696
- value: number;
697
- }>
698
- ) {
699
- const valueToPositionObject = {};
700
- const newSmallValues = new Heap<HeapItem>([], this._smallerComparator);
701
- const newLargeValues = new Heap<HeapItem>([], this._greaterComparator);
702
-
703
- arr.forEach((element) => {
704
- const { position, value } = element;
705
- if (value !== undefined) {
706
- const element = {
707
- position,
708
- value,
709
- };
710
- newSmallValues.push(element);
711
- newLargeValues.push(element);
712
- valueToPositionObject[value] = position;
713
- }
714
- });
715
- const _arr = new Array(this._bufferSize).fill(2);
716
- Object.keys(valueToPositionObject).map(
717
- (key) => (_arr[valueToPositionObject[key]] = 1)
718
- );
719
- _arr.forEach((_i, position) => {
720
- if (_i === 2) {
721
- const value = Number.MAX_SAFE_INTEGER - position;
722
- const element = {
723
- position,
724
- value,
725
- };
726
-
727
- newSmallValues.push(element);
728
- newLargeValues.push(element);
729
- valueToPositionObject[value] = position;
613
+ if (!meta || value === -1 || value == null) {
614
+ value = Number.MAX_SAFE_INTEGER - position;
730
615
  }
731
- });
732
- this._smallValues = newSmallValues;
733
- this._largeValues = newLargeValues;
734
- }
735
-
736
- // rebuildHeaps() {
737
- // const valueToPositionObject = {};
738
- // const newSmallValues = new Heap<HeapItem>([], this._smallerComparator);
739
- // const newLargeValues = new Heap<HeapItem>([], this._greaterComparator);
740
-
741
- // const keys = Object.keys(this._positionToValueObject);
742
- // for (let position = 0; position < keys.length; position++) {
743
- // const value = this._positionToValueObject[position];
744
- // if (value !== undefined) {
745
- // const element = {
746
- // position,
747
- // value,
748
- // };
749
- // valueToPositionObject[value] = position;
750
- // newSmallValues.push(element);
751
- // newLargeValues.push(element);
752
- // }
753
- // }
754
-
755
- // this._smallValues = newSmallValues;
756
- // this._largeValues = newLargeValues;
757
- // }
758
616
 
759
- _recreateHeaps() {
760
- const sourceHeap =
761
- this._smallValues.size() < this._largeValues.size()
762
- ? this._smallValues
763
- : this._largeValues;
764
- const newSmallValues = new Heap<HeapItem>(
765
- [], // Initial data in the heap
766
- this._smallerComparator
767
- );
768
- const newLargeValues = new Heap<HeapItem>(
769
- [], // Initial datat in the heap
770
- this._greaterComparator
771
- );
772
- while (!sourceHeap.empty()) {
773
- const element = sourceHeap.pop()!;
774
- // Push all still valid elements to new heaps
775
- if (
776
- this._metaToPositionMap.get(this._indexToMetaMap.get(element.value)) !=
777
- null
778
- ) {
779
- newSmallValues.push(element);
780
- newLargeValues.push(element);
617
+ const element = { position, value };
618
+ smallValues.push(element);
619
+ largeValues.push(element);
620
+ if (value > thresholdNumber) {
621
+ // @ts-ignore
622
+ this._setMetaPosition(value, position);
623
+ // @ts-ignore
624
+ this._setMetaIndex(value, value);
781
625
  }
782
626
  }
783
- this._smallValues = newSmallValues;
784
- this._largeValues = newLargeValues;
785
- }
786
627
 
787
- _cleanHeap(heap: Heap<HeapItem>) {
788
- while (
789
- !heap.empty() &&
790
- this._metaToPositionMap.get(
791
- this._indexToMetaMap.get(heap.peek()!.value)
792
- ) == null
793
- ) {
794
- heap.pop();
795
- }
628
+ this._largeValues.peek().value;
629
+
630
+ this._smallValues = smallValues;
631
+ this._largeValues = largeValues;
796
632
  }
797
633
 
634
+ // _cleanHeap(heap: Heap<HeapItem>) {
635
+ // while (
636
+ // !heap.empty() &&
637
+ // this._metaToPositionMap.get(
638
+ // this._indexToMetaMap.get(heap.peek()!.value)
639
+ // ) == null
640
+ // ) {
641
+ // console.log('pop ---', heap.peek()!.value);
642
+ // heap.pop();
643
+ // }
644
+ // }
645
+
798
646
  _smallerComparator(lhs: HeapItem, rhs: HeapItem) {
799
647
  return lhs.value < rhs.value;
800
648
  }