@inversifyjs/core
Version:
InversifyJs core package
100 lines • 3.74 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OneToManyMapStar = void 0;
const NOT_FOUND_INDEX = -1;
/**
* Data structure able to efficiently manage a set of models related to a set of properties in a one to many relation.
*/
class OneToManyMapStar {
#modelToRelationMap;
#relationToModelsMaps;
#spec;
constructor(spec) {
this.#modelToRelationMap = new Map();
this.#relationToModelsMaps = {};
for (const specProperty of Reflect.ownKeys(spec)) {
this.#relationToModelsMaps[specProperty] = new Map();
}
this.#spec = spec;
}
add(model, relation) {
this.#buildOrGetModelArray(model).push(relation);
for (const relationKey of Reflect.ownKeys(relation)) {
this.#buildOrGetRelationModels(relationKey, relation[relationKey]).push(model);
}
}
clone() {
const properties = Reflect.ownKeys(this.#spec);
const clone = new OneToManyMapStar(this.#spec);
this.#pushEntriesIntoMap(this.#modelToRelationMap, clone.#modelToRelationMap);
for (const property of properties) {
this.#pushEntriesIntoMap(this.#relationToModelsMaps[property], clone.#relationToModelsMaps[property]);
}
return clone;
}
get(key, value) {
return this.#relationToModelsMaps[key].get(value);
}
getAllKeys(key) {
return this.#relationToModelsMaps[key].keys();
}
removeByRelation(key, value) {
const models = this.get(key, value);
if (models === undefined) {
return;
}
const uniqueModelsSet = new Set(models);
for (const model of uniqueModelsSet) {
const relations = this.#modelToRelationMap.get(model);
if (relations === undefined) {
throw new Error('Expecting model relation, none found');
}
for (const relation of relations) {
if (relation[key] === value) {
this.#removeModelFromRelationMaps(model, relation);
}
}
this.#modelToRelationMap.delete(model);
}
}
#buildOrGetModelArray(model) {
let relations = this.#modelToRelationMap.get(model);
if (relations === undefined) {
relations = [];
this.#modelToRelationMap.set(model, relations);
}
return relations;
}
#buildOrGetRelationModels(relationKey, relationValue) {
let models = this.#relationToModelsMaps[relationKey].get(relationValue);
if (models === undefined) {
models = [];
this.#relationToModelsMaps[relationKey].set(relationValue, models);
}
return models;
}
#pushEntriesIntoMap(source, target) {
for (const [key, value] of source) {
target.set(key, [...value]);
}
}
#removeModelFromRelationMaps(model, relation) {
for (const relationKey of Reflect.ownKeys(relation)) {
this.#removeModelFromRelationMap(model, relationKey, relation[relationKey]);
}
}
#removeModelFromRelationMap(model, relationKey, relationValue) {
const relationModels = this.#relationToModelsMaps[relationKey].get(relationValue);
if (relationModels !== undefined) {
const index = relationModels.indexOf(model);
if (index !== NOT_FOUND_INDEX) {
relationModels.splice(index, 1);
}
if (relationModels.length === 0) {
this.#relationToModelsMaps[relationKey].delete(relationValue);
}
}
}
}
exports.OneToManyMapStar = OneToManyMapStar;
//# sourceMappingURL=OneToManyMapStar.js.map