コード例 #1
0
        public StrongReferenceContainer Prefetch(Key key, TypeInfo type, IList <PrefetchFieldDescriptor> descriptors)
        {
            ArgumentValidator.EnsureArgumentNotNull(key, "key");
            ArgumentValidator.EnsureArgumentNotNull(descriptors, "fields");
            if (descriptors.Count == 0)
            {
                return(null);
            }

            try {
                EnsureKeyTypeCorrespondsToSpecifiedType(key, type);

                EntityState ownerState;
                var         currentKey = key;
                if (!TryGetTupleOfNonRemovedEntity(ref currentKey, out ownerState))
                {
                    return(null);
                }
                var selectedFields = descriptors;
                var currentType    = type;
                StrongReferenceContainer hierarchyRootContainer = null;
                var isKeyTypeExact = currentKey.HasExactType ||
                                     currentKey.TypeReference.Type.IsLeaf ||
                                     currentKey.TypeReference.Type == type;
                if (isKeyTypeExact)
                {
                    currentType = currentKey.TypeReference.Type;
                    EnsureAllFieldsBelongToSpecifiedType(descriptors, currentType);
                }
                else
                {
                    ArgumentValidator.EnsureArgumentNotNull(currentType, "type");
                    EnsureAllFieldsBelongToSpecifiedType(descriptors, currentType);
                    SetUpContainers(currentKey, currentKey.TypeReference.Type,
                                    PrefetchHelper.GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, currentKey.TypeReference.Type),
                                    true, ownerState, true);
                    var hierarchyRoot = currentKey.TypeReference.Type;
                    selectedFields = descriptors
                                     .Where(descriptor => descriptor.Field.DeclaringType != hierarchyRoot)
                                     .ToList();
                }
                SetUpContainers(currentKey, currentType, selectedFields, isKeyTypeExact, ownerState, ReferenceEquals(descriptors, selectedFields));

                StrongReferenceContainer container = null;
                if (graphContainers.Count >= MaxContainerCount)
                {
                    container = ExecuteTasks();
                }
                if (referenceContainer != null)
                {
                    referenceContainer.JoinIfPossible(container);
                    return(referenceContainer);
                }
                return(container);
            }
            catch {
                CancelTasks();
                throw;
            }
        }
コード例 #2
0
        public IEnumerator <T> GetEnumerator()
        {
            TypeInfo modelType;

            session.Domain.Model.Types.TryGetValue(typeof(T), out modelType);
            var  taskCount        = session.Handler.PrefetchTaskExecutionCount;
            var  container        = new StrongReferenceContainer(null);
            var  fieldDescriptors = new List <PrefetchFieldDescriptor>();
            var  resultQueue      = new Queue <Key>();
            var  unknownTypeQueue = new Queue <Key>();
            var  se = source.GetEnumerator();
            bool exists;

            do
            {
                exists = se.MoveNext();
                if (exists)
                {
                    var key  = se.Current;
                    var type = key.HasExactType || modelType == null
            ? key.TypeReference.Type
            : modelType;
                    if (!key.HasExactType && !type.IsLeaf)
                    {
                        unknownTypeQueue.Enqueue(key);
                    }
                    resultQueue.Enqueue(key);
                    var defaultDescriptors = PrefetchHelper.GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, type);
                    container.JoinIfPossible(session.Handler.Prefetch(key, type, defaultDescriptors));
                }
                if (exists && taskCount == session.Handler.PrefetchTaskExecutionCount)
                {
                    continue;
                }

                if (!exists)
                {
                    container.JoinIfPossible(session.Handler.ExecutePrefetchTasks());
                }
                if (unknownTypeQueue.Count > 0)
                {
                    while (unknownTypeQueue.Count > 0)
                    {
                        var unknownKey         = unknownTypeQueue.Dequeue();
                        var unknownType        = session.EntityStateCache[unknownKey, false].Type;
                        var unknownDescriptors = PrefetchHelper.GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, unknownType);
                        session.Handler.Prefetch(unknownKey, unknownType, unknownDescriptors);
                    }
                    session.Handler.ExecutePrefetchTasks();
                }
                while (resultQueue.Count > 0)
                {
                    yield return((T)(IEntity)session.EntityStateCache[resultQueue.Dequeue(), true].Entity);
                }
                taskCount = session.Handler.PrefetchTaskExecutionCount;
            } while (exists);
        }
コード例 #3
0
        private void FillColumnCollection()
        {
            var descriptors = PrefetchHelper
                              .GetCachedDescriptorsForFieldsLoadedByDefault(Manager.Owner.Session.Domain, Type);
            SortedDictionary <int, ColumnInfo> columns;
            List <int> columnsToBeLoaded;

            Manager.GetCachedColumnIndexes(Type, descriptors, out columns, out columnsToBeLoaded);
            SetColumnCollections(columns, columnsToBeLoaded);
        }
コード例 #4
0
        private void RegisterFetchByKnownForeignKey(PrefetchFieldDescriptor referencingFieldDescriptor,
                                                    EntityState ownerState)
        {
            var association        = referencingFieldDescriptor.Field.Associations.Last();
            var referencedKeyTuple = association
                                     .ExtractForeignKey(ownerState.Type, ownerState.Tuple);
            var referencedKeyTupleState = referencedKeyTuple.GetFieldStateMap(TupleFieldState.Null);

            for (var i = 0; i < referencedKeyTupleState.Length; i++)
            {
                if (referencedKeyTupleState[i])
                {
                    return;
                }
            }
            var session       = Manager.Owner.Session;
            var referencedKey = Key.Create(session.Domain, session.StorageNodeId,
                                           association.TargetType, TypeReferenceAccuracy.BaseType,
                                           referencedKeyTuple);
            var      targetType       = association.TargetType;
            var      areToNotifyOwner = true;
            TypeInfo exactReferencedType;
            var      hasExactTypeBeenGotten = PrefetchHelper.TryGetExactKeyType(referencedKey, Manager,
                                                                                out exactReferencedType);

            if (hasExactTypeBeenGotten != null)
            {
                if (hasExactTypeBeenGotten.Value)
                {
                    targetType       = exactReferencedType;
                    areToNotifyOwner = false;
                }
            }
            else
            {
                return;
            }
            var fieldsToBeLoaded = PrefetchHelper
                                   .GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, targetType);
            var graphContainer = Manager.SetUpContainers(referencedKey, targetType,
                                                         fieldsToBeLoaded, true, null, true);

            if (areToNotifyOwner)
            {
                graphContainer.RootEntityContainer.SetParametersOfReference(referencingFieldDescriptor, referencedKey);
            }
        }
コード例 #5
0
        private async Task <StrongReferenceContainer> RegisterPrefetchAsync(IReadOnlyCollection <Key> keys,
                                                                            IHasNestedNodes fieldContainer, Guid enumerationId, CancellationToken token)
        {
            var      container = new StrongReferenceContainer(null);
            TypeInfo modelType = null;

            if (fieldContainer is ReferenceNode refNode)
            {
                modelType = refNode.ReferenceType;
            }

            foreach (var key in keys)
            {
                var type = key.HasExactType || modelType == null
          ? key.TypeReference.Type
          : modelType;
                if (!key.HasExactType && !type.IsLeaf)
                {
                    unknownTypeQueue.Enqueue(key);
                }

                var cacheKey = new Pair <IHasNestedNodes, TypeInfo>(fieldContainer, type);
                if (!fieldDescriptorCache.TryGetValue(cacheKey, out var fieldDescriptors))
                {
                    fieldDescriptors = PrefetchHelper
                                       .GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, type)
                                       .Concat(fieldContainer.NestedNodes.Select(fn => new PrefetchFieldDescriptor(fn.Field, false, true, enumerationId)))
                                       .ToList();
                    fieldDescriptorCache.Add(cacheKey, fieldDescriptors);
                }

                _ = container.JoinIfPossible(
                    await sessionHandler.PrefetchAsync(key, type, fieldDescriptors, token).ConfigureAwait(false));
            }

            var nestedContainers = fieldContainer.NestedNodes.OfType <IHasNestedNodes>();

            foreach (var nestedContainer in nestedContainers)
            {
                prefetchQueue.Enqueue(new Pair <IEnumerable <Key>, IHasNestedNodes>(keys, nestedContainer));
            }

            return(container);
        }
コード例 #6
0
        private StrongReferenceContainer RegisterPrefetch(IEnumerable <Key> keys, IHasNestedNodes fieldContainer)
        {
            var      container = new StrongReferenceContainer(null);
            TypeInfo modelType = null;
            var      refNode   = fieldContainer as ReferenceNode;

            if (refNode != null)
            {
                modelType = refNode.ReferenceType;
            }
            foreach (var key in keys)
            {
                var type = key.HasExactType || modelType == null
          ? key.TypeReference.Type
          : modelType;
                if (!key.HasExactType && !type.IsLeaf)
                {
                    unknownTypeQueue.Enqueue(key);
                }
                IList <PrefetchFieldDescriptor> fieldDescriptors;
                var cacheKey = new Pair <IHasNestedNodes, TypeInfo>(fieldContainer, type);
                if (!fieldDescriptorCache.TryGetValue(cacheKey, out fieldDescriptors))
                {
                    fieldDescriptors = PrefetchHelper
                                       .GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, type)
                                       .Concat(fieldContainer.NestedNodes.Select(fn => new PrefetchFieldDescriptor(fn.Field, false, true))).ToList();
                    fieldDescriptorCache.Add(cacheKey, fieldDescriptors);
                }
                container.JoinIfPossible(sessionHandler.Prefetch(key, type, fieldDescriptors));
            }
            var nestedContainers = fieldContainer.NestedNodes.OfType <IHasNestedNodes>();

            foreach (var nestedContainer in nestedContainers)
            {
                prefetchQueue.Enqueue(new Pair <IEnumerable <Key>, IHasNestedNodes>(keys, nestedContainer));
            }

            return(container);
        }
コード例 #7
0
        private async Task <StrongReferenceContainer> ProcessFetchedElementsAsync(Guid enumerationId, CancellationToken token)
        {
            var container = new StrongReferenceContainer(null);

            while (unknownTypeQueue.TryDequeue(out var unknownKey))
            {
                var unknownType        = session.EntityStateCache[unknownKey, false].Type;
                var unknownDescriptors =
                    PrefetchHelper.GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, unknownType);
                _ = await sessionHandler.PrefetchAsync(unknownKey, unknownType, unknownDescriptors, token).ConfigureAwait(false);
            }

            while (prefetchQueue.TryDequeue(out var pair))
            {
                var parentKeys  = pair.First;
                var nestedNodes = pair.Second;
                var keys        = new List <Key>();
                foreach (var parentKey in parentKeys)
                {
                    var entityState = session.EntityStateCache[parentKey, false];
                    if (entityState == null)
                    {
                        _           = container.JoinIfPossible(await sessionHandler.ExecutePrefetchTasksAsync(true, token).ConfigureAwait(false));
                        entityState = session.EntityStateCache[parentKey, false];
                        if (entityState == null)
                        {
                            throw new InvalidOperationException(string.Format(Strings.ExCannotResolveEntityWithKeyX, parentKey));
                        }
                    }

                    keys.AddRange(nestedNodes.ExtractKeys(entityState.Entity));
                }

                _ = container.JoinIfPossible(await RegisterPrefetchAsync(keys, nestedNodes, enumerationId, token).ConfigureAwait(false));
            }

            return(container);
        }
コード例 #8
0
        private StrongReferenceContainer ProcessFetchedElements()
        {
            var container = new StrongReferenceContainer(null);

            taskCount = sessionHandler.PrefetchTaskExecutionCount;
            while (unknownTypeQueue.Count > 0)
            {
                var unknownKey         = unknownTypeQueue.Dequeue();
                var unknownType        = session.EntityStateCache[unknownKey, false].Type;
                var unknownDescriptors = PrefetchHelper.GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, unknownType);
                sessionHandler.Prefetch(unknownKey, unknownType, unknownDescriptors);
            }
            while (prefetchQueue.Count > 0)
            {
                var pair        = prefetchQueue.Dequeue();
                var parentKeys  = pair.First;
                var nestedNodes = pair.Second;
                var keys        = new List <Key>();
                foreach (var parentKey in parentKeys)
                {
                    var entityState = session.EntityStateCache[parentKey, false];
                    if (entityState == null)
                    {
                        container.JoinIfPossible(sessionHandler.ExecutePrefetchTasks(true));
                        taskCount   = sessionHandler.PrefetchTaskExecutionCount;
                        entityState = session.EntityStateCache[parentKey, false];
                        if (entityState == null)
                        {
                            throw new InvalidOperationException(string.Format(Strings.ExCannotResolveEntityWithKeyX, parentKey));
                        }
                    }
                    keys.AddRange(nestedNodes.ExtractKeys(entityState.Entity));
                }
                container.JoinIfPossible(RegisterPrefetch(keys, nestedNodes));
            }
            return(container);
        }
コード例 #9
0
        public async IAsyncEnumerator <T> GetAsyncEnumerator(CancellationToken token = default)
        {
            session.Domain.Model.Types.TryGetValue(typeof(T), out var modelType);
            var taskCount        = session.Handler.PrefetchTaskExecutionCount;
            var container        = new StrongReferenceContainer(null);
            var resultQueue      = new Queue <Key>();
            var unknownTypeQueue = new Queue <Key>();

            using var se = source.GetEnumerator();
            bool exists;

            do
            {
                exists = se.MoveNext();
                if (exists)
                {
                    var key  = se.Current;
                    var type = key.HasExactType || modelType == null
            ? key.TypeReference.Type
            : modelType;
                    if (!key.HasExactType && !type.IsLeaf)
                    {
                        unknownTypeQueue.Enqueue(key);
                    }

                    resultQueue.Enqueue(key);
                    var defaultDescriptors = PrefetchHelper.GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, type);
                    container.JoinIfPossible(
                        await session.Handler.PrefetchAsync(key, type, defaultDescriptors, token).ConfigureAwait(false));
                }

                if (exists && taskCount == session.Handler.PrefetchTaskExecutionCount)
                {
                    continue;
                }

                if (!exists)
                {
                    container.JoinIfPossible(
                        await session.Handler.ExecutePrefetchTasksAsync(token).ConfigureAwait(false));
                }

                if (unknownTypeQueue.Count > 0)
                {
                    while (unknownTypeQueue.Count > 0)
                    {
                        var unknownKey         = unknownTypeQueue.Dequeue();
                        var unknownType        = session.EntityStateCache[unknownKey, false].Type;
                        var unknownDescriptors =
                            PrefetchHelper.GetCachedDescriptorsForFieldsLoadedByDefault(session.Domain, unknownType);
                        await session.Handler.PrefetchAsync(
                            unknownKey, unknownType, unknownDescriptors, token).ConfigureAwait(false);
                    }

                    await session.Handler.ExecutePrefetchTasksAsync(token).ConfigureAwait(false);
                }

                while (resultQueue.Count > 0)
                {
                    yield return((T)(IEntity)session.EntityStateCache[resultQueue.Dequeue(), true].Entity);
                }

                taskCount = session.Handler.PrefetchTaskExecutionCount;
            } while (exists);
        }