Files
lik/ts/classes.backpressuredarray.ts

87 lines
2.0 KiB
TypeScript
Raw Normal View History

2024-02-25 13:01:06 +01:00
import * as plugins from './classes.plugins.js';
2023-11-13 14:40:01 +01:00
export class BackpressuredArray<T> {
2023-11-13 16:43:06 +01:00
public data: T[];
2023-11-13 14:40:01 +01:00
private highWaterMark: number;
2023-11-13 16:27:04 +01:00
public hasSpace = new plugins.smartrx.rxjs.Subject<'hasSpace'>();
2023-11-13 17:20:45 +01:00
private itemsAvailable = new plugins.smartrx.rxjs.Subject<'itemsAvailable'>();
private isDestroyed = false;
2023-11-13 14:40:01 +01:00
constructor(highWaterMark: number = 16) {
this.data = [];
this.highWaterMark = highWaterMark;
}
push(item: T): boolean {
this.data.push(item);
2023-11-13 17:20:45 +01:00
this.itemsAvailable.next('itemsAvailable');
2023-11-13 14:40:01 +01:00
const spaceAvailable = this.checkSpaceAvailable();
if (spaceAvailable) {
2023-11-13 16:27:04 +01:00
this.hasSpace.next('hasSpace');
2023-11-13 14:40:01 +01:00
}
2023-11-13 17:20:45 +01:00
return spaceAvailable;
2023-11-13 14:40:01 +01:00
}
shift(): T | undefined {
const item = this.data.shift();
if (this.checkSpaceAvailable()) {
2023-11-13 16:27:04 +01:00
this.hasSpace.next('hasSpace');
2023-11-13 14:40:01 +01:00
}
return item;
}
checkSpaceAvailable(): boolean {
return this.data.length < this.highWaterMark;
}
2023-11-13 14:59:03 +01:00
public checkHasItems(): boolean {
return this.data.length > 0;
}
2023-11-13 14:59:03 +01:00
waitForSpace(): Promise<void> {
return new Promise<void>((resolve) => {
if (this.checkSpaceAvailable() || this.isDestroyed) {
2023-11-13 14:59:03 +01:00
resolve();
} else {
const subscription = this.hasSpace.subscribe({
next: () => {
subscription.unsubscribe();
resolve();
},
complete: () => {
resolve();
},
2023-11-13 14:59:03 +01:00
});
}
});
}
2023-11-13 17:20:45 +01:00
waitForItems(): Promise<void> {
return new Promise<void>((resolve) => {
if (this.data.length > 0 || this.isDestroyed) {
2023-11-13 17:20:45 +01:00
resolve();
} else {
const subscription = this.itemsAvailable.subscribe({
next: () => {
subscription.unsubscribe();
resolve();
},
complete: () => {
resolve();
},
2023-11-13 17:20:45 +01:00
});
}
});
}
/**
* destroys the BackpressuredArray, completing all subjects
*/
public destroy() {
this.isDestroyed = true;
this.hasSpace.complete();
this.itemsAvailable.complete();
}
2023-11-13 14:40:01 +01:00
}