Beispiel #1
0
        protected void EnsureInitializedRelationsIntern3(Object obj, PrefetchPath[] cachePaths, ILinkedMap <Type, PrefetchPath[]> entityTypeToPrefetchPaths,
                                                         IMap <ICacheIntern, IISet <IObjRef> > cacheToOrisToLoad, IMap <ICacheIntern, IMap <IObjRelation, bool> > cacheToOrelsToLoad,
                                                         IMap <ICacheIntern, IISet <IObjRef> > cacheToOrisLoadedHistory, IMap <ICacheIntern, IISet <IObjRelation> > cacheToOrelsLoadedHistory,
                                                         AlreadyHandledSet alreadyHandledSet, IList <PrefetchCommand> cascadeLoadItems)
        {
            if (obj == null)
            {
                return;
            }
            if (!alreadyHandledSet.PutIfNotExists(obj, cachePaths, true))
            {
                return;
            }
            if (obj is IndirectValueHolderRef)
            {
                IndirectValueHolderRef vhk = (IndirectValueHolderRef)obj;
                HandleValueHolder(vhk, cachePaths, cacheToOrisToLoad, cacheToOrelsToLoad, cacheToOrisLoadedHistory, cacheToOrelsLoadedHistory,
                                  alreadyHandledSet, cascadeLoadItems);
                // Do nothing because this is only to prefetch RootCache entries
                return;
            }
            else if (obj is DirectValueHolderRef)
            {
                DirectValueHolderRef vhk = (DirectValueHolderRef)obj;
                if (!HandleValueHolder(vhk, cachePaths, cacheToOrisToLoad, cacheToOrelsToLoad, cacheToOrisLoadedHistory, cacheToOrelsLoadedHistory,
                                       alreadyHandledSet, cascadeLoadItems))
                {
                    return;
                }
                // force valueholder init. at this point we know that all related items are already in the cache. there will be no roundtrip
                // to the server
                if (vhk.Member == null)
                {
                    obj = vhk.Vhc;
                }
                else
                {
                    obj = vhk.Member.GetValue(vhk.Vhc);
                }
            }
            if (obj == null)
            {
                // this check is necessary because even if we create only instances of DirectValueHolderRef in cases where there is a not initalized relation
                // even then it might be possible that a concurrent thread initializes the valueholder to null (e.g. an empty to-one relation)
                return;
            }
            if ((cachePaths == null || cachePaths.Length == 0) && entityTypeToPrefetchPaths == null)
            {
                return;
            }
            if (obj is IEnumerable)
            {
                var items = new List <Object>();
                foreach (Object item in (IEnumerable)obj)
                {
                    if (item == null)
                    {
                        continue;
                    }
                    items.Add(item);
                }
                foreach (Object item in items)
                {
                    EnsureInitializedRelationsIntern3(item, cachePaths, entityTypeToPrefetchPaths, cacheToOrisToLoad, cacheToOrelsToLoad,
                                                      cacheToOrisLoadedHistory, cacheToOrelsLoadedHistory, alreadyHandledSet, cascadeLoadItems);
                }
                return;
            }
            IEntityMetaData metaData = ((IEntityMetaDataHolder)obj).Get__EntityMetaData();

            if (cachePaths == null || cachePaths.Length == 0)
            {
                if (entityTypeToPrefetchPaths != null)
                {
                    cachePaths = entityTypeToPrefetchPaths.Get(metaData.EntityType);
                }
                if (cachePaths == null || cachePaths.Length == 0)
                {
                    return;
                }
            }
            RelationMember[] relationMembers = metaData.RelationMembers;
            if (relationMembers.Length == 0)
            {
                return;
            }
            IValueHolderContainer vhc = (IValueHolderContainer)obj;

            for (int a = cachePaths.Length; a-- > 0;)
            {
                PrefetchPath path = cachePaths[a];

                int            relationIndex = path.memberIndex;
                RelationMember member        = relationMembers[relationIndex];

                if (ValueHolderState.INIT != vhc.Get__State(relationIndex))
                {
                    DirectValueHolderRef vhk = new DirectValueHolderRef(vhc, member);
                    EnsureInitializedRelationsIntern3(vhk, path.children, entityTypeToPrefetchPaths, cacheToOrisToLoad, cacheToOrelsToLoad, cacheToOrisLoadedHistory,
                                                      cacheToOrelsLoadedHistory, alreadyHandledSet, cascadeLoadItems);
                    continue;
                }
                Object memberValue = member.GetValue(obj);
                if (memberValue == null)
                {
                    continue;
                }
                EnsureInitializedRelationsIntern3(memberValue, path.children, entityTypeToPrefetchPaths, cacheToOrisToLoad, cacheToOrelsToLoad,
                                                  cacheToOrisLoadedHistory, cacheToOrelsLoadedHistory, alreadyHandledSet, cascadeLoadItems);
            }
        }
Beispiel #2
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);
            }
        }