public void InMemDb_Core_ChunkUpload_NewFile()
        {
            Test(async() =>
            {
                var root = CreateTestRoot();
                var file = new File(root)
                {
                    Name = "File1.txt"
                };
                file.Binary.ContentType = "application/octet-stream";
                //file.Binary.FileName = "File1.txt";
                file.Save();

                var chunks = new[]
                {
                    new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                    new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
                    new byte[] { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
                    new byte[] { 4, 4 }
                };
                var chunkSize = chunks[0].Length;

                // START CHUNK
                var versionId      = file.VersionId;
                var propertyTypeId = PropertyType.GetByName("Binary").Id;
                var fullSize       = 50L;
                var token          = await BlobStorage.StartChunkAsync(versionId, propertyTypeId, fullSize, CancellationToken.None)
                                     .ConfigureAwait(false);

                // WRITE CHUNKS
                for (int i = 0; i < chunks.Length; i++)
                {
                    var offset = i * chunkSize;
                    var chunk  = chunks[i];
                    await BlobStorage.WriteChunkAsync(versionId, token, chunk, offset, fullSize,
                                                      CancellationToken.None).ConfigureAwait(false);
                }

                // COMMIT CHUNK
                await BlobStorage.CommitChunkAsync(versionId, propertyTypeId, token, fullSize, null, CancellationToken.None)
                .ConfigureAwait(false);

                // ASSERT
                Cache.Reset();
                file       = Node.Load <File>(file.Id);
                var length = Convert.ToInt32(file.Binary.Size);
                var buffer = new byte[length];
                using (var stream = file.Binary.GetStream())
                    stream.Read(buffer, 0, length);
                Assert.AreEqual(
                    "11111111111111112222222222222222333333333333333344",
                    new string(buffer.Select(b => (char)(b + '0')).ToArray()));
            }).GetAwaiter().GetResult();
        }
예제 #2
0
        /// <summary>
        /// This method deletes orphaned rows from the database physically.
        /// </summary>
        private static void CleanupFilesDeleteRows()
        {
            var deleteCount = 0;

            try
            {
                SnTrace.Database.Write(TRACE_PREFIX + "Cleanup files: deleting rows...");

                // keep deleting orphaned binary rows while there are any
                while (BlobStorage.CleanupFiles())
                {
                    deleteCount++;
                }

                if (deleteCount > 0)
                {
                    SnLog.WriteInformation(string.Format("{0} orphaned rows were deleted from the binary table during cleanup.", deleteCount), EventId.RepositoryRuntime);
                }
            }
            catch (Exception ex)
            {
                SnLog.WriteWarning("Error in file cleanup background process. " + ex, EventId.RepositoryRuntime);
            }
        }
예제 #3
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (offset + count > buffer.Length)
            {
                throw new ArgumentException("Offset + count must not be greater than the buffer length.");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), "The offset must be greater than zero.");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count), "The count must be greater than zero.");
            }

            // Calculate the maximum count of the bytes that can be read.
            // Return immediately if nothing to read.
            var maximumReadableByteCount = Length - Position;

            if (maximumReadableByteCount < 1)
            {
                return(0);
            }

            var realCount = (int)Math.Min(count, maximumReadableByteCount);

            if (CanInnerBufferHandleReadRequest(realCount))
            {
                Array.Copy(_innerBuffer, (int)Position - _innerBufferFirstPostion, buffer, offset, realCount);
            }
            else
            {
                _innerBuffer = null;

                var bytesRead = 0;
                var bytesStoredInInnerBuffer = 0;

                while (bytesRead < realCount)
                {
                    // bytes to load from the db
                    var bytesToReadInThisIteration = (int)Math.Min(this.Length - Position - bytesRead,
                                                                   BlobStorageOptions.BinaryChunkSize);

                    // bytes that we will copy to the buffer of the caller
                    var bytesToStoreInThisIteration = Math.Min(bytesToReadInThisIteration, realCount - bytesRead);

                    // stores the current chunk
                    var tempBuffer = BlobStorage.LoadBinaryFragmentAsync(this.FileId, Position + bytesRead,
                                                                         bytesToReadInThisIteration, CancellationToken.None).GetAwaiter().GetResult();

                    // first iteration: create inner buffer for caching a part of the stream in memory
                    if (_innerBuffer == null)
                    {
                        _innerBuffer             = new byte[GetInnerBufferSize(realCount)];
                        _innerBufferFirstPostion = Position;
                    }

                    // store a fragment of the data in the inner buffer if possible
                    if (bytesStoredInInnerBuffer < _innerBuffer.Length)
                    {
                        var bytesToStoreInInnerBuffer = Math.Min(bytesToReadInThisIteration, _innerBuffer.Length - bytesStoredInInnerBuffer);

                        Array.Copy(tempBuffer, 0, _innerBuffer, bytesStoredInInnerBuffer, bytesToStoreInInnerBuffer);
                        bytesStoredInInnerBuffer += bytesToStoreInInnerBuffer;
                    }

                    // copy the chunk from the temp buffer to the buffer of the caller
                    Array.Copy(tempBuffer, 0, buffer, bytesRead, bytesToStoreInThisIteration);
                    bytesRead += bytesToReadInThisIteration;
                }
            }

            Position += realCount;

            return(realCount);
        }