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; } }
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); }
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); }
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); } }
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); }
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); }
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); }
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); }
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); }