diff --git a/app/src/apps/BenchmarkApp/strategies/DecisionMatrixStrategy/structs/DecisionSegments.ts b/app/src/apps/BenchmarkApp/strategies/DecisionMatrixStrategy/structs/DecisionSegments.ts index e404bcff..adc897f5 100644 --- a/app/src/apps/BenchmarkApp/strategies/DecisionMatrixStrategy/structs/DecisionSegments.ts +++ b/app/src/apps/BenchmarkApp/strategies/DecisionMatrixStrategy/structs/DecisionSegments.ts @@ -8,28 +8,13 @@ import { ExpansionTypes } from 'apps/BenchmarkApp/strategies/DecisionMatrixStrat const TooltipEffortPointsManhattanDistance = 'Effort points (EP) are calculated based upon the unweighted Manhattan distance of both base values.'; -export const InitialEffort: DecisionRowAlgorithm[] = [ - { - title: 'Matching Solution Type', - selector: (anEntity) => - anEntity.softKPIs?.integrationEffort?.solutionType?.join(', ') ?? '?', - }, - { - title: 'Use Case', - selector: (anEntity) => - anEntity.softKPIs?.integrationEffort?.useCase?.join(', ') ?? '?', - }, +export const IntegrationExpenditures: DecisionRowAlgorithm[] = [ { title: 'General Costs', selector: (anEntity) => (anEntity.softKPIs?.integrationEffort?.generalCosts?.toString() ?? '?') + ' €', }, - { - title: 'Deployment Type', - selector: (anEntity) => - anEntity.softKPIs?.integrationEffort?.deploymentType?.join(', ') ?? '?', - }, { title: 'Installation Effort', selector: (anEntity) => @@ -60,7 +45,7 @@ export const InitialEffort: DecisionRowAlgorithm[] = [ }, ]; -export const ContinuousEffort: DecisionRowAlgorithm[] = [ +export const ConfigurationExpenditures: DecisionRowAlgorithm[] = [ { title: 'Matching Solution Effort', selector: (anEntity) => @@ -117,6 +102,24 @@ export const ContinuousEffort: DecisionRowAlgorithm[] = [ '?') + ' man-hr', expandedBy: ExpansionTypes.DomainEffort, }, +]; + +const CategoricalSoftKPIs: DecisionRowAlgorithm[] = [ + { + title: 'Matching Solution Type', + selector: (anEntity) => + anEntity.softKPIs?.integrationEffort?.solutionType?.join(', ') ?? '?', + }, + { + title: 'Use Case', + selector: (anEntity) => + anEntity.softKPIs?.integrationEffort?.useCase?.join(', ') ?? '?', + }, + { + title: 'Deployment Type', + selector: (anEntity) => + anEntity.softKPIs?.integrationEffort?.deploymentType?.join(', ') ?? '?', + }, { title: 'Interfaces', selector: (anEntity) => @@ -132,12 +135,16 @@ export const ContinuousEffort: DecisionRowAlgorithm[] = [ // eslint-disable-next-line @typescript-eslint/no-explicit-any export const DecisionSegments: DecisionSegmentEntity[] = [ { - title: 'Initial Effort', - children: InitialEffort, + title: 'Integration Expenditures', + children: IntegrationExpenditures, + }, + { + title: 'Configuration Expenditures', + children: ConfigurationExpenditures, }, { - title: 'Continuous Effort', - children: ContinuousEffort, + title: 'Categorical Soft KPIs', + children: CategoricalSoftKPIs, }, { title: 'Macro Average Metrics', diff --git a/wrapper/src/api/providers/benchmark/cache/basicCache.ts b/wrapper/src/api/providers/benchmark/cache/basicCache.ts index 6f2313c1..a850f156 100644 --- a/wrapper/src/api/providers/benchmark/cache/basicCache.ts +++ b/wrapper/src/api/providers/benchmark/cache/basicCache.ts @@ -22,7 +22,7 @@ export abstract class BasicBenchmarkCache< if (!intersection) { intersection = this.createAndCache(baseConfig, key); } else { - intersection.access(config); + intersection.access(this.mapBaseConfigToCustomConfig(baseConfig)); } return intersection; } diff --git a/wrapper/src/api/providers/experiment/file/experimentInserter.ts b/wrapper/src/api/providers/experiment/file/experimentInserter.ts index 799dc7e1..e5ac1f8c 100644 --- a/wrapper/src/api/providers/experiment/file/experimentInserter.ts +++ b/wrapper/src/api/providers/experiment/file/experimentInserter.ts @@ -27,6 +27,7 @@ export abstract class ExperimentInserter { private table: ExperimentTable | undefined = undefined; private numberOfUploadedRecords = 0; private unionFind: UnionFind; + private seenIdPairs = new Set(); constructor( protected readonly experimentId: ExperimentId, @@ -62,19 +63,35 @@ export abstract class ExperimentInserter { ): void { this.numberOfUploadedRecords++; [id1, id2] = [id1, id2].sort(); - const table = this.getOrCreateTable(similarityScores); - table.batchUpsert( - [ - () => - this.rowToInsertParameters( - id1, - id2, - detectedAsDuplicate, - similarityScores - ), - ], - INSERT_BATCH_SIZE - ); + if (this.isValidPair(id1, id2)) { + const table = this.getOrCreateTable(similarityScores); + table.batchUpsert( + [ + () => + this.rowToInsertParameters( + id1, + id2, + detectedAsDuplicate, + similarityScores + ), + ], + INSERT_BATCH_SIZE + ); + } + } + + private isValidPair(id1: string, id2: string) { + if (id1 === id2) { + return false; + } + + const idPair = encodeURIComponent(id1) + '/' + id2; + if (this.seenIdPairs.has(idPair)) { + return false; + } + + this.seenIdPairs.add(idPair); + return true; } private getOrCreateTable(similarityScores: {