Beispiel #1
0
        protected bool IsPrio2Member(IEntityMetaData rootMetaData, IEntityMetaData metaData, PrefetchPath[] prefetchPaths,
                                     ILinkedMap <Type, PrefetchPath[]> entityTypeToPrefetchSteps, Tuple2KeyHashMap <Type, PrefetchPath[], bool?> alreadyVisited,
                                     MergePrefetchPathsCache mergePrefetchPathsCache)
        {
            IEntityMetaDataProvider entityMetaDataProvider = this.entityMetaDataProvider;

            foreach (PrefetchPath prefetchPath in prefetchPaths)
            {
                if (!alreadyVisited.PutIfNotExists(prefetchPath.memberType, prefetchPath.children, true))
                {
                    continue;
                }
                PrefetchPath[] children = mergePrefetchPathsCache.MergePrefetchPaths(prefetchPath.memberType, prefetchPath.children, entityTypeToPrefetchSteps);
                if (children == null)
                {
                    continue;
                }
                IEntityMetaData childMetaData = entityMetaDataProvider.GetMetaData(prefetchPath.memberType);
                if (metaData == childMetaData)
                {
                    // prio1 case at a later stage
                    continue;
                }
                if (rootMetaData == childMetaData)
                {
                    // prio1 in a transitive manner (current stage)
                    return(true);
                }
                if (IsPrio2Member(rootMetaData, childMetaData, children, entityTypeToPrefetchSteps, alreadyVisited, mergePrefetchPathsCache))
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
            }
        }