Files
lik/ts/classes.interestmap.ts

140 lines
4.2 KiB
TypeScript
Raw Normal View History

2022-05-27 17:53:02 +02:00
/* ===========
The InterestMap is an mechanism that collects interests into something
An interest is expressed by an object, string or number.
A comparison func can be specified to make interests comparable
For every unique interestId an interest is created.
Subssequent interests will be mapped to the same interest
which is then is only fullfilled once.
=========== */
2024-02-25 13:01:06 +01:00
import * as plugins from './classes.plugins.js';
import { ObjectMap } from './classes.objectmap.js';
import { Interest } from './classes.interestmap.interest.js';
2018-11-23 20:33:44 +01:00
export type IInterestComparisonFunc<T> = (objectArg: T) => string;
2020-07-14 01:11:48 +00:00
export interface IInterestMapOptions {
markLostAfterDefault?: number;
}
2018-11-23 20:33:44 +01:00
export class InterestMap<DTInterestId, DTInterestFullfillment> {
2020-07-14 01:11:48 +00:00
public options: IInterestMapOptions;
2018-11-23 20:33:44 +01:00
/**
* stores interests that are currently fullfilled by the cache
*/
private interestObjectMap = new ObjectMap<Interest<DTInterestId, DTInterestFullfillment>>();
2018-11-23 20:33:44 +01:00
/**
* O(1) lookup of interests by their comparison string
*/
private interestsByComparisonString = new Map<string, Interest<DTInterestId, DTInterestFullfillment>>();
2018-11-23 20:33:44 +01:00
/**
* a function to compare interests
*/
private comparisonFunc: IInterestComparisonFunc<DTInterestId>;
2020-11-24 18:53:28 +00:00
constructor(
comparisonFuncArg: IInterestComparisonFunc<DTInterestId>,
optionsArg: IInterestMapOptions = {}
) {
2018-11-23 20:33:44 +01:00
this.comparisonFunc = comparisonFuncArg;
2020-07-14 01:11:48 +00:00
this.options = optionsArg;
2018-11-23 20:33:44 +01:00
}
/**
* adds an interest to the InterestMap
2022-05-27 17:53:02 +02:00
* @param interestId
2018-11-23 20:33:44 +01:00
*/
public async addInterest(
2022-05-27 17:53:02 +02:00
interestId: DTInterestId,
2020-07-14 10:55:48 +00:00
defaultFullfillmentArg?: DTInterestFullfillment
2018-11-23 20:33:44 +01:00
): Promise<Interest<DTInterestId, DTInterestFullfillment>> {
2022-05-27 17:53:02 +02:00
const comparisonString = this.comparisonFunc(interestId);
2018-11-23 20:33:44 +01:00
let returnInterest: Interest<DTInterestId, DTInterestFullfillment>;
const existingInterest = this.interestsByComparisonString.get(comparisonString);
if (existingInterest) {
returnInterest = existingInterest;
returnInterest.renew();
} else {
returnInterest = new Interest<DTInterestId, DTInterestFullfillment>(
this,
interestId,
this.comparisonFunc,
{
markLostAfterDefault: this.options.markLostAfterDefault,
defaultFullfillment: defaultFullfillmentArg,
}
);
this.interestObjectMap.add(returnInterest);
this.interestsByComparisonString.set(comparisonString, returnInterest);
2018-11-23 20:33:44 +01:00
}
this.interestObservable.push(returnInterest);
return returnInterest;
}
public interestObservable = new plugins.smartrx.ObservableIntake<Interest<DTInterestId, any>>();
/**
* removes an interest from the interest map
*/
public removeInterest(interestArg: Interest<DTInterestId, DTInterestFullfillment>) {
this.interestObjectMap.findOneAndRemoveSync((interestArg2) => {
2018-11-23 20:33:44 +01:00
return interestArg.comparisonString === interestArg2.comparisonString;
});
this.interestsByComparisonString.delete(interestArg.comparisonString);
2018-11-23 20:33:44 +01:00
}
/**
* check interest
*/
public checkInterest(objectArg: DTInterestId): boolean {
const comparisonString = this.comparisonFunc(objectArg);
return this.checkInterestByString(comparisonString);
}
/**
* checks an interest
* @param comparisonStringArg
*/
public checkInterestByString(comparisonStringArg: string): boolean {
return this.interestsByComparisonString.has(comparisonStringArg);
2018-11-23 20:33:44 +01:00
}
/**
* inform lost interest
2018-12-11 01:36:14 +01:00
* @param interestId
2018-11-23 20:33:44 +01:00
*/
2018-12-11 01:36:14 +01:00
public informLostInterest(interestId: DTInterestId) {
2018-11-23 20:33:44 +01:00
const wantedInterest = this.findInterest(interestId);
if (wantedInterest) {
wantedInterest.markLost();
}
}
/**
* finds an interest
2022-05-27 17:53:02 +02:00
* @param interestId
2018-11-23 20:33:44 +01:00
*/
2022-05-27 17:53:02 +02:00
public findInterest(interestId: DTInterestId): Interest<DTInterestId, DTInterestFullfillment> {
const comparableString = this.comparisonFunc(interestId);
return this.interestsByComparisonString.get(comparableString) ?? null;
2018-11-23 20:33:44 +01:00
}
/**
* destroys the InterestMap and cleans up all resources
*/
public destroy() {
const interests = this.interestObjectMap.getArray();
for (const interest of interests) {
interest.destroy();
}
this.interestObjectMap.wipe();
this.interestsByComparisonString.clear();
this.interestObservable.signalComplete();
}
2018-11-23 20:33:44 +01:00
}