protected void AddCascadeLoadItem(DirectValueHolderRef vhr, PrefetchPath[] cachePaths, IList <PrefetchCommand> cascadeLoadItems) { if (cachePaths != null || !vhr.ObjRefsOnly) { PrefetchCommand cascadeLoadItem = new PrefetchCommand(vhr, cachePaths); cascadeLoadItems.Add(cascadeLoadItem); } }
public override bool Equals(object obj) { if (Object.ReferenceEquals(this, obj)) { return(true); } if (!(obj is PrefetchCommand)) { return(false); } PrefetchCommand other = (PrefetchCommand)obj; if (valueHolder is DirectValueHolderRef) { // Use equals() of ValueHolderKey return(valueHolder.Equals(other.valueHolder) && prefetchPaths == other.prefetchPaths); } return(Object.ReferenceEquals(valueHolder, other.valueHolder) && Object.ReferenceEquals(prefetchPaths, other.prefetchPaths)); }
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 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); } }