fix(Objectmap): switch to an object map with unique keys
This commit is contained in:
parent
9d756dbff7
commit
b880036b64
39
package-lock.json
generated
39
package-lock.json
generated
@ -385,6 +385,17 @@
|
|||||||
"luxon": "^1.16.0"
|
"luxon": "^1.16.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@pushrocks/smartunique": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartunique/-/smartunique-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-xBu9ZB4C0BA0S/pbFFZn2ItPfnodPKpzrYIq1yN5XDs6OaookwcDF/iBwfS9+EYMSPENC9wAsOxg2RGMm4Qicw==",
|
||||||
|
"requires": {
|
||||||
|
"@types/shortid": "^0.0.29",
|
||||||
|
"@types/uuid": "^3.0.0",
|
||||||
|
"shortid": "^2.2.8",
|
||||||
|
"uuid": "^3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@pushrocks/tapbundle": {
|
"@pushrocks/tapbundle": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2ftapbundle/-/tapbundle-3.2.0.tgz",
|
"resolved": "https://verdaccio.lossless.one/@pushrocks%2ftapbundle/-/tapbundle-3.2.0.tgz",
|
||||||
@ -540,6 +551,11 @@
|
|||||||
"resolved": "https://verdaccio.lossless.one/@types%2fnode/-/node-13.7.0.tgz",
|
"resolved": "https://verdaccio.lossless.one/@types%2fnode/-/node-13.7.0.tgz",
|
||||||
"integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ=="
|
"integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ=="
|
||||||
},
|
},
|
||||||
|
"@types/shortid": {
|
||||||
|
"version": "0.0.29",
|
||||||
|
"resolved": "https://verdaccio.lossless.one/@types%2fshortid/-/shortid-0.0.29.tgz",
|
||||||
|
"integrity": "sha1-gJPuBBam4r8qpjOBCRFLP7/6Dps="
|
||||||
|
},
|
||||||
"@types/through2": {
|
"@types/through2": {
|
||||||
"version": "2.0.34",
|
"version": "2.0.34",
|
||||||
"resolved": "https://verdaccio.lossless.one/@types%2fthrough2/-/through2-2.0.34.tgz",
|
"resolved": "https://verdaccio.lossless.one/@types%2fthrough2/-/through2-2.0.34.tgz",
|
||||||
@ -549,6 +565,11 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/uuid": {
|
||||||
|
"version": "3.4.7",
|
||||||
|
"resolved": "https://verdaccio.lossless.one/@types%2fuuid/-/uuid-3.4.7.tgz",
|
||||||
|
"integrity": "sha512-C2j2FWgQkF1ru12SjZJyMaTPxs/f6n90+5G5qNakBxKXjTBc/YTSelHh4Pz1HUDwxFXD9WvpQhOGCDC+/Y4mIQ=="
|
||||||
|
},
|
||||||
"@types/vinyl": {
|
"@types/vinyl": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://verdaccio.lossless.one/@types%2fvinyl/-/vinyl-2.0.3.tgz",
|
"resolved": "https://verdaccio.lossless.one/@types%2fvinyl/-/vinyl-2.0.3.tgz",
|
||||||
@ -1259,6 +1280,11 @@
|
|||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"nanoid": {
|
||||||
|
"version": "2.1.11",
|
||||||
|
"resolved": "https://verdaccio.lossless.one/nanoid/-/nanoid-2.1.11.tgz",
|
||||||
|
"integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA=="
|
||||||
|
},
|
||||||
"nice-try": {
|
"nice-try": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://verdaccio.lossless.one/nice-try/-/nice-try-1.0.5.tgz",
|
"resolved": "https://verdaccio.lossless.one/nice-try/-/nice-try-1.0.5.tgz",
|
||||||
@ -1542,6 +1568,14 @@
|
|||||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
|
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"shortid": {
|
||||||
|
"version": "2.2.15",
|
||||||
|
"resolved": "https://verdaccio.lossless.one/shortid/-/shortid-2.2.15.tgz",
|
||||||
|
"integrity": "sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==",
|
||||||
|
"requires": {
|
||||||
|
"nanoid": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"signal-exit": {
|
"signal-exit": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://verdaccio.lossless.one/signal-exit/-/signal-exit-3.0.2.tgz",
|
"resolved": "https://verdaccio.lossless.one/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||||
@ -1755,6 +1789,11 @@
|
|||||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://verdaccio.lossless.one/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
},
|
||||||
"vinyl": {
|
"vinyl": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://verdaccio.lossless.one/vinyl/-/vinyl-2.2.0.tgz",
|
"resolved": "https://verdaccio.lossless.one/vinyl/-/vinyl-2.2.0.tgz",
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
"@pushrocks/smartpromise": "^3.0.6",
|
"@pushrocks/smartpromise": "^3.0.6",
|
||||||
"@pushrocks/smartrx": "^2.0.5",
|
"@pushrocks/smartrx": "^2.0.5",
|
||||||
"@pushrocks/smarttime": "^3.0.12",
|
"@pushrocks/smarttime": "^3.0.12",
|
||||||
|
"@pushrocks/smartunique": "^3.0.1",
|
||||||
"@types/minimatch": "^3.0.3",
|
"@types/minimatch": "^3.0.3",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
"symbol-tree": "^3.2.4"
|
"symbol-tree": "^3.2.4"
|
||||||
|
@ -1,11 +1,41 @@
|
|||||||
import * as plugins from './lik.plugins';
|
import * as plugins from './lik.plugins';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fast map allows for very quick lookups of objects with a unique key
|
||||||
|
*/
|
||||||
export class FastMap<T> {
|
export class FastMap<T> {
|
||||||
private mapObject: { [key: string]: T } = {};
|
private mapObject: { [key: string]: T } = {};
|
||||||
|
|
||||||
public isUniqueKey() {}
|
public isUniqueKey(keyArg: string): boolean {
|
||||||
|
return this.mapObject[keyArg] ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
public addToMap(identifier: string, objectArg: T) {
|
public addToMap(keyArg: string, objectArg: T): boolean {
|
||||||
this.mapObject[identifier] = objectArg;
|
if (this.isUniqueKey(keyArg)) {
|
||||||
|
this.mapObject[keyArg] = objectArg;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getByKey(keyArg: string) {
|
||||||
|
return this.mapObject[keyArg];
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeFromMap(keyArg): T {
|
||||||
|
const removedItem = this.getByKey(keyArg);
|
||||||
|
delete this.mapObject[keyArg];
|
||||||
|
return removedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getKeys() {
|
||||||
|
const keys: string[] = [];
|
||||||
|
for (const keyArg in this.mapObject) {
|
||||||
|
if (this.mapObject[keyArg]) {
|
||||||
|
keys.push(keyArg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,12 @@ export class LoopTracker<T> {
|
|||||||
* checks and tracks an object
|
* checks and tracks an object
|
||||||
* @param objectArg
|
* @param objectArg
|
||||||
*/
|
*/
|
||||||
checkAndTrack(objectArg: T) {
|
checkAndTrack(objectArg: T): boolean {
|
||||||
return this.referenceObjectMap.add(objectArg);
|
if (!this.referenceObjectMap.checkForObject(objectArg)) {
|
||||||
|
this.referenceObjectMap.add(objectArg);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ export interface IObjectmapFindFunction<T> {
|
|||||||
*/
|
*/
|
||||||
export class Objectmap<T> {
|
export class Objectmap<T> {
|
||||||
private fastMap = new FastMap<T>();
|
private fastMap = new FastMap<T>();
|
||||||
private objectArray: T[] = [];
|
|
||||||
|
|
||||||
// events
|
// events
|
||||||
public eventSubject = new plugins.smartrx.rxjs.Subject<any>();
|
public eventSubject = new plugins.smartrx.rxjs.Subject<any>();
|
||||||
@ -30,45 +29,51 @@ export class Objectmap<T> {
|
|||||||
* adds an object mapped to a string
|
* adds an object mapped to a string
|
||||||
* the string must be unique
|
* the string must be unique
|
||||||
*/
|
*/
|
||||||
addMappedUnique(uniqueKey: string, objectArg: T) {
|
addMappedUnique(uniqueKeyArg: string, objectArg: T) {
|
||||||
this.add(objectArg);
|
this.fastMap.addToMap(uniqueKeyArg, objectArg);
|
||||||
this.fastMap.addToMap(uniqueKey, objectArg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fastest way to get an object from the map
|
* fastest way to get an object from the map
|
||||||
* @param uniqueKey
|
* @param uniqueKey
|
||||||
*/
|
*/
|
||||||
public getMappedUnique(uniqueKey: string) {}
|
public getMappedUnique(uniqueKeyArg: string) {
|
||||||
|
return this.fastMap.getByKey(uniqueKeyArg);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove key
|
* remove key
|
||||||
* @param functionArg
|
* @param functionArg
|
||||||
*/
|
*/
|
||||||
public removeMappedUnique() {}
|
public removeMappedUnique(uniqueKey: string) {
|
||||||
|
const object = this.getMappedUnique(uniqueKey);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add object to Objectmap
|
* add object to Objectmap
|
||||||
* returns false if the object is already in the map
|
* returns false if the object is already in the map
|
||||||
* returns true if the object was added successfully
|
* returns true if the object was added successfully
|
||||||
*/
|
*/
|
||||||
public add(objectArg: T): boolean {
|
public add(objectArg: T): string {
|
||||||
if (this.checkForObject(objectArg)) {
|
// lets search for an existing unique key
|
||||||
// the object is already in the objectmap
|
for (const keyArg of this.fastMap.getKeys()) {
|
||||||
return false;
|
const object = this.fastMap.getByKey(keyArg);
|
||||||
} else {
|
if (object === objectArg) {
|
||||||
// the object is not yet in the objectmap
|
return keyArg;
|
||||||
this.objectArray.push(objectArg);
|
|
||||||
this.eventSubject.next('add');
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// otherwise lets create it
|
||||||
|
const uniqueKey = plugins.smartunique.shortId();
|
||||||
|
this.addMappedUnique(uniqueKey, objectArg);
|
||||||
|
return uniqueKey;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* like .add but adds an whole array of objects
|
* like .add but adds an whole array of objects
|
||||||
*/
|
*/
|
||||||
public addArray(objectArrayArg: T[]) {
|
public addArray(objectArrayArg: T[]) {
|
||||||
for (let item of objectArrayArg) {
|
for (const item of objectArrayArg) {
|
||||||
this.add(item);
|
this.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,19 +81,34 @@ export class Objectmap<T> {
|
|||||||
/**
|
/**
|
||||||
* check if object is in Objectmap
|
* check if object is in Objectmap
|
||||||
*/
|
*/
|
||||||
public checkForObject(objectArg: T) {
|
public checkForObject(objectArg: T): boolean {
|
||||||
return this.objectArray.indexOf(objectArg) !== -1;
|
return !!this.getKeyForObject(objectArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get key for object
|
||||||
|
* @param findFunction
|
||||||
|
*/
|
||||||
|
public getKeyForObject(objectArg: T) {
|
||||||
|
let foundKey: string = null;
|
||||||
|
for (const keyArg of this.fastMap.getKeys()) {
|
||||||
|
if (!foundKey && this.fastMap.getByKey(keyArg) === objectArg) {
|
||||||
|
foundKey = keyArg;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foundKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find object
|
* find object
|
||||||
*/
|
*/
|
||||||
public find(findFunction: IObjectmapFindFunction<T>) {
|
public find(findFunction: IObjectmapFindFunction<T>): T {
|
||||||
const resultArray = this.objectArray.filter(findFunction);
|
for (const keyArg of this.fastMap.getKeys()) {
|
||||||
if (resultArray.length > 0) {
|
if (findFunction(this.fastMap.getByKey(keyArg))) {
|
||||||
return resultArray[0];
|
return this.getMappedUnique(keyArg);
|
||||||
} else {
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,8 +127,8 @@ export class Objectmap<T> {
|
|||||||
* run function for each item in Objectmap
|
* run function for each item in Objectmap
|
||||||
*/
|
*/
|
||||||
public async forEach(functionArg: IObjectmapForEachFunction<T>) {
|
public async forEach(functionArg: IObjectmapForEachFunction<T>) {
|
||||||
for (let object of this.objectArray) {
|
for (const keyArg of this.fastMap.getKeys()) {
|
||||||
await functionArg(object);
|
await functionArg(this.fastMap.getByKey(keyArg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +136,9 @@ export class Objectmap<T> {
|
|||||||
* gets an object in the Observablemap and removes it, so it can't be retrieved again
|
* gets an object in the Observablemap and removes it, so it can't be retrieved again
|
||||||
*/
|
*/
|
||||||
public getOneAndRemove(): T {
|
public getOneAndRemove(): T {
|
||||||
const removedItem = this.objectArray.shift();
|
const keys = this.fastMap.getKeys();
|
||||||
|
const keyToUse = keys[keys.length - 1];
|
||||||
|
const removedItem = this.fastMap.removeFromMap(keyToUse);
|
||||||
this.eventSubject.next('remove');
|
this.eventSubject.next('remove');
|
||||||
return removedItem;
|
return removedItem;
|
||||||
}
|
}
|
||||||
@ -126,8 +148,8 @@ export class Objectmap<T> {
|
|||||||
*/
|
*/
|
||||||
public getArray(): T[] {
|
public getArray(): T[] {
|
||||||
const returnArray: any[] = [];
|
const returnArray: any[] = [];
|
||||||
for (const objectItem of this.objectArray) {
|
for (const keyArg of this.fastMap.getKeys()) {
|
||||||
returnArray.push(objectItem);
|
returnArray.push(this.fastMap.getByKey(keyArg));
|
||||||
}
|
}
|
||||||
return returnArray;
|
return returnArray;
|
||||||
}
|
}
|
||||||
@ -136,32 +158,29 @@ export class Objectmap<T> {
|
|||||||
* check if Objectmap ist empty
|
* check if Objectmap ist empty
|
||||||
*/
|
*/
|
||||||
public isEmpty(): boolean {
|
public isEmpty(): boolean {
|
||||||
if (this.objectArray.length === 0) {
|
return this.fastMap.getKeys().length === 0;
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove object from Objectmap
|
* remove object from Objectmap
|
||||||
*/
|
*/
|
||||||
public remove(objectArg: T) {
|
public remove(objectArg: T): T {
|
||||||
let replacementArray = [];
|
if (this.checkForObject(objectArg)) {
|
||||||
for (let item of this.objectArray) {
|
const keyArg = this.getKeyForObject(objectArg);
|
||||||
if (item !== objectArg) {
|
const removedObject = this.fastMap.removeFromMap(keyArg);
|
||||||
replacementArray.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.objectArray = replacementArray;
|
|
||||||
this.eventSubject.next('remove');
|
this.eventSubject.next('remove');
|
||||||
|
return removedObject;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wipe Objectmap
|
* wipe Objectmap
|
||||||
*/
|
*/
|
||||||
public wipe() {
|
public wipe() {
|
||||||
this.objectArray = [];
|
for (const keyArg of this.fastMap.getKeys()) {
|
||||||
this.eventSubject.next('wiped');
|
this.fastMap.removeFromMap(keyArg);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,9 @@ import * as smartdelay from '@pushrocks/smartdelay';
|
|||||||
import * as smartpromise from '@pushrocks/smartpromise';
|
import * as smartpromise from '@pushrocks/smartpromise';
|
||||||
import * as smartrx from '@pushrocks/smartrx';
|
import * as smartrx from '@pushrocks/smartrx';
|
||||||
import * as smarttime from '@pushrocks/smarttime';
|
import * as smarttime from '@pushrocks/smarttime';
|
||||||
|
import * as smartunique from '@pushrocks/smartunique';
|
||||||
|
|
||||||
export { smartdelay, smartpromise, smartrx, smarttime };
|
export { smartdelay, smartpromise, smartrx, smarttime, smartunique };
|
||||||
|
|
||||||
// ==============
|
// ==============
|
||||||
// third party
|
// third party
|
||||||
|
Loading…
Reference in New Issue
Block a user