Exemple #1
0
        private async Task UpdateNonInlinedPagesAsync(
            HiveType hive,
            IReadOnlyList <HiveType> replicaHives,
            string id,
            IndexInfo indexInfo,
            CatalogCommit registrationCommit,
            HiveMergeResult mergeResult)
        {
            var taskFactories = new ConcurrentBag <Func <Task> >();

            for (var pageIndex = 0; pageIndex < indexInfo.Items.Count; pageIndex++)
            {
                var pageInfo = indexInfo.Items[pageIndex];

                if (pageInfo.IsInlined)
                {
                    _logger.LogInformation(
                        "Moving page {PageNumber}/{PageCount} [{Lower}, {Upper}] from being inlined to having its own blob.",
                        pageIndex + 1,
                        indexInfo.Items.Count,
                        pageInfo.Lower.ToNormalizedString(),
                        pageInfo.Upper.ToNormalizedString());

                    pageInfo = await pageInfo.CloneToNonInlinedAsync();

                    indexInfo.RemoveAt(pageIndex);
                    indexInfo.Insert(pageIndex, pageInfo);
                }
                else if (!mergeResult.ModifiedPages.Contains(pageInfo))
                {
                    _logger.LogInformation(
                        "Skipping unmodified page {PageNumber}/{PageCount} [{Lower}, {Upper}].",
                        pageIndex + 1,
                        indexInfo.Items.Count,
                        pageInfo.Lower.ToNormalizedString(),
                        pageInfo.Upper.ToNormalizedString());

                    continue;
                }

                Guard.Assert(!pageInfo.IsInlined, "The page should not be inlined at this point.");

                var page = await pageInfo.GetPageAsync();

                _entityBuilder.UpdateNonInlinedPageItem(pageInfo.PageItem, hive, id, pageInfo.Count, pageInfo.Lower, pageInfo.Upper);
                _entityBuilder.UpdateCommit(pageInfo.PageItem, registrationCommit);
                _entityBuilder.UpdatePage(page, hive, id, pageInfo.Count, pageInfo.Lower, pageInfo.Upper);
                _entityBuilder.UpdateCommit(page, registrationCommit);

                var pageNumber = pageIndex + 1;
                taskFactories.Add(async() =>
                {
                    _logger.LogInformation(
                        "Updating page {PageNumber}/{PageCount} [{Lower}, {Upper}].",
                        pageNumber,
                        indexInfo.Items.Count,
                        pageInfo.Lower.ToNormalizedString(),
                        pageInfo.Upper.ToNormalizedString());
                    await _storage.WritePageAsync(hive, replicaHives, id, pageInfo.Lower, pageInfo.Upper, page);
                });
            }

            await ParallelAsync.Repeat(
                async() =>
            {
                await Task.Yield();
                while (taskFactories.TryTake(out var taskFactory))
                {
                    await taskFactory();
                }
            },
                _options.Value.MaxConcurrentOperationsPerHive);
        }