private async Task <Page> ReadPageAsync(int pageNum, ushort pageSize, CancellationToken cancellationToken) { // Sanity checks if (stream == null) { // TODO - create custom exception throw new Exception("Block store is not open!"); } // Seek to the proper spot SeekToPage(pageNum); // Read the bytes for the page var bytes = new byte[pageSize]; await stream.ReadAsync(bytes, 0, pageSize); // Peek at the page type and build the proper page type. // TODO - a big switch statement is ugly...find a better way. var pageType = BitConverter.ToUInt16(bytes, 1); Page page = null; switch (pageType) { case ZeroPage.PageId: page = new ZeroPage(); break; case HeaderPage.PageId: page = new HeaderPage(); break; default: throw new Exception($"Unhandled page type: {pageType}."); } // Have the page deserialize itself page.Deserialize(bytes); // And return whatever we've got. return(page); }
/// <summary> /// Create a new file. /// </summary> /// <param name="path">The path of the file.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A task that can be awaited.</returns> public async Task CreateAsync(string path, CancellationToken cancellationToken) { // Create the stream, read/write, no sharing. stream = new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None); // Set up // TODO - accept a config lambda to get page size and whatnot PageSize = 2 * MinPageSize; // TODO - bump default to 4096 or 8192 // Initialize and write the zero-page, which always uses the minimum page size. var zeroPage = new ZeroPage { PageSize = PageSize }; await WritePageAsync(0, zeroPage, MinPageSize, cancellationToken); // Write the two header pages. var header1 = new HeaderPage(); var header2 = new HeaderPage(); await WritePageAsync(1, header1, cancellationToken); await WritePageAsync(2, header2, cancellationToken); }