Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend derivation rules to create new instances of table or entity #316

Conversation

marcboulle
Copy link
Collaborator

Première version de l'implémentation des règles de création d'instance

  • série de commit par point d'étapes

Objectif du merge

  • incorporer les développements ayant atteint une stabilité suffisant pour un premier point d'étape
  • pour ne pas trop charger un branche qui risque de venir trop "lourde"

Objectif du review:

  • relecture conjointe avec les reviewers des notes de commit pour donner une vue d'ensemble macroscopique sur les impacts de cette nouvelle fonctionnalité

@marcboulle marcboulle linked an issue Jun 26, 2024 that may be closed by this pull request
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch 5 times, most recently from 7dbd2d8 to cce3753 Compare July 2, 2024 15:02
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch 8 times, most recently from fcd1ecf to 167d697 Compare July 10, 2024 07:49
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch 4 times, most recently from fcf8cee to 2101699 Compare July 16, 2024 11:37
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch 2 times, most recently from aab9f37 to 1d23f2b Compare July 19, 2024 12:47
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch from 1d23f2b to 913a58a Compare August 13, 2024 07:11
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch 2 times, most recently from 84ede03 to b004dc9 Compare November 7, 2024 16:12
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch 5 times, most recently from e8d0ef0 to 5e57f31 Compare November 25, 2024 10:34
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch 4 times, most recently from cc89dec to ec63195 Compare November 29, 2024 14:29
@marcboulle marcboulle requested review from lucaurelien and removed request for alexisbondu December 2, 2024 09:48
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch 2 times, most recently from c77f2fb to b4bd3cf Compare December 2, 2024 17:02
Copy link
Collaborator

@popescu-v popescu-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few minor comments on the code.

Pour une instruction exploitee uniquement en debug, on utilise la macro debug en laissant le ';' a la fin
Exemples:
- "debug(int nValue);"
- debug(nValue = 0);

Nettoyage des anciens patterns qui etaient mal geres par le pretty printer.
A eviter:
- "debug(int nValue;);"
- "debug(int nValue;)"
KWAttribute::Check
- transformation des warnings en erreurs
- ajout d'un controle specifique au type TextList, qui ne peut ete natif et doit etre associe a une regle de derivation

Test dans LearningTest\TestKhiops\Bugs\DicoTypeWithMissingRule

Modification des tests unitaires de KWClass and KWClassDomain pour ne plus creer de variable de type TextList
En effet, ce type de variable ne peut etre natif (une regle de derivation est obligatoire), et cela
provoque une erreur de compilation des dictionnaires
Contexte:
- la methode KWDerivationRule::Compile est optimisee en ne se declenchant pas
  si la regle est deja optimisee (IsCompiled)
- cependant, quand la methode est reimplementee, cette optimisation n'est pas effectuee
  lors des reimplementations.
- cela declenche de nombreuses re-compilations des regles associees a des attributs utilises
  en operandes de plusieurs regles de derivation

Correction, uniquement dans les methodes controlant le declenhement de la compilation:
- KWAttribute::Compile
- KWAttributeBlock::Compile
- KWDerivationRuleOperand::Compile

Resultats observes: environ 40% de compilation de regles en moins

Tests complets sur LearningTest (full)
Tests preliminaires en utilisant les regles existantes avec reimplementation de
 la methode GetReference a false pour indiquer que la Table en sortie est cree.

Creation d'un prototype de regle creant une vue en sortie: "ProtoBuildTableView"
- ajout de Learning/KWDRRuleLibrary/KWDRTableCreation.h, .cpp
- classe KWDRProtoBuildTableView pour prototyper le cas standard d'une vue
  - reimplementation de la methode GetReference, en retournant false
  - test en renvoyant en sortie la meme classe qu'en entree
- test additionnels:
  - creation d'objets en sortie d'une classe differente de celle en entree
  - propagation des calculs sur les objets crees
- teste dans LearningTest\TestKhiops\z_TableCreationRules\TableCreationRules
  - cela marche correctement, y compris pour la gestion de la memoire

Ce prototype indique que le framework existant des regles de derivation est un bon point de depart.

Prise en compte de vue comportant des Entity ou des Table natives
Dans ce cas, la vue recopie les attribut correspondant de l'objet source de la vue, mais ceux ci-ne doivent pas
etre detruits au moment de la destruction de l'objet de type vue

KWObject:
- Set|GetViewTypeUse
	// Indicateur de type vue pour un object, selon le type de creation d'un objet (cf. lCreationIndex)
	// - utilisation standard:
	//   - les attributs natifs de type Entity ou Table sont crees a partir des lectures dans une database
	//   - il sont detruits avec l'objet
	// - utilisation de type vue:
	//   - les attributs natifs de type Entity ou Table sont recopies a partir d'objets sources au moment
	//     de la creation de l'objet via une regle de derivation de creation de Table
	//   - il ne sont pas detruits avec l'objet, car deja detruits avec l'objet source
- lCreationIndex: pour des raison d'optimisation memoire, ce longint stocke plisuerus info
  - index de creation
  - indicateur de type vue (cf. GetViewTypeUse)
  - taille du vectuer d'attribut (cf. GetSmallSize)
- la destruction/mutation est necessaire
  - si attribute de type nRelation natif, et on est on pas dans une vue
    - car tout attribut natif cree a partir d'un fichier de donnees doit etre detruit
    - mais un attribut natif d'une vue est juste une reference a un attribut source de la vue, et il ne doit pas etre detruit
  - si attribut calcule mais non reference: objet cree
- implementation: prise en compte systematique de GetViewTypeUse pour piloter la destruction ou mutation des Entity et Relation
  - methodes concernees:
    - DeleteAttributes
    - CleanTemporayDataItemsToComputeAndClean
    - CleanAllNonNativeAttributes
    - CleanNativeRelationAttributes
    - Mutate

Modification de la gestion des attributs de type Relation correspond a un objet natif ou cree (non reference)
  - on passe d'un test sur les KWAttributs de type "GetDerivationRule() == NULL" a "not GetReference()"
  - methodes impactees directement
    - KWClass::IndexClass
    - KWMTDatabase::ComputeUnusedNativeAttributesToKeepForRule
    - KWObject::Mutate: modifications majeures
  - methodes impactees pour les assertions uniquement
    - KWAttribute::GetInternalLoadIndex
    - KWObject::DeleteAttributes

Amelioration des commentaires sur la gestion des attributs de type Relation crees par une regle
- KWClass: GetUnloadedNativeRelationAttributeNumber renomme en GetUnloadedOwnedRelationAttributeNumber

Amelioration de la Trace
- KWClass::IndexClass: ajout de trace (en utilisant la nouvelle methode interne WriteAttributes)
- KWDatabase::BuildPhysicalClass: legere modification
- KWMTDatabase::ComputeUnusedNativeAttributesToKeep: ajout de trace conditionne par bTrace

Corrections au passage dans KWLearningProblemView
- ComputeStats, BuildConstructedDictionary, CheckData:
  - test sur le dictionnaire deplace en premier
  - supression du test sur la valeur de selection de la base d'apprentissage, redondant avec la verification de la base
- CheckData:
  - ajout d'un test sur la validite des specification de la base, notament en multi-table

Creation de plusieurs jeux de test par complexite croissante: TestKhiops\z_TableCreationRules
Mise en place de classes de service ancetre pour les regles de creation:
- KWDRRelationCreationRule
  - GetReference: renvoie true
  - Compile: memorisation de la classe cible et des index source et cible des attributs a copier
  - CheckOperandsCompleteness: debut d'implementation des constraintes pour les alimentations de type vue
  - IsFirstOperandViewType: methode virtuelle pour indiquer que le premier operande est la source de la vue
  - NewTargetObject: creation d'un objet de type vue (cf. KWObject::GetViewTypeUse)
  - CopyObjectCommonNativeAttributes: recopie optimisee des attributs de vue
- KWDRTableCreationRule
- KWDREntityCreationRule

KWDerivationRuleOperand::CheckCompleteness
- ajout d'une contrainte pour interdire l'utilisation d'une regle de creation de table en operande

KWDRRelationCreationRule::BuildAllUsedAttributes
- premiere implementation qui marche
- test dans LearningTest\TestKhiops\z_TableCreationRules\TableViewErrors avec de nombreux effets de bord
- ne prend pas en compte une optimisation poussee
  - complexe a mettre en place
  - il faut evaluer quels attributs sources de la vue sont effectivement utilises en fonction des
    attributs cible de la vue utilisee par d'autres regles
  - comme une vue peut etre calcule depuis plusieurs dictionanires sources differents, un meme attribut cible
    de vue peut avoir une source de nature distincte selon le dictionnaire d'origine
  - actuellement, on integre systematiquement tous les attributs sources de la regle BuidTableView
  - mais on pourrait evaluer de facon fine quels sont les seuls attributs sources vraiment necessaires

Au passage: correction de deux warnings dans KDMultiTableFeatureConstruction.cpp
Prise en compte des regles de creation de table avec alimentation de type calcul

Pour un dictionnaire en sortie, on distingue deux types d'alimentation des variables:
- alimentation de type vue: valeur des variables recopiee depuis les variables de meme nom de la table en entree
- alimentation de type calcul: la regle designe les variables en sortie a mettre a jour
  - on utilise ':' pour separer les operande en entree des operande en sortie de la regle
  - il peut y avoir plusieurs operandes en sortie, separes par des ','
  - chaque operande en sortie designe explicitement un nom de variable native a alimenter dans le dictionnaire en sortie

CMakeLists.txt: amelioration d'un commentaire
CMakePresets.json: parametrage temporaire de BUILD_LEX_YACC": "ON" pour mettre au point le parser

Modification du parser de dictionnaire
- KWCLex.lex:
  - prise en compte du caractère séparateur ':'
- KWYac.yac:
  - renommage de la regle keyFieldList en fieldList
  - la regle derivationRuleBody admet desormais une nouvelle variante de syntaxe avec specification des operandes en sortie
    - parsing d'une liste d'operandes pour les operandes en sortie
    - interet
      - permet d'avoir des erreurs de syntaxe plus precises
      - au dela de la specification des noms de variables en sortie, permet d'envisager
        n'importe quel type d'operande en sortie (constante, regle de derivation)
    - impact
      - nouvelle regle dediee au parsing d'une liste d'operandes de taille non nulle
      - nouveau type de token oaOperands
      - fonctions dediees pour factoriser la gestion des operandes des regles parsees
        - ImportParserRuleOperands
        - ImportParserRuleOutputOperands
        - ImportParserOperand

Deplacement de KWRelationRule dans KWData
- classes generiques de creation de Table ou d'entite

KWDRRelationCreationRule: classe ancetre
  - specialisation de KWDerivationRule, comportant toute la gestion de la creation de table
  - methodes dediee a la gestion des operandes en sortie
    - Get|SetOutputOperandNumber
    - Get|SetVariableOutputOperandNumber
    - GetOutputOperandAt
    - AddOutputOperand
    - DeleteAllOutputOperands, RemoveAllOutputOperands
    - DeleteAllVariableOutputOperands
  - passage en virtuel des methodes suivantes de KWDerivationRule:
    - RenameClass
    - BuildAllUsedOperands
    - ContainsCycle
    - ComputeHashValue
    - WriteUsedRuleOperands (nouvelle methode)
  - redefinition de toutes les methodes a specialiser
    - RenameClass
    - CheckRuleDefinition, CheckOperandsDefinition
    - CheckRuleFamily, CheckOperandsFamily
    - CheckOperandsCompleteness
    - ContainsCycle
    - Compile
    - BuildAllUsedOperands, BuildAllUsedAttributes
    - CopyFrom
    - FullCompare, GetUsedMemory, ComputeHashValue
    - Write, WriteUsedRuleOperands
    - InternalCompleteTypeInfo
  - premiere implementation uniquement des methodes de base (principalement CopyFrom et Write)
    pour tester le parser

KWDRTableCreationRule: classe dediee aux tables

KWCYac.yac: specialisation du parser pour gerer les operandes en sortie
- on garde l'essentiel du parser initial
- utilisation de la classe KWDRRelationCreationRule pour specialiser KWDerivationRule, uniquement en deux endroits
  - pour stocker les operandes en sortie quand le parser en reconnait
  - pour les exploiter au moment ou on verifie la regle

KWDRBuidlRelation, dans KWDRRuleLibrary
- KWDRProtoBuildTableView: prototype de regle avec alimentation de type vue
- KWDRProtoBuildTableAdvancedView: prototype de regle avec alimentation de type calcul
Nettoyage des methodes inutilises, dont la maintenance pour les regles de creation est lourde et sans interet:
- KWClassDomain
  - RenameAttribute
- KWClass
  - RenameAttribute
- KWDerivationRule
  - RenameAttribute
  - DeleteLastOperand
  - ComputeAttributeName
- KWDerivationRuleOperand
  - RenameAttribute
  - ComputeOperandName
…put variables

Implementation de la specialisation des methodes dediees aux variables en sortie
- KWDRRelationCreationRule
  - RenameClass
  - CheckRuleDefinition
  - CheckOperandsDefinition
  - CheckRuleFamily
  - CheckOperandsFamily
  - CheckOperandsCompleteness
  - Compile: compilation complete pour les aliemtation de type vue et calcul
  - BuildAllUsedAttributes
  - FullCompare
  - GetUsedMemory
  - ComputeHashValue
  - InternalCompleteTypeInfo
  - IsFirstOperandViewType : renomme en IsViewModeActivated

KWDerivationRule
- on precise que la gestion des regles de creation de relation est
  sous-traitee a la classe dediee KWRelationCreationRule
- ajout des methodes de gestion des operandes en sortie en virtuel
  - minimaliste: uniquement trois methodes de consultation des specifications
  - GetOutputOperandNumber, GetVariableOutputOperandNumber, GetOutputOperandAt
- permet une implementation generique plus simple dans le parser KWCYac.yac et dans KWRelationCreationRule

Au passage, refactoring basique:
- KWDerivationRule::CheckOperandsDefinition
- KWDerivationRuleOperand::CheckDefinition
- KWDerivationRule::RegisterDerivationRule: verification par un require que la regle est correctement definie

KWDRProtoBuildTableAdvancedView
- nettoyage
- alimentation de type vue et calcul testes sur un cas elementaire avec une seule variable en sortie
Passage a l'implementation des regles "officielles"
- regles
  - BuildTableView
  - BuildTableAdvancedView
  - BuildEntityView
  - BuildEntityAdvancedView
  - BuildEntity
- Supression des règle temporaires prefixees par "Proto"

KWDRRelationCreationRule
- SetVariableOutputOperandNumber: precision de la semantique en cas de nombre variable d'operandes
- IsValidOutputOperandType: test de validite du type d'un operande en sortie
- CopyObjectCommonNativeAttributes: renomme en FillViewModeTargetAttributes
- FillComputeModeTargetAttributes:
  - alimentation des attributs cibles pour les operandes en sortie de regle
  - actuellement, implementation specifique aux besoins de BuildTableAdvancedView
- amelioration des messages d'erreur
- specialisation avance de la reimplementation des methodes suivantes
  - CheckOperandsDefinition
  - CheckOperandsFamily

KWDerivationRule
- CheckOperandsDefinition
  - correction specifique pour le cas avec nombre variable d'operandes, de type Unknown dans la regle enregistree

KWAttribute::Check
- correction pour accepter un dictionnaire de sous-table ou sous-entite sans cle,
  s'il n'est pas natif, et s'il ne s'agit pas d'une regle de reference à une table externe
- si l'attribut de type relation est calcule, soit par une regle de creation de table, soit par une regle quelconque,
  la cle n'est plus obligatoire

Parser KWCYac.yac
- corrections mineures pour la gestion des operandes en sortie

KWDRBuildTableAdvancedView
- utilisation d'un nombre variable d'operandes a la fois en entree et en sortie pour les alimenations de type calcul

Tests extensifs des methodes BuildTableView et BuildTableAdvancedView
- LearningTest\TestKhiops\z_TableCreationRules\TableRenameVariables: test de quatre facons de renommer les variables d'une sous-tables
…d multi-table schema

Lors de la construction de variable pour un schema multi-table, une passe de collecte des echantillons de valeur
est necessaire pour instancier les operande de slection de la regle construite TableSelection.
Cela se fait dans le cas d'un schema multi-table "logique" avec un mapping sur un ensemble de fichier.

Avec les regles de creation de table, on peut avoir un schema "logique" mono-table avec construction
en memoire d'une structure multi-table selon un schema "conceptuel".
C'est le cas par exemple dans le cas d'une serie temporelle de taille fixe representee par une serie de variables
Value_1, , Value_2, Value_last que l'on peut representer via une table secondaire via un dictionnaire comportant
des regles de construction d'entite et de tables
- TS_i = BuildEntity(i, Value_i : Index, Value) par valeur de la serie
- EntitySet(TS_1, TS_2,...)
Il s'agit ici d'etendre les algorithmes de collecte d'echantillons de valeur dans le cas de schemas multi-table "conceptuels"
cree a partir d'une reprentation mono-table "logique".

KDSelectionOperandSamplingTask
- extension au cas ou la base utilisee est mono-table (avec representation multi-table "conceptuelle")
  - on s'adapte maintenant au cas mono-table, avec acces aux specificites multi-tables uniquement si necessaire
  - on accede a la database de facon generique, avec acces au cas multi-table uniquement si necessaire
- ComputeResourceRequirements: extension des heuristique de dimensionnement au cas d'un schema multi-table construit
  - on peut avoir une base mono-table avec des Table ou Entity creees par des regles de creation d'instances
  - dans ce cas, adaptation de l'heuristique de dimensionnement basee sur une estimation du nombre max d'objet en memoire
  - on prend en compte les instances creees par des regles de creation d'instance
- ComputeCreatedEntityNumber: calcul du nombre de variables de type Entity creees par des regles

KWDatabase, KWMTDatabase
- deplacement des methodes de gestion des attributs de type Realation en Unused a garder pour gerer
  correctement leur mutation
  - nkdUnusedNativeAttributesToKeep: dictionnaire impacte
  - methodes deplacees de KWMTDatabase vers KWDatabase
    - ComputeUnusedNativeAttributesToKeep
    - ComputeUnusedNativeAttributesToKeepForRule
  - autres methdoes impactees
    - BuildPhysicalClass: supprimees de KWMTDatabase et enrichies dans KWDatabase
    - DeletePhysicalClass

PLSTDatabaseTextFile: ajout de methodes de dimensionnement similaire a celle du cas multi-table
- GetInMemoryEstimatedFileObjectNumber
- GetEstimatedUsedMemoryPerObject

PLDatabaseTextFile: acces generique aux methodes de dimensionnement, pour les deux cas mono et multi-tables
- GetInMemoryEstimatedFileObjectNumber
- GetEstimatedUsedMemoryPerObject
Ce type de probleme etait correctement diagnostique, mais le dictionnaire erronne etait quand meme charge en memoire,
ce qui ne permet pas au traitements (apprentissage, déploiement) de s'executer correctement.

En effet, la methode Check verifie tous les types d'erreur, sauf la detection de cycle qui n'est detectee
qu'au moment de la compilation d'un domaine, qui est lie a la detection de cycles.

Correction:
- KWClassDomain::Compile: cette methode renvoie desormais un booleen en cas d'erreur dues a des
  cycles dans le graphe des regles de derivation
- en cas d'erreur, le dictionnaire n'est pas charge en memoire, empechant tout traitement
- impacts dans
  - KWClassManagement::ReadClasses, pour Khiops et Khiops coclustering
  - KNIOpenStream, pour l'ouverture d'un stream KNI, qui desormais echoue
Extension de la detection de cycle dans les dictionnaires au cas de cycle de creation d'instance,
qui peuvent aboutir a une recursion infinie de creation d'instances

Impacts:
- KWDRRelationCreationRule::ContainsCycle
  - extension de la detection de cycle dans le cas d'un attribut lie a une regles de creation de table
  - dans ce cas, on analyse tous les attributs de la table cree
	// On propage la detection de cycle au dictionnaire des instances creees en sortie, qui potentiellement
	// pourrait creer des instances en boucle infinie
	// Il n'est pas par contre necessaire de detecter les cycles de calcul sur les attributs sources de vue
	// dans le cas d'une alimentation de type vue, car cette detection est de toute facon effectuee
	// pour chaque dictionnaire
- KWDerivationRule::ContainsCycle
  - amelioration mineurs des messages d'erreurs existants

Autres ameliorations ou correction mineures
- KWDerivationRuleOperand::CheckCompleteness
  - completion dans le cas d'operande en nombre variable et de type Unknown, dans le cas d'attribut inexistant
- KWDRRelationCreationRule::CheckOperandsCompleteness
  - supression des '"' autour des noms de variables et de dictionnaire, qui alourdissent les messages d'erreur
    et ne sont pas conformes au reste des messages
- KWDRRelationCreationRule::CheckOperandsFamily
  - correction sur le controle de coherence de type entre operandes en entree et sortie dans le cas de type relation
- KWDRRelationCreationRule::FillComputeModeTargetAttributesForVariableOperandNumber
  - correction dans le cas des attributs de type Entity
- KWAttribute::ContainsCycle, KWAttributeBlock::ContainsCycle
  - on conditionne la detection de cycle a la presence d'une regle de derivation, pour eviter des traitement inutiles
  - on remplace un SetAt(key, NULL) par un RemoveKey(key) pour etre plus effcace en memoire

Plus quelques typos de commentaire
KWDRRelationCreationRule
- clarification des comemntaires sur l'utilisation des cles et de Root pour les dictionnaires des tables creees par des regles

En resume:
- un dictionnaire peut ne pas avoir de cle s'il est cree
- verification a priori lors de la lecture d'un fichier dictionnaire
  - verification des cles pour les variables natives (non calculee) de type relation
  - contrainte uniquement si le dictionnaire utilisant a une cle
    - cree une contrainte sur la table calculee
      - peut ne pas avoir de cle
      - si elle une cle, ses sous-tables doivent egalement en avoir
- verification a posteriori sur l'usage d'un flocon via le choix d'un dictionaire d'analyse
  - ok si coherence des cle, permet la lecture a partir de fichier
  - ko si des variable natives ne peuvent etre lues en rasion d'un manque de cle
- gestion des tables externes (Root)
  - interdiction de creer une table associee a un dictionnaire externe (Root)
    - sinon, incoherence de la gestion des references aux objets externes, non presents dans des fichiers
  - attention, lors de l'analyse recursive d'une dictuionnaire d'analyse
    - on se limite aux table natives pour en deduire le flocon
    - il faut par contre parcourir entierement les tables calculees ou non pour en deduire les tables externes a utliser

Impacts
- interdiction de creer une table Root
  - KWDRRelationCreationRule::CheckOperandsCompleteness
- correction pour prendre en compte les regles associees a des blocs d'attributs
  - KWAttribute::GetReference
- tolerance sur la verification des cles
  - KWAttribute::Check
- amelioration des messages d'erreur et de warning
  - KWAttribute::Check
  - KWClass:CheckClassComposition
- extension en prenant en compte les tables externes references depuis des attributs table creees par des regles
  - KWClass::ComputeOverallNativeRelationAttributeNumber
  - KWMTDatabase::CreateMapping
Problemes apparaissant avec des schemas en flocon et des vues
- detecte dans z_TableCreationRules\NoKeyInCreatedSnowflake
  - variantes selon CheckDatabase, Compute, avec plus ou moins de constructed features
- exemple, flocon: Customer-Service-Usage
- Vue ServiceView sur Service, avec recuperation des usages
- Services en Unused:
  - destruction des Usages depuis Services, ce qui les rend inutilisables depuis les ServiceView

Autre probleme: jeu de test TestKhiops\z_TableCreationRules\BugDeleteSubTableOfView
- apprentissage avec creation de variables

Bilan
- les corrections ci-dessous permettent de resoudre tous les problemes connus
- la trace est maintenant suffisante pour identifier les problemes de gestion memoire
- il va falloir par contre optimiser la gestion des classes physiques dans KWDatabase pour optimiser les calculs dans le cas de vues
  - gestion non optimale des attributs utilises pour le calcul de la classe logique par KWDatabase
  - cf. KWDRRelationCreationRule::BuildAllUsedAttributes

Tentative abandonnee de gestion automatique de la memoire par comptage de reference
- KWObject: mise en place de la gestion des references
  - longint lRefCount
  - SafeReferenceObject, SaveDeleteObject
  - idem pour tableau d'objets et bloc sparse de tableaux d'objets
- utilisation dans KWObject des methodes SafeReference* et SafeDelete*
  - ComputeAllValues
  - DeleteAttributes
  - CleanTemporayDataItemsToComputeAndClean
  - CleanAllNonNativeAttributes
  - CleanNativeRelationAttributes
  - Mutate
- KWClass: nettoyage de la gestion des UnloadedOwnedRelationAttribute
  - GetUnloadedOwnedRelationAttributeNumber: supprime
  - GetUnloadedOwnedRelationAttributeAt: supprime
  - GetTotalInternallyLoadedDataItemNumber: a supprimer
  - impacts sur KWObject: DeleteAttributes, Mutate, GetUsedMemory
- KWDatabase: nettoyage du calcul des attributs a garder
  - BuildPhysicalClass: calcul des attributs a garder commente
    - supression de ce parametre a propager
  - ComputeUnusedNativeAttributesToKeep: a suprimer
  - ComputeUnusedNativeAttributesToKeepForRule: a supprimer
- abandon car cela ne marche pas a cause des cycle de references potentiels
  - cf. graphe de donnees, base de molecules

KWDatabase::BuildPhysicalClass
- quand on reordonne les attributs physiques surnumeraires en fin de classe, on ne deplace que ceux
  qui etaient utilises dans la classe logique
- par exemple: besoin d'un attribut natif used d'une classe en unused, mais en source d'une vue

KWDatabase::ComputeUnusedNativeAttributesToKeepForRule
- on prend on compte toutes les variables de type relation, quelle que soit leur nature
  - avant, on se limitait aux operandes relations de meme type que celui du code retour de la regle
  - cela ne suffit pas pour les regles de creation d'instances
- on prend maintenant en operande l'ensemble des classes necessaires recursivement dans le flocon
  - on garde ainsi tous les attributs crees associes a un dictionnaire necessaire
  - resout le cas d'un dictionnaire utilise pour calculer une vue, mais jamais directement utilise sinon

Correction mineure additionnelle
- Bug dans les mappings multi-table avec des variables de type relation dont le nom est de longueur 1
- Bug d'assertion dans le mapping multi-table pour un nom de variable de un seul caractere en fin de data path
- Bug d'effet de bord
- Correction dans KWMTDatabaseMapping::CheckDataPath

Amelioration de la trace pour aider au diagnostique des problemes de gestion memoire des KWObject
- KWMTDatabase::UpdateMultiTableMappings: ajout de trace
- KWDatabase::BuildPhysicalClass: stabilisation de la trace
  - tri des classes
  - tri des attributs par classe, puis par nom
  - impact avec KWAttributeCompareClassAndAttributeName
    - variante de KWAttributeCompareName avec comparaison prealable du nom de la classe
- KWDatabase::MutatePhysicalObject: ajout de trace avant et apres mutation
- KWObject::PrettyWrite: version de Write avec indentations
- KWObject: ajout de trace pour la mise au point fine des mutations d'objets
  - ComputeAllValues
  - DeleteAttributes
  - Mutate

Tests complets sur \z_TableCreationRules en debug
Probleme explique en commentaire du nouvel attribut KWDatabase::nkdMutationClasses
  // Dictionnaire des classes de mutation, avec en cle la classe physique des objets a muter
  // et en valeur la classe suite a la mutation
  //
  // Dans la majorite des cas, la classe de mutation est la classe logique de meme nom,
  // qui garde les attributs charges en memoire de la classe logique, alors que la classe physique
  // a potentiellement plus d'attributs charges en memoire, en unused dans la classe logique, mais
  // necessaires dans la classe physique pour le calcul des attribut derives
  //
  // Dans des cas a effet de bord, la classe de mutation peut rester la classe physique si la classe
  // logique est en unused, mais est necessaire en tant qu'attribut de type relation non charge en
  // memoire, mais a garder pour la destruction des objets (cf. UnloadedOwnedRelationAttribute dans KWClass)
  // Exemple d'effet de bord:
  //   La classe Customer a des Services en Unused, ses services on des Usages, et la classe Customer
  //   a tous ses usages utilises via la regle TableSubUnion(Services, Usages)
  //   Dans ce cas, les Services physiques sont gardes dans leur classe physique pour gerer recursivement
  //   la destruction des Usages, mais ils ne sont pas mutes, car non utilises au niveau logique

Impacts principaux
- KWDatabase
  - BuildPhysicalClass: memorisation des classes de mutation dans le nouvel attribut nkdMutationClasses
  - MutatePhysicalObject: utilisation de nkdMutationClasses en parametre supplementaire
- KWDataTableSliceSet
  - PhysicalRead: adaptation miimaliste pour le parametrage supplementaire de la methode Mutate
- KWObject
  - Mutate: prend nkdMutationClasses pour gere les classe de mutation destination
  - on distingue la mutation de l'objet, qui n'est effectuee que si la classe de mutation est une nouvelle classe,
    de la mutation des attributs de type relation charges en memoire, qui est effectuee systematiquement
  - ajout de trace facilitant l'analyse des problème mémoire dans les methodes suivantes
    - KWObject (constructeur)
    - ComputeAllValues
    - DeleteAttributes
    - Mutate
    - PrettyWrite

Tous les tests de LearningTest passent, y compris en debug, sans fuite memoire
@marcboulle marcboulle requested a review from popescu-v December 3, 2024 12:22
@marcboulle marcboulle force-pushed the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch from b4bd3cf to db028b0 Compare December 3, 2024 12:55
Copy link
Collaborator

@popescu-v popescu-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM:

  • commit messages are clear,
  • the specification is clear (to be updated upon feature finalization though).

Copy link

@lucaurelien lucaurelien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

functionally approved

@marcboulle marcboulle merged commit e934b1f into dev Dec 3, 2024
53 checks passed
@marcboulle marcboulle deleted the 199-extend-derivation-rules-to-create-new-instances-of-table-or-entity branch December 3, 2024 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extend derivation rules to create new instances of Table or Entity
3 participants