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); } }
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 void WaitEventToResume(Object eventTargetToResume, long maxWaitTime, IBackgroundWorkerParamDelegate <IProcessResumeItem> resumeDelegate, IBackgroundWorkerParamDelegate <Exception> errorDelegate) { try { IdentityHashSet <Object> pendingSet = new IdentityHashSet <Object>(); if (eventTargetToResume is IEnumerable) { pendingSet.AddAll((IEnumerable)eventTargetToResume); } else { pendingSet.Add(eventTargetToResume); } WaitForResumeItem pauseItem = null; listenersWriteLock.Lock(); try { IList <Object> remainingPausedEventTargets = EvaluatePausedEventTargetsOfForeignThreads(); IdentityLinkedSet <Object> remainingPausedEventTargetsSet = new IdentityLinkedSet <Object>(remainingPausedEventTargets); remainingPausedEventTargetsSet.RetainAll(pendingSet); if (remainingPausedEventTargetsSet.Count > 0) { // We should wait now but we have to check if we are in the UI thread, which must never wait if (GuiThreadHelper.IsInGuiThread()) { // This is the trick: We "requeue" the current action in the UI pipeline to prohibit blocking GuiThreadHelper.InvokeInGuiLate(delegate() { WaitEventToResume(eventTargetToResume, maxWaitTime, resumeDelegate, errorDelegate); }); return; } pauseItem = new WaitForResumeItem(pendingSet); waitForResumeSet.Add(pauseItem); } } finally { listenersWriteLock.Unlock(); } if (pauseItem == null) { resumeDelegate.Invoke(null); return; } CountDownLatch latch = pauseItem.Latch; if (maxWaitTime < 0) { latch.Await(); } else if (maxWaitTime > 0) { latch.Await(TimeSpan.FromMilliseconds(maxWaitTime)); } else { throw new System.Exception("Thread should wait but does not want to"); } resumeDelegate.Invoke(pauseItem); } catch (Exception e) { if (Log.ErrorEnabled) { Log.Error(e); } if (errorDelegate != null) { errorDelegate.Invoke(e); } throw; } }