public async Task OpenAsync() { try { await _blob.FetchAttributesAsync(); _commitPosition = Get_Committed_Position(); } catch (StorageException ex) { if (ex.RequestInformation.HttpStatusCode != 404) throw; _commitPosition = Position.Start; } byte[] lastPage = new byte[PageSize]; if (_commitPosition.ToLinearAddress() != 0) { using (var stream = _blob.OpenRead()) { stream.Seek(_commitPosition.Page * PageSize, SeekOrigin.Begin); await stream.ReadAsync(lastPage, 0, PageSize); } } _lastPage = new Page(_commitPosition, lastPage); }
async Task Commit_new_length_if_it_grew(long newLength, Page lastPage) { if (_commitPosition.ToLinearAddress() < newLength) { await Commit_Position(newLength); _lastPage = lastPage; } }
Page Retrieve_Page_At(int position) { if (position == _commitPosition.ToLinearAddress()) return _lastPage; else { var page = new Page(position); page.FillFromBlob(_blob); return page; } }
async Task<PreparedPages> PreparePages(int position, Stream stream) { int count = (int)stream.Length; int copied = 0; int currentPosition = position; int firstPageNumber = position / PageSize; int lastPageNumber = ((position + count) / PageSize); Page firstPage = Retrieve_Page_At(position); Page lastPage = new Page(position + count); Task lastFilling = null; if (firstPageNumber == lastPageNumber) lastPage = firstPage; else if (lastPage.GetBaseAddress() < _commitPosition.ToLinearAddress()) lastFilling = lastPage.FillFromBlobAsync(_blob); var bufferedPages = new StreamJoiner(); if (firstPage.Is_empty_and_can_contain_all_data___or___Is_not_empty(count)) { copied = firstPage.Append(stream); bufferedPages.Append(firstPage.ToStream()); currentPosition = position + copied; } if (copied < count) { int rem; int fullPages = Math.DivRem(count - copied, PageSize, out rem); if (fullPages > 0) { bufferedPages.Append(stream, copied, count - copied - rem); copied += fullPages * PageSize; currentPosition = position + copied; stream.Seek(copied, SeekOrigin.Begin); } if (copied < count) { Debug.Assert(rem > 0); if (lastFilling != null) await lastFilling; else lastPage = new Page(position + copied); lastPage.Fill_From(stream); bufferedPages.Append(lastPage.ToStream()); copied += rem; currentPosition = position + copied; } } Debug.Assert(position + count == currentPosition); Debug.Assert(copied == count); return new PreparedPages { Position = position, CurrentPosition = currentPosition, Pages = bufferedPages, LastPage = lastPage }; }