protected IObjRef ExtractAndMergeObjRef(IDataChangeEntry dataChangeEntry, IDictionary <IObjRef, IObjRef> touchedObjRefSet) { IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(dataChangeEntry.EntityType); IObjRef objRef = GetObjRef(dataChangeEntry, metaData); IObjRef existingObjRef = DictionaryExtension.ValueOrDefault(touchedObjRefSet, objRef); if (existingObjRef == null) { touchedObjRefSet.Add(objRef, objRef); return(objRef); } Object newVersion = objRef.Version; Object existingVersion = existingObjRef.Version; if (newVersion == null) { return(existingObjRef); } if (existingVersion == null || ((IComparable)newVersion).CompareTo(existingVersion) >= 0) { existingObjRef.Version = newVersion; } return(existingObjRef); }
protected void CleanupSecondLevelCaches(CacheDependencyNode node, IList <IObjRef> deletesList, IList <IDataChangeEntry> updates, CHashSet <Type> occuringTypes) { List <IObjRef> objRefsRemovePriorVersions = new List <IObjRef>(updates.Count); for (int a = updates.Count; a-- > 0;) { IDataChangeEntry updateEntry = updates[a]; Type entityType = updateEntry.EntityType; occuringTypes.Add(entityType); objRefsRemovePriorVersions.Add(new ObjRef(entityType, updateEntry.IdNameIndex, updateEntry.Id, updateEntry.Version)); } CleanupSecondLevelCachesIntern(node, deletesList, objRefsRemovePriorVersions); }
protected IObjRef GetObjRef(IDataChangeEntry dataChangeEntry, IEntityMetaData metaData) { if (dataChangeEntry is DirectDataChangeEntry) { return(new DirectObjRef(dataChangeEntry.EntityType, ((DirectDataChangeEntry)dataChangeEntry).Entry)); } Object id = dataChangeEntry.Id; sbyte idIndex = dataChangeEntry.IdNameIndex; Member idMember = metaData.GetIdMemberByIdIndex(idIndex); Member versionMember = metaData.VersionMember; id = ConversionHelper.ConvertValueToType(idMember.RealType, id); Object version = versionMember != null?ConversionHelper.ConvertValueToType(versionMember.RealType, dataChangeEntry.Version) : null; return(new ObjRef(dataChangeEntry.EntityType, idIndex, id, version)); }
protected void BuildCacheChangeItems(CacheDependencyNode rootNode, IDataChange dataChange) { List <IDataChangeEntry> insertsAndUpdates = new List <IDataChangeEntry>(); IList <IDataChangeEntry> deletes = dataChange.Deletes; insertsAndUpdates.AddRange(dataChange.Updates); insertsAndUpdates.AddRange(dataChange.Inserts); List <IObjRef> changesToSearchInCache = new List <IObjRef>(insertsAndUpdates.Count); List <IObjRef> changesWithVersion = new List <IObjRef>(insertsAndUpdates.Count); List <IObjRef> deletesToSearchInCache = new List <IObjRef>(deletes.Count); for (int a = deletes.Count; a-- > 0;) { IDataChangeEntry deleteEntry = deletes[a]; Object id = deleteEntry.Id; if (id == null) { deletesToSearchInCache.Add(null); continue; } deletesToSearchInCache.Add(new ObjRef(deleteEntry.EntityType, deleteEntry.IdNameIndex, id, null)); } for (int a = insertsAndUpdates.Count; a-- > 0;) { IDataChangeEntry updateEntry = insertsAndUpdates[a]; Object id = updateEntry.Id; if (id == null) { changesToSearchInCache.Add(null); continue; } changesToSearchInCache.Add(new ObjRef(updateEntry.EntityType, updateEntry.IdNameIndex, id, null)); changesWithVersion.Add(new ObjRef(updateEntry.EntityType, updateEntry.IdNameIndex, id, updateEntry.Version)); } BuildCacheChangeItems(rootNode, deletesToSearchInCache, changesToSearchInCache, changesWithVersion); }
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(); } } }