mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 04:44:04 +00:00
feat: supports compact method to save memory. #91
This commit is contained in:
parent
5ff8eb97d9
commit
ac1712ba04
|
@ -19,6 +19,12 @@ import { SinglyLinkedList } from '../linked-list';
|
|||
export class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E, R>> {
|
||||
constructor(elements: Iterable<E> | Iterable<R> = [], options?: QueueOptions<E, R>) {
|
||||
super(options);
|
||||
|
||||
if (options) {
|
||||
const { autoCompactRatio = 0.5 } = options;
|
||||
this._autoCompactRatio = autoCompactRatio;
|
||||
}
|
||||
|
||||
if (elements) {
|
||||
for (const el of elements) {
|
||||
if (this.toElementFn) this.push(this.toElementFn(el as R));
|
||||
|
@ -89,6 +95,25 @@ export class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E,
|
|||
return this.size > 0 ? this.elements[this.elements.length - 1] : undefined;
|
||||
}
|
||||
|
||||
_autoCompactRatio: number = 0.5;
|
||||
|
||||
/**
|
||||
* This function returns the value of the autoCompactRatio property.
|
||||
* @returns The `autoCompactRatio` property of the object, which is a number.
|
||||
*/
|
||||
get autoCompactRatio(): number {
|
||||
return this._autoCompactRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
* The above function sets the autoCompactRatio property to a specified number in TypeScript.
|
||||
* @param {number} v - The parameter `v` represents the value that will be assigned to the
|
||||
* `_autoCompactRatio` property.
|
||||
*/
|
||||
set autoCompactRatio(v: number) {
|
||||
this._autoCompactRatio = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(n)
|
||||
|
@ -145,12 +170,7 @@ export class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E,
|
|||
const first = this.first;
|
||||
this._offset += 1;
|
||||
|
||||
if (this.offset * 2 < this.elements.length) return first;
|
||||
|
||||
// only delete dequeued elements when reaching half size
|
||||
// to decrease latency of shifting elements.
|
||||
this._elements = this.elements.slice(this.offset);
|
||||
this._offset = 0;
|
||||
if (this.offset / this.elements.length > this.autoCompactRatio) this.compact();
|
||||
return first;
|
||||
}
|
||||
|
||||
|
@ -237,6 +257,17 @@ export class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E,
|
|||
this._offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `compact` function in TypeScript slices the elements array based on the offset and resets the
|
||||
* offset to zero.
|
||||
* @returns The `compact()` method is returning a boolean value of `true`.
|
||||
*/
|
||||
compact(): boolean {
|
||||
this._elements = this.elements.slice(this.offset);
|
||||
this._offset = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(n)
|
||||
|
@ -317,7 +348,7 @@ export class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E,
|
|||
*
|
||||
* The function `_getIterator` returns an iterable iterator for the elements in the class.
|
||||
*/
|
||||
protected* _getIterator(): IterableIterator<E> {
|
||||
protected *_getIterator(): IterableIterator<E> {
|
||||
for (const item of this.elements.slice(this.offset)) {
|
||||
yield item;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { IterableElementBaseOptions } from '../base';
|
||||
|
||||
export type QueueOptions<E, R> = IterableElementBaseOptions<E, R> & {};
|
||||
export type QueueOptions<E, R> = IterableElementBaseOptions<E, R> & {
|
||||
autoCompactRatio?: number;
|
||||
};
|
||||
|
|
|
@ -90,6 +90,16 @@ describe('Queue', () => {
|
|||
expect(queue.isEmpty()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('compact method should work well', () => {
|
||||
for (let i = 0; i < 1000; i++) queue.push(i);
|
||||
|
||||
for (let i = 0; i < 499; i++) queue.shift();
|
||||
|
||||
expect(queue.elements.length).toBe(1000);
|
||||
queue.compact();
|
||||
expect(queue.elements.length).toBe(501);
|
||||
});
|
||||
|
||||
test('should at after shifting', () => {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
queue.push(i);
|
||||
|
@ -116,7 +126,10 @@ describe('Queue', () => {
|
|||
});
|
||||
|
||||
it('should object queue map & filter', function () {
|
||||
const queue = new Queue<{ a: string; key: number }>([
|
||||
const queue = new Queue<{
|
||||
a: string;
|
||||
key: number;
|
||||
}>([
|
||||
{ key: 1, a: 'a1' },
|
||||
{ key: 6, a: 'a6' },
|
||||
{ key: 5, a: 'a5' },
|
||||
|
|
Loading…
Reference in a new issue