import { FieldMetadata } from "../../meta/impl/FieldMetadata" ; import { SpaceSavingMap } from "../../state/impl/SpaceSavingMap" ; import { Record } from "../Record" ; import { VariableArgs } from "../../state/impl/Args" ; export class BackReferences { private associationOwnerMap = new SpaceSavingMap < FieldMetadata , SpaceSavingMap < string | undefined , ParameterizedRecordSet > > ( ) ; add ( associationField , args , ownerRecord ) { this . associationOwnerMap . computeIfAbsent ( associationField , ( ) => new SpaceSavingMap < string , ParameterizedRecordSet > ( ) ) . computeIfAbsent ( args ?. key , ( ) => new ParameterizedRecordSet ( args ) ) . add ( ownerRecord ) ; } remove ( associationField , args , ownerRecord ) { const subMap = this . associationOwnerMap . get ( associationField ) ; if ( subMap !== undefined ) { const set = subMap ?. get ( args ?. key ) ; if ( set !== undefined ) { set . remove ( ownerRecord ) ; if ( set . isEmtpty ) { subMap . remove ( args ?. key ) ; if ( subMap . isEmpty ) { this . associationOwnerMap . remove ( associationField ) ; } } } } } forEach ( callback ) { this . associationOwnerMap . forEach ( ( field , subMap ) => { subMap . forEachValue ( set => { set . forEach ( record => { callback ( field , set . args , record ) ; } ) ; } ) ; } ) ; } } class ParameterizedRecordSet { private records = new Set < Record > ( ) ; constructor ( readonly args ? ) { } add ( record ) { this . records . add ( record ) ; } remove ( record ) { this . records . delete ( record ) ; } get isEmtpty ( ) : boolean { return this . records . size === 0 ; } forEach ( callback ) { for ( const record of this . records ) { callback ( record ) ; } } } type BackReferencesCallback = ( field : FieldMetadata , args : VariableArgs | undefined , ownerRecord : Record ) => void ;