public ISet <IObjRef> lookForIntermediateDeletes() { CHashSet <IObjRef> intermediateDeletes = new CHashSet <IObjRef>(); // Hold cache values as hard ref to prohibit cache loss due to GC IList <IObjRef> hardRefRequest = hardRefObjRefsToLoad.ToList(); IList <Object> hardRefResult = rootCache.GetObjects(hardRefRequest, cacheValueResultAndReturnMissesSet); for (int a = hardRefResult.Count; a-- > 0;) { Object hardRef = hardRefResult[a]; if (hardRef != null) { continue; } // Objects are marked as UPDATED in the DCE, but could not be newly retrieved from the server // This occurs if a fast DELETE event on the server happened but has not been processed, yet IObjRef hardRefObjRefToLoad = hardRefRequest[a]; intermediateDeletes.Add(hardRefObjRefToLoad); } this.privilegedHardRefResult = hardRefResult; RemoveNotFoundObjRefs(intermediateDeletes.ToArray()); return(intermediateDeletes); }
protected void ChangeSecondLevelCacheIntern(CacheDependencyNode node, CacheDirective cacheDirective) { IRootCache rootCache = node.rootCache; HashMap <IObjRef, CacheValueAndPrivilege> objRefToLoadContainerDict = node.objRefToCacheValueMap; CHashSet <IObjRef> objRefsToLoad = new CHashSet <IObjRef>(node.objRefsToLoad); if (node.cacheChangeItems != null) { foreach (CacheChangeItem cci in node.cacheChangeItems) { if (cci == null) { continue; } objRefsToLoad.AddAll(cci.UpdatedObjRefs); } } IList <IObjRef> objRefs = objRefsToLoad.ToList(); IList <Object> refreshResult = rootCache.GetObjects(objRefs, cacheDirective); IPrivilege[] privileges = null; if (SecurityActivation != null && PrivilegeProvider != null && SecurityActivation.FilterActivated) { privileges = PrivilegeProvider.GetPrivilegesByObjRef(objRefs).GetPrivileges(); } for (int a = refreshResult.Count; a-- > 0;) { RootCacheValue cacheValue = (RootCacheValue)refreshResult[a]; if (cacheValue == null) { continue; } objRefToLoadContainerDict.Put(objRefs[a], new CacheValueAndPrivilege(cacheValue, privileges != null ? privileges[a] : null)); } CheckCascadeRefreshNeeded(node); CHashSet <IObjRef> cascadeRefreshObjRefsSet = node.cascadeRefreshObjRefsSet; CHashSet <IObjRelation> cascadeRefreshObjRelationsSet = node.cascadeRefreshObjRelationsSet; if (cascadeRefreshObjRelationsSet.Count > 0) { IList <IObjRelationResult> relationsResult = rootCache.GetObjRelations(cascadeRefreshObjRelationsSet.ToList(), cacheDirective); for (int a = relationsResult.Count; a-- > 0;) { IObjRelationResult relationResult = relationsResult[a]; cascadeRefreshObjRefsSet.AddAll(relationResult.Relations); } // apply gathered information of unknown relations to the rootCache rootCache.Put(relationsResult); } if (cascadeRefreshObjRefsSet.Count > 0) { IList <IObjRef> cascadeRefreshObjRefsSetList = cascadeRefreshObjRefsSet.ToList(); refreshResult = rootCache.GetObjects(cascadeRefreshObjRefsSetList, cacheDirective); } List <CacheDependencyNode> childNodes = node.childNodes; for (int a = childNodes.Count; a-- > 0;) { ChangeSecondLevelCacheIntern(childNodes[a], failInCacheHierarchyAndCacheValueResultAndReturnMissesSet); } }
protected void DataChangedIntern(IDataChange dataChange, IList <Object> pausedEventTargets, IProcessResumeItem processResumeItem, CacheDependencyNode rootNode) { try { bool isLocalSource = dataChange.IsLocalSource; IList <IDataChangeEntry> deletes = dataChange.Deletes; IList <IDataChangeEntry> updates = dataChange.Updates; IList <IDataChangeEntry> inserts = dataChange.Inserts; CHashSet <Type> occuringTypes = new CHashSet <Type>(); CHashSet <IObjRef> deletesSet = new CHashSet <IObjRef>(); CHashSet <Type> directRelatingTypes = new CHashSet <Type>(); bool acquirementSuccessful = rootNode.rootCache.AcquireHardRefTLIfNotAlready(); try { for (int a = deletes.Count; a-- > 0;) { IDataChangeEntry deleteEntry = deletes[a]; Type entityType = deleteEntry.EntityType; occuringTypes.Add(entityType); if (deleteEntry is DirectDataChangeEntry) { // Ignore delete entries of unpersisted objects here continue; } ObjRef tempORI = new ObjRef(entityType, deleteEntry.IdNameIndex, deleteEntry.Id, deleteEntry.Version); deletesSet.Add(tempORI); } // Remove items from the cache only if they are really deleted/updates by a remote event // And not 'simulated' by a local source bool cleanupSecondLevelCaches = false; if (pausedEventTargets != null && (deletes.Count > 0 || updates.Count > 0) && !isLocalSource) { cleanupSecondLevelCaches = true; } else if (updates.Count > 0) { for (int a = updates.Count; a-- > 0;) { IDataChangeEntry updateEntry = updates[a]; Type entityType = updateEntry.EntityType; occuringTypes.Add(entityType); } } for (int a = inserts.Count; a-- > 0;) { IDataChangeEntry insertEntry = inserts[a]; Type entityType = insertEntry.EntityType; occuringTypes.Add(entityType); } EnsureMetaDataIsLoaded(occuringTypes, directRelatingTypes); if (cleanupSecondLevelCaches) { CleanupSecondLevelCaches(rootNode, deletesSet.ToList(), updates, occuringTypes); } BuildCacheChangeItems(rootNode, dataChange); rootNode.AggregateAllCascadedObjRefs(); ISet <IObjRef> intermediateDeletes = rootNode.lookForIntermediateDeletes(); ChangeSecondLevelCache(rootNode); if (rootNode.IsPendingChangeOnAnyChildCache()) { GuiThreadHelper.InvokeInGuiAndWait(delegate() { bool oldFailEarlyModeActive = AbstractCache.FailInCacheHierarchyModeActive; AbstractCache.FailInCacheHierarchyModeActive = true; try { ChangeFirstLevelCaches(rootNode, intermediateDeletes); } finally { AbstractCache.FailInCacheHierarchyModeActive = oldFailEarlyModeActive; } }); } } finally { rootNode.rootCache.ClearHardRefs(acquirementSuccessful); } } finally { if (processResumeItem != null) { processResumeItem.ResumeProcessingFinished(); } } }