From: <mcu...@us...> - 2007-08-15 01:48:11
|
Revision: 1085 http://orm.svn.sourceforge.net/orm/?rev=1085&view=rev Author: mcurland Date: 2007-08-14 18:48:13 -0700 (Tue, 14 Aug 2007) Log Message: ----------- Fixed issue with FactTypeMappingPermuter incorrectly traversing many-to-one fact types. refs #327 Modified Paths: -------------- trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs Modified: trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs =================================================================== --- trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs 2007-08-15 01:44:14 UTC (rev 1084) +++ trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs 2007-08-15 01:48:13 UTC (rev 1085) @@ -120,18 +120,27 @@ continue; } + // Indicates whether we should follow the fact type and include + // the object type at the other end of it in the current chain. + bool traverseFactType; FactTypeMapping mapping; FactTypeMappingList mappingList; + // Check for undecided one-to-one mappings... if (myUndecidedOneToOneFactTypeMappings.TryGetValue(factType, out mappingList)) { + traverseFactType = true; chain.UndecidedOneToOneFactTypeMappings.Add(mappingList); } + // ...or predecided one-to-one mappings... else if (myPredecidedOneToOneFactTypeMappings.TryGetValue(factType, out mapping)) { + traverseFactType = true; chain.PredecidedOneToOneFactTypeMappings.Add(mapping); } - else if (myPredecidedManyToOneFactTypeMappings.TryGetValue(factType, out mapping)) + // ...or predecided many-to-one mappings towards this object type. + else if (myPredecidedManyToOneFactTypeMappings.TryGetValue(factType, out mapping) && mapping.TowardsObjectType == objectType) { + traverseFactType = false; chain.PredecidedManyToOneFactTypeMappings.Add(mapping); } else @@ -142,12 +151,31 @@ // Record that this fact type has been visited. visitedFactTypes[factType] = null; + // We don't want to include the object type at the other end of this + // fact type in the chain, so continue on with the next played role. + if (!traverseFactType) + { + continue; + } + + // At most one of the two roles will be played by a different object type. LinkedElementCollection<RoleBase> roles = factType.RoleCollection; Debug.Assert(roles.Count == 2); ObjectType objectType1 = roles[0].Role.RolePlayer; - ObjectType objectType2 = roles[1].Role.RolePlayer; - ProcessObjectType(objectType1, chain, visitedFactTypes, visitedObjectTypes); - ProcessObjectType(objectType2, chain, visitedFactTypes, visitedObjectTypes); + if (objectType1 != objectType) + { + // We found the role played by a different object type, so there is no need to check the other role. + ProcessObjectType(objectType1, chain, visitedFactTypes, visitedObjectTypes); + } + else + { + // The first role was played by this object tpye, so we need to check the second role. + ObjectType objectType2 = roles[1].Role.RolePlayer; + if (objectType2 != objectType) + { + ProcessObjectType(objectType2, chain, visitedFactTypes, visitedObjectTypes); + } + } } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2007-08-30 17:27:44
|
Revision: 1103 http://orm.svn.sourceforge.net/orm/?rev=1103&view=rev Author: mcurland Date: 2007-08-30 10:27:46 -0700 (Thu, 30 Aug 2007) Log Message: ----------- Fixed bug that was causing us to only ever get one Permutation out of FindSmallestPermutationsInTermsOfConceptTypes(). Added EliminatePermutationsWithIdenticalResults(). refs #327 Modified Paths: -------------- trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs Modified: trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs =================================================================== --- trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs 2007-08-30 17:26:19 UTC (rev 1102) +++ trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs 2007-08-30 17:27:46 UTC (rev 1103) @@ -278,6 +278,7 @@ PermuteFactTypeMappings(chain.PossiblePermutations, chain.UndecidedOneToOneFactTypeMappings, newlyDecidedFactTypeMappings, deeplyMappedObjectTypes, 0); EliminateInvalidPermutations(chain); FindSmallestPermutationsInTermsOfConceptTypes(chain); + EliminatePermutationsWithIdenticalResults(chain); // Add each mapping from the optimal permutation to the "global" set of decided mappings. foreach (FactTypeMapping optimalMapping in ChooseOptimalPermutation(chain).Mappings) @@ -441,7 +442,7 @@ else { // We have the same number of top-level concept types as the minimum, so we need to check the number of non-top-level concept types. - if (nonTopLevelConceptTypes.Count > minTopLevelConceptTypesCount) + if (nonTopLevelConceptTypes.Count > minNonTopLevelConceptTypesCount) { // This isn't an optimal permutation, so go on to the next one. continue; @@ -458,8 +459,55 @@ } } + /// <summary> + /// Eliminates <see cref="Permutation"/>s that have the same set of top-level concept types and non-top-level concept types, + /// which will always result in the same OIAL. + /// </summary> + private static void EliminatePermutationsWithIdenticalResults(Chain chain) + { + PermutationList smallestPermutationsInTermsOfConceptTypes = chain.SmallestPermutationsInTermsOfConceptTypes; + for (int currentPermutationIndex = 0; currentPermutationIndex < smallestPermutationsInTermsOfConceptTypes.Count - 1; currentPermutationIndex++) + { + Permutation currentPermutation = smallestPermutationsInTermsOfConceptTypes[currentPermutationIndex]; + for (int comparisonPermutationIndex = smallestPermutationsInTermsOfConceptTypes.Count - 1; comparisonPermutationIndex > currentPermutationIndex; comparisonPermutationIndex--) + { + Permutation comparisonPermutation = smallestPermutationsInTermsOfConceptTypes[comparisonPermutationIndex]; + bool hasIdenticalConceptTypes = true; + // Check if comparisonPermutation has the same top-level concept types. + foreach (ObjectType topLevelConceptType in currentPermutation.TopLevelConceptTypes.Keys) + { + if (!comparisonPermutation.TopLevelConceptTypes.ContainsKey(topLevelConceptType)) + { + hasIdenticalConceptTypes = false; + break; + } + } + if (hasIdenticalConceptTypes) + { + // Check if comparisonPermutation has the same non-top-level concept types. + foreach (ObjectType nonTopLevelConceptType in currentPermutation.NonTopLevelConceptTypes.Keys) + { + if (!comparisonPermutation.NonTopLevelConceptTypes.ContainsKey(nonTopLevelConceptType)) + { + hasIdenticalConceptTypes = false; + break; + } + } + if (hasIdenticalConceptTypes) + { + // comparisonPermutation has the same set of top-level and non-top-level concept types, so we can get rid of it. + // It is entirely arbitrary which one we get rid of, so we'll keep the first since it is easier. + smallestPermutationsInTermsOfConceptTypes.RemoveAt(comparisonPermutationIndex); + } + } + } + } + } + + + private static Permutation ChooseOptimalPermutation(Chain chain) { // UNDONE: This should do something smart! This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |