コード例 #1
0
        private protected virtual async ValueTask ReadRefs()
        {
            string fileName = Path.Combine(GitDir, PackedRefsFile);

            if (!File.Exists(fileName))
            {
                return;
            }

            try
            {
                using var sr = FileBucket.OpenRead(fileName, false);

                var idLength = GitId.HashLength(Repository.InternalConfig.IdType) * 2;

                GitRefPeel?last = null;
                while (true)
                {
                    var(bb, eol) = await sr.ReadUntilEolFullAsync(BucketEol.LF).ConfigureAwait(false);

                    if (bb.IsEof)
                    {
                        return;
                    }

                    bb = bb.Trim(eol);
                    ParseLineToPeel(bb, ref last, idLength);
                }
            }
            catch (FileNotFoundException)
            {
                return;
            }
        }
コード例 #2
0
        public override async ValueTask <TGitObject?> GetByIdAsync <TGitObject>(GitId id)
            where TGitObject : class
        {
            var name = id.ToString();

            string path = Path.Combine(_objectsDir, name.Substring(0, 2), name.Substring(2));

            if (!File.Exists(path))
            {
                return(null);
            }

            var fileReader = FileBucket.OpenRead(path, false);

            try
            {
                var rdr = new GitObjectFileBucket(fileReader);

                GitObject ob = await GitObject.FromBucketAsync(Repository, rdr, id).ConfigureAwait(false);

                if (ob is TGitObject tg)
                {
                    return(tg);
                }

                rdr.Dispose();

                return(null);
            }
            catch
            {
                fileReader.Dispose();
                throw;
            }
        }
コード例 #3
0
        public async Task FileBucketCleanup()
        {
            string p = Path.Combine(TestContext.TestResultsDirectory, Guid.NewGuid().ToString());

            File.WriteAllText(p, "blub");

            using (FileBucket fb = new FileBucket(p))
            {
                Assert.AreEqual(4, await fb.ReadAtAsync(0, new byte[25]));
            }

            File.Delete(p);


            File.WriteAllText(p, "blub2");

            using (FileBucket fb = new FileBucket(p))
            {
                Assert.AreEqual(5, await fb.ReadAtAsync(0, new byte[25]));

                using (var fb2 = fb.Duplicate(true))
                {
                    Assert.AreEqual(5, await fb.ReadAtAsync(0, new byte[25]));
                }
            }

            File.Delete(p);
        }
コード例 #4
0
        public PageFileRepository(IPagesDbContext dbContext)
        {
            if (dbContext == null)
            {
                throw new ArgumentNullException(nameof(dbContext));
            }

            files = new FileBucket(dbContext.Database, new GridFSBucketOptions {
                BucketName = "BrandUpPages", DisableMD5 = false
            });
        }
コード例 #5
0
        static async IAsyncEnumerable <GitReferenceChange>?GetChangesFromRefLogFile(string fileName)
        {
            var fb = FileBucket.OpenRead(fileName);

            using var gr = new GitReferenceLogBucket(fb);

            while (await gr.ReadGitReferenceLogRecordAsync().ConfigureAwait(false) is GitReferenceLogRecord lr)
            {
                yield return(new GitReferenceChange(lr));
            }
        }
コード例 #6
0
ファイル: PackObjectRepository.cs プロジェクト: AmpScm/AmpScm
        async ValueTask InitAsync()
        {
            if (_ver == 0)
            {
                _fIdx ??= FileBucket.OpenRead(Path.ChangeExtension(PackFile, ".idx"));

                byte[] header       = new byte[8];
                long   fanOutOffset = -1;
                if (header.Length == await _fIdx.ReadAtAsync(0, header).ConfigureAwait(false))
                {
                    var index = new byte[] { 255, (byte)'t', (byte)'O', (byte)'c', 0, 0, 0, 2 };

                    if (header.SequenceEqual(index))
                    {
                        // We have a v2 header.
                        fanOutOffset = 8;
                        _ver         = 2;
                    }
                    else if (header.Take(4).SequenceEqual(index.Take(4)))
                    {
                        // We have an unsupported future header
                        _ver = -1;
                        _fIdx.Dispose();
                        _fIdx = null;
                        return;
                    }
                    else
                    {
                        // We have a v0/v1 header, which is no header
                        fanOutOffset = 0;
                        _ver         = 1;
                    }
                }

                if (_fanOut == null && _ver > 0)
                {
                    byte[] fanOut = new byte[4 * 256];

                    if (fanOut.Length == await _fIdx.ReadAtAsync(fanOutOffset, fanOut).ConfigureAwait(false))
                    {
                        _fanOut = new uint[256];
                        for (int i = 0; i < 256; i++)
                        {
                            _fanOut[i] = NetBitConverter.ToUInt32(fanOut, i * 4);
                        }
                    }

                    _hasBitmap = File.Exists(Path.ChangeExtension(PackFile, ".bitmap"));
                }
            }
        }
コード例 #7
0
        public async Task CheckIndexAsync()
        {
            using var repo = GitRepository.Open(GitTestEnvironment.GetRepository(GitTestDir.Packed));

            var index = FileBucket.OpenRead(Path.Combine(repo.WorkTreeDirectory, "index"));

            using var dc = new GitDirectoryBucket(index, new() { IdType = GitIdType.Sha1 });

            await dc.ReadHeaderAsync();

            TestContext.WriteLine($"Version: {dc.IndexVersion}");

            while (await dc.ReadEntryAsync() is GitDirectoryEntry entry)
            {
                TestContext.WriteLine($"{entry.Name} - {entry}");
            }
        }
コード例 #8
0
ファイル: GitBitmapTests.cs プロジェクト: AmpScm/AmpScm
        public async Task Read4BitmapsXor()
        {
            string bmpFile = FindResource("*.bitmap") ?? throw new InvalidOperationException("Bitmap not found");

            var fb = FileBucket.OpenRead(bmpFile);


            var headers = await fb.ReadFullAsync(32); // Skip headers

            uint count = NetBitConverter.ToUInt32(headers, 8);

            Assert.AreEqual(106u, count);

            List <GitEwahBitmapBucket> buckets = new List <GitEwahBitmapBucket>();

            for (int i = 0; i < 4; i++)
            {
                buckets.Add(new GitEwahBitmapBucket(fb.Duplicate(false)));

                await fb.ReadNetworkUInt32Async();           // Bitlength

                uint u2 = await fb.ReadNetworkUInt32Async(); // Compressed length

                for (uint n = 0; n < u2; n++)
                {
                    await fb.ReadNetworkUInt64Async();
                }
                await fb.ReadNetworkUInt32Async(); // Last RLW start
            }

            var allXor = new BitwiseXorBucket(new BitwiseXorBucket(buckets[0], buckets[1]), new BitwiseXorBucket(buckets[2], buckets[3]));

            int maxBits = buckets.Max(x => x.ReadBitLengthAsync().AsTask().Result);

            Assert.AreEqual(2369, maxBits);
            var bb = await allXor.ReadFullAsync((maxBits + 7) / 8);

            for (int i = 0; i < bb.Length - 1; i++)
            {
                Assert.AreEqual((byte)0xFF, bb[i]);
            }
        }
コード例 #9
0
        protected virtual async ValueTask InitAsync()
        {
            if (FanOut is not null)
            {
                return;
            }

            await Task.Yield();

            ChunkReader ??= FileBucket.OpenRead(_fileName);

            var(idType, chunkCount, chunkTableOffset) = await ReadHeaderAsync().ConfigureAwait(false);

            if (chunkCount == 0)
            {
                ChunkReader.Dispose();
                ChunkReader = null;
                return;
            }
            IdType = idType;


            await ReadChunks(chunkTableOffset, chunkCount).ConfigureAwait(false);
        }
コード例 #10
0
ファイル: GitObjectWriter.cs プロジェクト: AmpScm/AmpScm
        private protected async ValueTask <GitId> WriteBucketAsObject(Bucket bucket, GitRepository repository, CancellationToken cancellationToken = default)
        {
            string tmpFile     = Guid.NewGuid().ToString() + ".tmp";
            var    di          = Directory.CreateDirectory(Path.Combine(repository.GitDirectory, "objects", "info"));
            var    tmpFilePath = Path.Combine(di.FullName, tmpFile);
            string?tmpFile2    = null;
            GitId? id          = null;
            string newName;

            using (var f = GitInstallFile.Create(tmpFilePath))
            {
                try
                {
                    long?r = await bucket.ReadRemainingBytesAsync().ConfigureAwait(false);

                    if (!r.HasValue)
                    {
                        string innerTmp = Path.Combine(Path.GetTempPath(), tmpFile) + ".pre";

                        using (var tmp = File.Create(innerTmp))
                        {
                            tmpFile2 = innerTmp;
                            await bucket.WriteToAsync(tmp, cancellationToken).ConfigureAwait(false);

                            r = tmp.Length;
                        }
                        bucket = FileBucket.OpenRead(innerTmp);
                    }

                    await Type.CreateHeader(r.Value !).Append(bucket)
                    .GitHash(repository.InternalConfig.IdType, cs => id = cs)
                    .Compress(BucketCompressionAlgorithm.ZLib, BucketCompressionLevel.Maximum)
                    .WriteToAsync(f, cancellationToken).ConfigureAwait(!false);

                    string idName = id !.ToString();

                    var dir = Path.Combine(repository.GitDirectory, "objects", idName.Substring(0, 2));
                    Directory.CreateDirectory(dir);

                    newName = Path.Combine(dir, idName.Substring(2));
                }
                catch when(!GitInstallFile.TrySetDeleteOnClose(f, true))
                {
                    f.Close();

                    try
                    {
                        File.Delete(tmpFilePath);
                    }
                    catch (UnauthorizedAccessException)
                    { }
                    catch (IOException)
                    { }

                    throw;
                }
                finally
                {
                    try
                    {
                        if (tmpFile2 is not null)
                        {
                            File.Delete(tmpFile2);
                        }
                    }
                    catch (UnauthorizedAccessException)
                    { }
                    catch (IOException)
                    { }
                }

                if (!File.Exists(newName))
                {
                    if (GitInstallFile.TryMoveFile(f, newName))
                    {
                        return(id);
                    }
                }
                else
                {
                    if (GitInstallFile.TrySetDeleteOnClose(f, true))
                    {
                        return(id);
                    }
                }
            }

            if (File.Exists(newName))
            {
                File.Delete(tmpFilePath);
            }
            else
            {
                File.Move(tmpFilePath, newName);
            }
            return(id);
        }
コード例 #11
0
ファイル: GitBitmapTests.cs プロジェクト: AmpScm/AmpScm
        public async Task ReadBitmap()
        {
            string bmpFile = FindResource("*.bitmap") ?? throw new InvalidOperationException("Bitmap not found");

            var fb = FileBucket.OpenRead(bmpFile);


            var headers = await fb.ReadFullAsync(32); // Skip headers

            uint count = NetBitConverter.ToUInt32(headers, 8);

            Assert.AreEqual(106u, count);

            //BitArray
            var bitLengths = new int[4];

            {
                var c = fb.Duplicate(false);
                Assert.AreEqual(32, c.Position);

                for (int i = 0; i < 4; i++)
                {
                    bitLengths[i] = (int)await c.ReadNetworkUInt32Async();

                    uint u2 = await c.ReadNetworkUInt32Async();

                    List <ulong> w = new List <ulong>();

                    for (uint n = 0; n < u2; n++)
                    {
                        w.Add(await c.ReadNetworkUInt64Async());
                    }
                    await c.ReadNetworkUInt32Async();

                    TestContext.WriteLine($"EWAH  {i}: {bitLengths[i]}\t{u2}");
                    foreach (var v in w)
                    {
                        TestContext.Write($"{v:X16} ");
                    }
                    TestContext.WriteLine();
                }

                //GC.KeepAlive(u1 + u2 + u3);
            }

            for (int i = 0; i < 4; i++)
            {
                using var ewah = new GitEwahBitmapBucket(fb.NoClose(true));

                Assert.AreEqual(0L, ewah.Position);

                int expectedBytes = (int)(8 * ((bitLengths[i] + 63) / 64));

                long?p = await ewah.ReadRemainingBytesAsync();

                int peekLen = ewah.Peek().Length;
                Assert.IsTrue(peekLen > 0, "Can peek something");
                Assert.IsTrue(peekLen <= expectedBytes, "No overshoot");

                Assert.AreEqual(expectedBytes, (int)p, "ReadRemaining returned expected value");

                var bb = await ewah.ReadFullAsync(65536);

                Assert.AreEqual(expectedBytes, bb.Length, $"Read {bb.Length}, expected {bitLengths[i]} bits, what would be {(bitLengths[i] + 7) / 8} bytes, or {expectedBytes} bytes when reading longs");

                StringBuilder sb = new StringBuilder();
                for (int ii = 0; ii < bb.Length; ii++)
                {
                    sb.Append(bb[ii].ToString("x2"));
                }
                TestContext.WriteLine();
                int removeAfter = 2 * ((bitLengths[i] + 7) / 8);

                if (removeAfter < sb.Length)
                {
                    sb.Remove(removeAfter, sb.Length - removeAfter);
                }
                TestContext.WriteLine(sb.ToString());
            }
        }