コード例 #1
0
ファイル: MergeServiceRegistry.cs プロジェクト: vogelb/ambeth
        public IList <IEntityMetaData> GetMetaData(IList <Type> entityTypes)
        {
            IdentityHashMap <IMergeServiceExtension, IList <Type> > mseToEntityTypes = new IdentityHashMap <IMergeServiceExtension, IList <Type> >();

            for (int a = entityTypes.Count; a-- > 0;)
            {
                Type entityType = entityTypes[a];
                IMergeServiceExtension mergeServiceExtension = mergeServiceExtensions.GetExtension(entityType);
                if (mergeServiceExtension == null)
                {
                    continue;
                }
                IList <Type> groupedEntityTypes = mseToEntityTypes.Get(mergeServiceExtension);
                if (groupedEntityTypes == null)
                {
                    groupedEntityTypes = new List <Type>();
                    mseToEntityTypes.Put(mergeServiceExtension, groupedEntityTypes);
                }
                groupedEntityTypes.Add(entityType);
            }
            List <IEntityMetaData> metaDataResult = new List <IEntityMetaData>(entityTypes.Count);

            foreach (Entry <IMergeServiceExtension, IList <Type> > entry in mseToEntityTypes)
            {
                IList <IEntityMetaData> groupedMetaData = entry.Key.GetMetaData(entry.Value);
                metaDataResult.AddRange(groupedMetaData);
            }
            return(metaDataResult);
        }
コード例 #2
0
ファイル: MergeServiceRegistry.cs プロジェクト: vogelb/ambeth
        protected IMergeServiceExtension GetServiceForType(Type type)
        {
            if (type == null)
            {
                return(null);
            }
            IMergeServiceExtension mse = mergeServiceExtensions.GetExtension(type);

            if (mse == null)
            {
                throw new Exception("No merge service found to handle entity type '" + type.FullName + "'");
            }
            return(mse);
        }
コード例 #3
0
ファイル: MergeServiceRegistry.cs プロジェクト: vogelb/ambeth
        protected ICUDResult WhatIfMerged(ICUDResult cudResult, IMethodDescription methodDescription, List <MergeOperation> mergeOperationSequence,
                                          IncrementalMergeState incrementalState)
        {
            IList <MergeOperation> lastMergeOperationSequence;

            while (true)
            {
                IMap <Type, IList <IChangeContainer> > sortedChanges = BucketSortChanges(cudResult.AllChanges);
                lastMergeOperationSequence = CreateMergeOperationSequence(sortedChanges);

                ParamHolder <bool>     hasAtLeastOneImplicitChange = new ParamHolder <bool>(false);
                IList <MergeOperation> fLastMergeOperationSequence = lastMergeOperationSequence;
                cudResult = CacheContext.ExecuteWithCache(incrementalState.GetStateCache(), delegate(ICUDResult cudResult2)
                {
                    for (int a = 0, size = fLastMergeOperationSequence.Count; a < size; a++)
                    {
                        MergeOperation mergeOperation = fLastMergeOperationSequence[a];
                        IMergeServiceExtension mergeServiceExtension = mergeOperation.MergeServiceExtension;

                        ICUDResult explAndImplCudResult = mergeServiceExtension.EvaluateImplicitChanges(cudResult2, incrementalState);
                        cudResult2 = MergeCudResult(cudResult2, explAndImplCudResult, mergeServiceExtension, hasAtLeastOneImplicitChange,
                                                    incrementalState);
                    }
                    return(cudResult2);
                }, cudResult);
                foreach (IMergeListener mergeListener in mergeListeners.GetExtensions())
                {
                    ICUDResult explAndImplCudResult = mergeListener.PreMerge(cudResult, incrementalState.GetStateCache());
                    cudResult = MergeCudResult(cudResult, explAndImplCudResult, mergeListener, hasAtLeastOneImplicitChange, incrementalState);
                }
                if (!hasAtLeastOneImplicitChange.Value)
                {
                    break;
                }
            }
            mergeOperationSequence.AddRange(lastMergeOperationSequence);
            return(cudResult);
        }
コード例 #4
0
ファイル: MergeServiceRegistry.cs プロジェクト: vogelb/ambeth
 public void UnregisterMergeServiceExtension(IMergeServiceExtension mergeServiceExtension, Type entityType)
 {
     mergeServiceExtensions.Unregister(mergeServiceExtension, entityType);
 }
コード例 #5
0
ファイル: MergeServiceRegistry.cs プロジェクト: vogelb/ambeth
        protected IList <MergeOperation> CreateMergeOperationSequence(IMap <Type, IList <IChangeContainer> > sortedChanges)
        {
            Type[] entityPersistOrder = EntityMetaDataProvider.GetEntityPersistOrder();
            IList <MergeOperation> mergeOperations = new List <MergeOperation>();

            if (entityPersistOrder != null)
            {
                for (int a = entityPersistOrder.Length; a-- > 0;)
                {
                    Type orderedEntityType           = entityPersistOrder[a];
                    IList <IChangeContainer> changes = sortedChanges.Get(orderedEntityType);
                    if (changes == null)
                    {
                        // No changes of current type found. Nothing to do here
                        continue;
                    }
                    List <IChangeContainer> removes           = new List <IChangeContainer>(changes.Count);
                    List <IChangeContainer> insertsAndUpdates = new List <IChangeContainer>(changes.Count);
                    for (int b = changes.Count; b-- > 0;)
                    {
                        IChangeContainer change = changes[b];
                        if (change is DeleteContainer)
                        {
                            removes.Add(change);
                        }
                        else
                        {
                            insertsAndUpdates.Add(change);
                        }
                    }
                    if (removes.Count == 0)
                    {
                        // Nothing to do. Ordering is not necessary here
                        continue;
                    }
                    if (insertsAndUpdates.Count == 0)
                    {
                        sortedChanges.Remove(orderedEntityType);
                    }
                    else
                    {
                        sortedChanges.Put(orderedEntityType, insertsAndUpdates);
                    }
                    IMergeServiceExtension mergeServiceExtension = GetServiceForType(orderedEntityType);
                    MergeOperation         mergeOperation        = new MergeOperation();
                    mergeOperation.MergeServiceExtension = mergeServiceExtension;
                    mergeOperation.ChangeContainer       = removes;

                    mergeOperations.Add(mergeOperation);
                }

                for (int a = 0, size = entityPersistOrder.Length; a < size; a++)
                {
                    Type orderedEntityType           = entityPersistOrder[a];
                    IList <IChangeContainer> changes = sortedChanges.Get(orderedEntityType);
                    if (changes == null)
                    {
                        // No changes of current type found. Nothing to do here
                        continue;
                    }
                    bool containsNew = false;
                    for (int b = changes.Count; b-- > 0;)
                    {
                        if (changes[b].Reference.Id == null)
                        {
                            containsNew = true;
                            break;
                        }
                    }
                    if (!containsNew)
                    {
                        // Nothing to do. Ordering is not necessary here
                        continue;
                    }
                    // Remove batch of changes where at least 1 new entity occured and
                    // this type of entity has to be inserted in a global order
                    sortedChanges.Remove(orderedEntityType);
                    IMergeServiceExtension mergeServiceExtension = GetServiceForType(orderedEntityType);
                    MergeOperation         mergeOperation        = new MergeOperation();
                    mergeOperation.MergeServiceExtension = mergeServiceExtension;
                    mergeOperation.ChangeContainer       = changes;

                    mergeOperations.Add(mergeOperation);
                }
            }

            // Everything which is left in the sortedChanges map can be merged without global order, so batch together as much as possible
            foreach (Entry <Type, IList <IChangeContainer> > entry in sortedChanges)
            {
                Type type = entry.Key;
                IList <IChangeContainer> unorderedChanges      = entry.Value;
                IMergeServiceExtension   mergeServiceExtension = GetServiceForType(type);

                if (mergeServiceExtension == null)
                {
                    throw new Exception("No extension found to merge entities of type '" + type.FullName + "'");
                }
                bool cont = false;
                foreach (MergeOperation existingMergeOperation in mergeOperations)
                {
                    if (Object.ReferenceEquals(existingMergeOperation.MergeServiceExtension, mergeServiceExtension))
                    {
                        IList <IChangeContainer> orderedChanges = existingMergeOperation.ChangeContainer;
                        for (int b = unorderedChanges.Count; b-- > 0;)
                        {
                            orderedChanges.Add(unorderedChanges[b]);
                        }
                        cont = true;
                        break;
                    }
                }
                if (cont)
                {
                    continue;
                }
                MergeOperation mergeOperation = new MergeOperation();
                mergeOperation.MergeServiceExtension = mergeServiceExtension;
                mergeOperation.ChangeContainer       = unorderedChanges;

                mergeOperations.Add(mergeOperation);
            }
            ;
            return(mergeOperations);
        }
コード例 #6
0
ファイル: MergeServiceRegistry.cs プロジェクト: vogelb/ambeth
        protected IOriCollection Intern(ICUDResult cudResult, IMethodDescription methodDescription, IList <MergeOperation> mergeOperationSequence,
                                        IncrementalMergeState state)
        {
            IList <IChangeContainer> allChanges   = cudResult.AllChanges;
            IList <Object>           originalRefs = cudResult.GetOriginalRefs();
            IdentityHashMap <IChangeContainer, int> changeToChangeIndexDict = new IdentityHashMap <IChangeContainer, int>();

            for (int a = allChanges.Count; a-- > 0;)
            {
                changeToChangeIndexDict.Put(allChanges[a], a);
            }
            IObjRef[] objRefs      = new IObjRef[allChanges.Count];
            long[]    allChangedOn = new long[allChanges.Count];
            String[]  allChangedBy = new String[allChanges.Count];

            CHashSet <long>   changedOnSet = new CHashSet <long>();
            CHashSet <String> changedBySet = new CHashSet <String>();

            for (int a = 0, size = mergeOperationSequence.Count; a < size; a++)
            {
                MergeOperation         mergeOperation        = mergeOperationSequence[a];
                IMergeServiceExtension mergeServiceExtension = mergeOperation.MergeServiceExtension;

                IList <IChangeContainer> changesForMergeService = mergeOperation.ChangeContainer;
                ICUDResult msCudResult = BuildCUDResult(changesForMergeService, changeToChangeIndexDict, originalRefs);

                IOriCollection msOriCollection = mergeServiceExtension.Merge(msCudResult, methodDescription);

                MergeController.ApplyChangesToOriginals(msCudResult, msOriCollection, state.GetStateCache());

                IList <IObjRef> allChangeORIs = msOriCollection.AllChangeORIs;

                long?  msDefaultChangedOn = msOriCollection.ChangedOn;
                String msDefaultChangedBy = msOriCollection.ChangedBy;

                long[]   msAllChangedOn = msOriCollection.AllChangedOn;
                String[] msAllChangedBy = msOriCollection.AllChangedBy;
                for (int b = changesForMergeService.Count; b-- > 0;)
                {
                    int index = changeToChangeIndexDict.Get(changesForMergeService[b]);
                    objRefs[index] = allChangeORIs[b];

                    if (msAllChangedOn != null)
                    {
                        long msChangedOn = msAllChangedOn[b];
                        allChangedOn[index] = msChangedOn;
                        changedOnSet.Add(msChangedOn);
                    }
                    else
                    {
                        allChangedOn[index] = msDefaultChangedOn.Value;
                    }
                    if (msAllChangedBy != null)
                    {
                        String msChangedBy = msAllChangedBy[b];
                        allChangedBy[index] = msChangedBy;
                        changedBySet.Add(msChangedBy);
                    }
                    else
                    {
                        allChangedBy[index] = msDefaultChangedBy;
                    }
                }
                if (msDefaultChangedOn != null)
                {
                    changedOnSet.Add(msDefaultChangedOn.Value);
                }
                if (msDefaultChangedBy != null)
                {
                    changedBySet.Add(msDefaultChangedBy);
                }
            }
            OriCollection oriCollection = new OriCollection();

            oriCollection.AllChangeORIs = new List <IObjRef>(objRefs);

            if (changedBySet.Count == 1)
            {
                Iterator <String> iter = changedBySet.Iterator();
                iter.MoveNext();
                oriCollection.ChangedBy = iter.Current;
            }
            else
            {
                oriCollection.AllChangedBy = allChangedBy;
            }
            if (changedOnSet.Count == 1)
            {
                Iterator <long> iter = changedOnSet.Iterator();
                iter.MoveNext();
                oriCollection.ChangedOn = iter.Current;
            }
            else
            {
                oriCollection.AllChangedOn = allChangedOn;
            }
            foreach (IMergeListener mergeListener in mergeListeners.GetExtensions())
            {
                mergeListener.PostMerge(cudResult, objRefs);
            }
            if (originalRefs != null)
            {
                // Set each original ref to null in order to suppress a post-processing in a potentially calling IMergeProcess
                for (int a = originalRefs.Count; a-- > 0;)
                {
                    originalRefs[a] = null;
                }
            }
            // TODO DCE must be fired HERE <---
            return(oriCollection);
        }