Example #1
0
        public async Task FlushMeta()
        {
            await metaSem.WaitAsync();

            try
            {
                var cmds        = db.CommandsInTransientCache();
                var groupedCmds = cmds.OrderBy(c => c.Index).GroupBy(c => c.Path);
                foreach (var group in groupedCmds)
                {
                    var g    = group.ToList();
                    var path = group.Key;
                    var seg  = new Formats.MetaSegment {
                        Commands = g.Select(e => e.ToProtoObject()).ToList()
                    };
                    var protoSegs = seg.ToListOfByteArrays();

                    var isFile = seg.Commands[0].ToDBObject().MetaType == DB.SQLMap.CommandMetaType.File;
                    var sum    = g[0].Index;

                    var nextIndex = 0;
                    for (; ; nextIndex++)
                    {
                        var indexId = isFile
                                                        ? generator.GenerateMetaFileID((uint)nextIndex, path)
                                                        : generator.GenerateMetaFolderID((uint)nextIndex, path);
                        var exists = null != db.FindMatchingSegmentInAssurancesByIndexId(indexId);
                        if (!exists)
                        {
                            break;
                        }
                    }

                    foreach (var psi in protoSegs.Select((ps, i) => new { ps, i }))
                    {
                        sum += Formats.MetaSegment.FromByteArray(psi.ps).Commands.Count;

                        var idx     = nextIndex + psi.i;
                        var indexId = isFile
                                                        ? generator.GenerateMetaFileID((uint)idx, path)
                                                        : generator.GenerateMetaFolderID((uint)idx, path);

                        await uploadChunk(psi.ps, psi.ps.SHA256(), indexId, _inAssuranceAdditionTransaction : () =>
                        {
                            db.CommandsFlushedForPath(path, indexSmallerThan: sum, _isAlreadyInTransaction: true);
                        });

                        // TODO: cache uploaded chunk
                    }
                }
            }
            finally
            {
                metaSem.Release();
            }
        }