protected override bool EqualKeys(PrioMembersKey key, MapEntry <PrioMembersKey, IdentityLinkedSet <Member> > entry) { PrioMembersKey other = entry.Key; if (key == other) { return(true); } IdentityLinkedSet <Member> key1 = key.Key1; IdentityLinkedSet <Member> otherKey1 = other.Key1; if (key1.Count != otherKey1.Count) { return(false); } foreach (Member item in key1) { if (!otherKey1.Contains(item)) { return(false); } } return(true); }
public void AddMembers(EntityMetaData metaData, IEntityConfig entityConfig) { Type realType = entityConfig.RealType; ISet <String> memberNamesToIgnore = new HashSet <String>(); ISet <String> explicitBasicMemberNames = new HashSet <String>(); IList <IMemberConfig> embeddedMembers = new List <IMemberConfig>(); IMap <String, IMemberConfig> nameToMemberConfig = new HashMap <String, IMemberConfig>(); IMap <String, IRelationConfig> nameToRelationConfig = new HashMap <String, IRelationConfig>(); IdentityLinkedMap <String, Member> nameToMemberMap = new IdentityLinkedMap <String, Member>(); FillNameCollections(entityConfig, memberNamesToIgnore, explicitBasicMemberNames, embeddedMembers, nameToMemberConfig, nameToRelationConfig); IdentityLinkedSet <PrimitiveMember> alternateIdMembers = new IdentityLinkedSet <PrimitiveMember>(); IdentityLinkedSet <PrimitiveMember> primitiveMembers = new IdentityLinkedSet <PrimitiveMember>(); IdentityLinkedSet <RelationMember> relationMembers = new IdentityLinkedSet <RelationMember>(); IdentityLinkedSet <Member> notMergeRelevant = new IdentityLinkedSet <Member>(); IdentityLinkedSet <Member> containedInAlternateIdMember = new IdentityLinkedSet <Member>(); IPropertyInfo[] properties = PropertyInfoProvider.GetProperties(realType); IdentityLinkedMap <String, Member> explicitlyConfiguredMemberNameToMember = new IdentityLinkedMap <String, Member>(); HashMap <String, IOrmConfig> nameToConfigMap = new HashMap <String, IOrmConfig>(); // Resolve members for all explicit configurations - both simple and composite ones, each with embedded // functionality (dot-member-path) foreach (IMemberConfig memberConfig in entityConfig.GetMemberConfigIterable()) { PutNameToConfigMap(memberConfig, nameToConfigMap); if (memberConfig.Ignore) { continue; } HandleMemberConfig(metaData, realType, memberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); } foreach (IRelationConfig relationConfig in entityConfig.GetRelationConfigIterable()) { PutNameToConfigMap(relationConfig, nameToConfigMap); HandleRelationConfig(realType, relationConfig, explicitlyConfiguredMemberNameToMember); } PutNameToConfigMap(entityConfig.IdMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.VersionMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.CreatedByMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.CreatedOnMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.UpdatedByMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.UpdatedOnMemberConfig, nameToConfigMap); metaData.IdMember = HandleMemberConfig(metaData, realType, entityConfig.IdMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.VersionMember = HandleMemberConfig(metaData, realType, entityConfig.VersionMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.CreatedByMember = HandleMemberConfig(metaData, realType, entityConfig.CreatedByMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.CreatedOnMember = HandleMemberConfig(metaData, realType, entityConfig.CreatedOnMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.UpdatedByMember = HandleMemberConfig(metaData, realType, entityConfig.UpdatedByMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.UpdatedOnMember = HandleMemberConfig(metaData, realType, entityConfig.UpdatedOnMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); IdentityHashSet <Member> idMembers = new IdentityHashSet <Member>(); Member idMember = metaData.IdMember; if (idMember is CompositeIdMember) { idMembers.AddAll(((CompositeIdMember)idMember).Members); } else { idMembers.Add(idMember); } // Handle all explicitly configured members foreach (Entry <String, Member> entry in explicitlyConfiguredMemberNameToMember) { String memberName = entry.Key; IOrmConfig ormConfig = nameToConfigMap.Get(memberName); Member member = entry.Value; if (idMembers.Contains(member)) { continue; } if (ormConfig.ExplicitlyNotMergeRelevant) { notMergeRelevant.Add(member); } if (ormConfig is IRelationConfig) { if (!relationMembers.Add((RelationMember)member)) { throw new Exception("Member has been registered as relation multiple times: " + member.Name); } continue; } if (!(ormConfig is IMemberConfig)) { continue; } if (((IMemberConfig)ormConfig).AlternateId) { if (!alternateIdMembers.Add((PrimitiveMember)member)) { throw new Exception("Member has been registered as alternate id multiple times: " + member.Name); } if (member is CompositeIdMember) { Member[] containedMembers = ((CompositeIdMember)member).Members; containedInAlternateIdMember.AddAll(containedMembers); } } if (!(member is CompositeIdMember) && metaData.VersionMember != member) { // Alternate Ids are normally primitives, too. But Composite Alternate Ids not - only their composite // items are primitives primitiveMembers.Add((PrimitiveMember)member); } } IdentityHashSet <String> explicitTypeInfoItems = IdentityHashSet <String> .Create(explicitlyConfiguredMemberNameToMember.Count); foreach (Entry <String, Member> entry in explicitlyConfiguredMemberNameToMember) { Member member = entry.Value; explicitTypeInfoItems.Add(member.Name); if (member is IEmbeddedMember) { explicitTypeInfoItems.Add(((IEmbeddedMember)member).GetMemberPath()[0].Name); } } // Go through the available members to look for potential auto-mapping (simple, no embedded) for (int i = 0; i < properties.Length; i++) { IPropertyInfo property = properties[i]; String memberName = property.Name; if (memberNamesToIgnore.Contains(memberName)) { continue; } if (explicitTypeInfoItems.Contains(memberName)) { // already configured, no auto mapping needed for this member continue; } MethodPropertyInfo mProperty = (MethodPropertyInfo)property; Type elementType = TypeInfoItemUtil.GetElementTypeUsingReflection(mProperty.Getter.ReturnType, null); if ((nameToMemberMap.Get(property.Name) is RelationMember) || RelationProvider.IsEntityType(elementType)) { RelationMember member = GetRelationMember(metaData.EntityType, property, nameToMemberMap); relationMembers.Add(member); continue; } PrimitiveMember member2 = GetPrimitiveMember(metaData.EntityType, property, nameToMemberMap); if (metaData.IdMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_ID)) { metaData.IdMember = member2; continue; } if (idMembers.Contains(member2) && !alternateIdMembers.Contains(member2) && !containedInAlternateIdMember.Contains(member2)) { continue; } if (member2.Equals(metaData.IdMember) || member2.Equals(metaData.VersionMember) || member2.Equals(metaData.CreatedByMember) || member2.Equals(metaData.CreatedOnMember) || member2.Equals(metaData.UpdatedByMember) || member2.Equals(metaData.UpdatedOnMember)) { continue; } if (metaData.VersionMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_VERSION)) { metaData.VersionMember = member2; continue; } if (metaData.CreatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_BY)) { metaData.CreatedByMember = member2; } else if (metaData.CreatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_ON)) { metaData.CreatedOnMember = member2; } else if (metaData.UpdatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_BY)) { metaData.UpdatedByMember = member2; } else if (metaData.UpdatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_ON)) { metaData.UpdatedOnMember = member2; } primitiveMembers.Add(member2); } foreach (PrimitiveMember member in primitiveMembers) { String memberName = member.Name; if (explicitBasicMemberNames.Contains(memberName)) { // Even if the name would match, this member was explicitly configured as "basic" continue; } if (metaData.CreatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_BY)) { metaData.CreatedByMember = member; } else if (metaData.CreatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_ON)) { metaData.CreatedOnMember = member; } else if (metaData.UpdatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_BY)) { metaData.UpdatedByMember = member; } else if (metaData.UpdatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_ON)) { metaData.UpdatedOnMember = member; } } FilterWrongRelationMappings(relationMembers); // Order of setter calls is important PrimitiveMember[] primitives = primitiveMembers.ToArray(); PrimitiveMember[] alternateIds = alternateIdMembers.ToArray(); RelationMember[] relations = relationMembers.ToArray(); Array.Sort(primitives); Array.Sort(alternateIds); Array.Sort(relations); metaData.PrimitiveMembers = primitives; metaData.AlternateIdMembers = alternateIds; metaData.RelationMembers = relations; foreach (Member member in notMergeRelevant) { metaData.SetMergeRelevant(member, false); } if (metaData.IdMember == null) { throw new Exception("No ID member could be resolved for entity of type " + metaData.RealType); } }
public IdentityLinkedSet <Member> GetPrioMembers(ILinkedMap <Type, PrefetchPath[]> entityTypeToPrefetchPath, List <PrefetchCommand> pendingPrefetchCommands, MergePrefetchPathsCache mergePrefetchPathsCache) { IdentityLinkedSet <Member> key1 = new IdentityLinkedSet <Member>(); PrioMembersKey key = new PrioMembersKey(entityTypeToPrefetchPath, key1); for (int a = 0, size = pendingPrefetchCommands.Count; a < size; a++) { PrefetchCommand prefetchCommand = pendingPrefetchCommands[a]; key1.Add(prefetchCommand.valueHolder.Member); } IdentityLinkedSet <Member> prioMembersMap = activeMembersToPrioMembersMap.Get(key); if (prioMembersMap != null) { return(prioMembersMap); } prioMembersMap = new IdentityLinkedSet <Member>(0.5f); Tuple2KeyHashMap <Type, PrefetchPath[], bool?> alreadyVisited = null; IdentityHashSet <Type> touchedTypesInPriority = null; if (mergePrefetchPathsCache == null) { mergePrefetchPathsCache = new MergePrefetchPathsCache(entityMetaDataProvider); } bool prio2Mode = true; foreach (PrefetchCommand prefetchCommand in pendingPrefetchCommands) { DirectValueHolderRef valueHolder = prefetchCommand.valueHolder; PrefetchPath[] prefetchPaths = prefetchCommand.prefetchPaths; RelationMember member = valueHolder.Member; Type targetEntityType = member.ElementType; // Merge the root prefetch path with the relative prefetch path prefetchPaths = mergePrefetchPathsCache.MergePrefetchPaths(targetEntityType, prefetchPaths, entityTypeToPrefetchPath); IEntityMetaData metaData = valueHolder.Vhc.Get__EntityMetaData(); if (targetEntityType.Equals(metaData.EntityType)) { // prio1 overrides prio2 if (prio2Mode) { prio2Mode = false; alreadyVisited = null; prioMembersMap.Clear(); if (touchedTypesInPriority != null) { touchedTypesInPriority.Clear(); } } prioMembersMap.Add(member); if (touchedTypesInPriority == null) { touchedTypesInPriority = new IdentityHashSet <Type>(); } touchedTypesInPriority.Add(member.EntityType); touchedTypesInPriority.Add(targetEntityType); continue; } if (prefetchPaths == null || !prio2Mode) { continue; } if (alreadyVisited == null) { alreadyVisited = new Tuple2KeyHashMap <Type, PrefetchPath[], bool?>(); } if (IsPrio2Member(metaData, entityMetaDataProvider.GetMetaData(targetEntityType), prefetchPaths, entityTypeToPrefetchPath, alreadyVisited, mergePrefetchPathsCache)) { prioMembersMap.Add(member); if (touchedTypesInPriority == null) { touchedTypesInPriority = new IdentityHashSet <Type>(); } touchedTypesInPriority.Add(member.EntityType); touchedTypesInPriority.Add(targetEntityType); } } if (prioMembersMap.Count > 0) { // check for out-of-order members which have nothing to do (and will never ever have in a transitive manner) with the priorized members foreach (PrefetchCommand prefetchCommand in pendingPrefetchCommands) { DirectValueHolderRef valueHolder = prefetchCommand.valueHolder; RelationMember member = valueHolder.Member; if (prioMembersMap.Contains(member)) { // already priorized continue; } if (touchedTypesInPriority.Contains(member.EntityType) || touchedTypesInPriority.Contains(member.ElementType)) { continue; } prioMembersMap.Add(member); } } Object writeLock = activeMembersToPrioMembersMap.GetWriteLock(); lock (writeLock) { IdentityLinkedSet <Member> existingPrioMembersMap = activeMembersToPrioMembersMap.Get(key); if (existingPrioMembersMap != null) { return(existingPrioMembersMap); } activeMembersToPrioMembersMap.Put(key, prioMembersMap); return(prioMembersMap); } }
protected void LoadAndAddOrels(ICacheIntern cache, IMap <IObjRelation, bool> orelsToLoad, IList <Object> hardRefList, IMap <ICacheIntern, IISet <IObjRelation> > cacheToOrelsLoadedHistory, ILinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisToLoad, IdentityLinkedSet <Member> prioMembers) { IList <IObjRelation> objRelList; if (prioMembers.Count > 0) { objRelList = new List <IObjRelation>(orelsToLoad.Count); IEntityMetaDataProvider entityMetaDataProvider = this.EntityMetaDataProvider; foreach (Entry <IObjRelation, Boolean> entry in orelsToLoad) { IObjRelation objRel = entry.Key; IEntityMetaData metaData = entityMetaDataProvider.GetMetaData(objRel.RealType); RelationMember memberByName = (RelationMember)metaData.GetMemberByName(objRel.MemberName); if (!prioMembers.Contains(memberByName)) { continue; } objRelList.Add(objRel); } } else { objRelList = orelsToLoad.KeyList(); } IList <IObjRelationResult> objRelResults = cache.GetObjRelations(objRelList, cache, CacheDirective.ReturnMisses); IISet <IObjRef> orisToLoad = null; for (int a = 0, size = objRelResults.Count; a < size; a++) { IObjRelation objRel = objRelList[a]; IObjRelationResult objRelResult = objRelResults[a]; bool objRefsOnly = orelsToLoad.Remove(objRel); if (objRelResult == null) { continue; } if (orelsToLoad.Get(objRel)) { // fetch only the objRefs, not the objects themselves continue; } IObjRef[] relations = objRelResult.Relations; if (relations.Length == 0 || objRefsOnly) { // fetch only the objRefs, not the objects themselves continue; } if (orisToLoad == null) { orisToLoad = cacheToOrisToLoad.Get(cache); if (orisToLoad == null) { orisToLoad = new CHashSet <IObjRef>(); cacheToOrisToLoad.Put(cache, orisToLoad); } } orisToLoad.AddAll(relations); } IISet <IObjRelation> orelsLoadedHistory = cacheToOrelsLoadedHistory.Get(cache); if (orelsLoadedHistory == null) { orelsLoadedHistory = new CHashSet <IObjRelation>(); cacheToOrelsLoadedHistory.Put(cache, orelsLoadedHistory); } orelsLoadedHistory.AddAll(objRelList); }
protected void ProcessPendingOrelsAndObjRefs(ILinkedMap <Type, PrefetchPath[]> entityTypeToPrefetchPath, AlreadyHandledSet alreadyHandledSet, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisLoadedHistory, IdentityLinkedMap <ICacheIntern, IISet <IObjRelation> > cacheToOrelsLoadedHistory, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisToLoad, IdentityLinkedMap <ICacheIntern, IMap <IObjRelation, bool> > cacheToOrelsToLoad, List <PrefetchCommand> pendingPrefetchCommands, List <Object> hardRefList) { // all relation members where at least one instance of the owning entity type needs a prefetch on this member in the immediate next step MergePrefetchPathsCache mergePrefetchPathsCache = new MergePrefetchPathsCache(EntityMetaDataProvider); IdentityLinkedSet <Member> prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache); LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers); LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory); while (pendingPrefetchCommands.Count > 0) { PrefetchCommand[] currentPrefetchCommands = pendingPrefetchCommands.ToArray(); // Clear the items to be ready for cascaded items in new batch recursion step pendingPrefetchCommands.Clear(); if (prioMembers.Count > 0) { for (int a = 0, size = currentPrefetchCommands.Length; a < size; a++) { PrefetchCommand prefetchCommand = currentPrefetchCommands[a]; DirectValueHolderRef valueHolder = prefetchCommand.valueHolder; if (!prioMembers.Contains(valueHolder.Member)) { currentPrefetchCommands[a] = null; pendingPrefetchCommands.Add(prefetchCommand); } } } GuiThreadHelper.InvokeInGuiAndWait(delegate() { ICacheModification cacheModification = CacheModification; ValueHolderContainerMixin valueHolderContainerMixin = ValueHolderContainerMixin; bool oldActive = cacheModification.Active; if (!oldActive) { cacheModification.Active = true; } try { foreach (PrefetchCommand prefetchCommand in currentPrefetchCommands) { if (prefetchCommand == null) { continue; } DirectValueHolderRef valueHolder = prefetchCommand.valueHolder; PrefetchPath[] cachePaths = prefetchCommand.prefetchPaths; RelationMember member = valueHolder.Member; // Merge the root prefetch path with the relative prefetch path cachePaths = mergePrefetchPathsCache.MergePrefetchPaths(member.ElementType, cachePaths, entityTypeToPrefetchPath); IObjRefContainer vhc = valueHolder.Vhc; ICacheIntern targetCache; bool doSetValue = false; if (valueHolder is IndirectValueHolderRef) { IndirectValueHolderRef valueHolderKey = (IndirectValueHolderRef)valueHolder; targetCache = valueHolderKey.RootCache; } else { targetCache = ((IValueHolderContainer)vhc).__TargetCache; doSetValue = true; } int relationIndex = vhc.Get__EntityMetaData().GetIndexByRelation(member); IObjRef[] objRefs = vhc.Get__ObjRefs(relationIndex); Object obj = valueHolderContainerMixin.GetValue(vhc, relationIndex, member, targetCache, objRefs, CacheDirective.FailEarly); if (doSetValue && obj != null) { member.SetValue(vhc, obj); } EnsureInitializedRelationsIntern3(obj, cachePaths, entityTypeToPrefetchPath, cacheToOrisToLoad, cacheToOrelsToLoad, cacheToOrisLoadedHistory, cacheToOrelsLoadedHistory, alreadyHandledSet, pendingPrefetchCommands); } } finally { if (!oldActive) { cacheModification.Active = false; } } }); // Remove all oris which have already been tried to load before if (cacheToOrisToLoad.Count == 0 && cacheToOrelsToLoad.Count == 0 && pendingPrefetchCommands.Count == 0) { return; } prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache); LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers); LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory); } }