Exemplo n.º 1
0
 protected void AddCascadeLoadItem(DirectValueHolderRef vhr, PrefetchPath[] cachePaths, IList <PrefetchCommand> cascadeLoadItems)
 {
     if (cachePaths != null || !vhr.ObjRefsOnly)
     {
         PrefetchCommand cascadeLoadItem = new PrefetchCommand(vhr, cachePaths);
         cascadeLoadItems.Add(cascadeLoadItem);
     }
 }
Exemplo n.º 2
0
        public override bool Equals(Object obj)
        {
            if (obj == this)
            {
                return(true);
            }
            if (!(obj is DirectValueHolderRef))
            {
                return(false);
            }
            DirectValueHolderRef other = (DirectValueHolderRef)obj;

            return(Object.ReferenceEquals(Vhc, other.Vhc) && Object.ReferenceEquals(Member, other.Member));
        }
Exemplo n.º 3
0
 public PrefetchCommand(DirectValueHolderRef valueHolder, PrefetchPath[] prefetchPaths)
 {
     this.valueHolder   = valueHolder;
     this.prefetchPaths = prefetchPaths;
 }
Exemplo n.º 4
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);
            }
        }
Exemplo n.º 5
0
        protected bool HandleValueHolder(DirectValueHolderRef vhr, PrefetchPath[] cachePaths, 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)
        {
            RelationMember member       = vhr.Member;
            bool           newOriToLoad = false;

            if (vhr is IndirectValueHolderRef)
            {
                RootCacheValue  rcv           = (RootCacheValue)vhr.Vhc;
                ICacheIntern    rootCache     = ((IndirectValueHolderRef)vhr).RootCache;
                IEntityMetaData metaData      = EntityMetaDataProvider.GetMetaData(rcv.EntityType);
                int             relationIndex = metaData.GetIndexByRelation(member);
                IObjRef[]       rcvObjRefs    = rcv.GetRelation(relationIndex);
                if (rcvObjRefs == null)
                {
                    IObjRelation        self = ValueHolderContainerMixin.GetSelf(rcv, member.Name);
                    ISet <IObjRelation> orelsLoadedHistory = cacheToOrelsLoadedHistory.Get(rootCache);
                    if (orelsLoadedHistory == null || !orelsLoadedHistory.Contains(self))
                    {
                        IMap <IObjRelation, bool> orelsToLoad = cacheToOrelsToLoad.Get(rootCache);
                        if (orelsToLoad == null)
                        {
                            orelsToLoad = new HashMap <IObjRelation, bool>();
                            cacheToOrelsToLoad.Put(rootCache, orelsToLoad);
                        }
                        orelsToLoad.Put(self, vhr.ObjRefsOnly);
                        AddCascadeLoadItem(vhr, cachePaths, cascadeLoadItems);
                    }
                    return(false);
                }
                else if (!vhr.ObjRefsOnly && rcvObjRefs.Length > 0)
                {
                    ISet <IObjRef> orisLoadedHistory = cacheToOrisLoadedHistory.Get(rootCache);
                    for (int b = rcvObjRefs.Length; b-- > 0;)
                    {
                        IObjRef ori = rcvObjRefs[b];
                        if (orisLoadedHistory != null && orisLoadedHistory.Contains(ori))
                        {
                            // Object has been tried to load before but it is obviously not in the cache
                            // So the load must have been failed somehow. It is assumed that the entity
                            // is not persisted in the database anymore (deleted before) so the ORI is illegal.
                            // We cleanup the ValueHolder so that future calls will not lead to
                            // another unnecessary roundtrip to the server
                            rcvObjRefs[b] = null;
                            continue;
                        }
                        IISet <IObjRef> orisToLoad = cacheToOrisToLoad.Get(rootCache);
                        if (orisToLoad == null)
                        {
                            orisToLoad = new CHashSet <IObjRef>();
                            cacheToOrisToLoad.Put(rootCache, orisToLoad);
                        }
                        orisToLoad.Add(ori);
                        newOriToLoad = true;
                    }
                    if (newOriToLoad)
                    {
                        AddCascadeLoadItem(vhr, cachePaths, cascadeLoadItems);
                    }
                }
                return(false);
            }
            IValueHolderContainer vhc = (IValueHolderContainer)vhr.Vhc;
            int relationIndex2        = vhc.Get__EntityMetaData().GetIndexByRelationName(member.Name);

            if (ValueHolderState.INIT == vhc.Get__State(relationIndex2))
            {
                return(true);
            }
            ICacheIntern cache = vhc.__TargetCache;

            IObjRef[] objRefs = vhc.Get__ObjRefs(relationIndex2);
            if (objRefs == null)
            {
                IObjRelation        self  = vhc.Get__Self(relationIndex2);
                List <IObjRelation> orels = new List <IObjRelation>();
                orels.Add(self);
                IList <IObjRelationResult> orelResults = cache.GetObjRelations(orels, cache, failEarlyReturnMisses);
                IObjRelationResult         orelResult  = orelResults[0];
                if (orelResult == null)
                {
                    ISet <IObjRelation> orelsLoadedHistory = cacheToOrelsLoadedHistory.Get(cache);
                    if (orelsLoadedHistory == null || !orelsLoadedHistory.Contains(self))
                    {
                        IMap <IObjRelation, bool> orelsToLoad = cacheToOrelsToLoad.Get(cache);
                        if (orelsToLoad == null)
                        {
                            orelsToLoad = new HashMap <IObjRelation, bool>();
                            cacheToOrelsToLoad.Put(cache, orelsToLoad);
                        }
                        orelsToLoad.Put(self, vhr.ObjRefsOnly);
                        AddCascadeLoadItem(vhr, cachePaths, cascadeLoadItems);
                    }
                    return(false);
                }
                objRefs = orelResult.Relations;
                if (objRefs != null)
                {
                    vhc.Set__ObjRefs(relationIndex2, objRefs);
                }
            }
            if (!vhr.ObjRefsOnly && objRefs != null && objRefs.Length > 0)
            {
                IList <Object> loadedObjects = cache.GetObjects(new List <IObjRef>(objRefs), cache, failEarlyReturnMisses);
                try
                {
                    for (int b = objRefs.Length; b-- > 0;)
                    {
                        IObjRef ori          = objRefs[b];
                        Object  loadedObject = loadedObjects[b];
                        if (loadedObject != null)
                        {
                            continue;
                        }
                        ISet <IObjRef> orisLoadedHistory = cacheToOrisLoadedHistory.Get(cache);
                        if (orisLoadedHistory != null && orisLoadedHistory.Contains(ori))
                        {
                            // Object has been tried to load before but it is obviously not in the cache
                            // So the load must have been failed somehow. It is assumed that the entity
                            // is not persisted in the database anymore (deleted before) so the ORI is illegal.
                            // We cleanup the ValueHolder so that future calls will not lead to
                            // another unnecessary roundtrip to the server
                            objRefs[b] = null;
                            continue;
                        }
                        IISet <IObjRef> orisToLoad = cacheToOrisToLoad.Get(cache);
                        if (orisToLoad == null)
                        {
                            orisToLoad = new CHashSet <IObjRef>();
                            cacheToOrisToLoad.Put(cache, orisToLoad);
                        }
                        orisToLoad.Add(ori);
                        newOriToLoad = true;
                    }
                }
                finally
                {
                    loadedObjects.Clear();
                    loadedObjects = null;
                }
            }
            if (objRefs == null || newOriToLoad)
            {
                AddCascadeLoadItem(vhr, cachePaths, cascadeLoadItems);
                return(false);
            }
            return(true);
        }
Exemplo n.º 6
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);
            }
        }
Exemplo n.º 7
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);
            }
        }