internal DatabaseCreationBuilder(string path, Guid versionCheck) { this.path = path; this.versionCheck = versionCheck; buffer = new byte[8192]; headers = new List <ArrayHeader>(); stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read); db = new Database(() => Database.Open(FileShare.ReadWrite | FileShare.Delete, path), headers); try { stream.Write(BitConverter.GetBytes(0L)); stream.Write(versionCheck.ToByteArray()); } catch { stream.Dispose(); db.Dispose(); } }
public void Dispose() { db.Dispose(); }
public override DatabaseBuilder AddIndirectArray <T, TKey>( ISerializer <T> serializer, Func <Database, IEnumerable <T> > elements, Func <T, TKey> selector, IComparer <TKey>?comparer) { try { var headerPosition = stream.Position; // write a dummy header var dummyHeaderBytes = new ArrayHeader(serializer).AsBytes(); stream.Write(dummyHeaderBytes); var pointersArrayOffsetPosition = stream.Position; stream.Write(BitConverter.GetBytes(0L)); var dataStartPosition = stream.Position; long elementCount = 0; // TODO: less lazy way var offsetList = new List <long>(); var elementsEnumerable = elements(db); if (comparer != null) { elementsEnumerable = elementsEnumerable.OrderBy(selector, comparer); } foreach (var element in elementsEnumerable) { int actualLength; while (!serializer.TrySerialize(element, buffer.AsSpan(), out actualLength)) { Utility.Reallocate(ref buffer); } offsetList.Add(stream.Position - dataStartPosition); stream.Write(BitConverter.GetBytes(actualLength)); stream.Write(buffer, 0, actualLength); elementCount++; } var pointerArrayPosition = stream.Position; stream.Position += elementCount * sizeof(long); var pastEndPosition = stream.Position; stream.Seek(headerPosition, SeekOrigin.Begin); var arrayHeader = new ArrayHeader(serializer) { OverallLength = pastEndPosition - pointersArrayOffsetPosition, RecordCount = elementCount, StartsAt = pointersArrayOffsetPosition, EndsAt = pastEndPosition, Type = 2 }; stream.Write(arrayHeader.AsBytes()); stream.Write(BitConverter.GetBytes(pointerArrayPosition - pointersArrayOffsetPosition)); stream.Seek(pointerArrayPosition, SeekOrigin.Begin); foreach (var off in offsetList) { stream.Write(BitConverter.GetBytes(off)); } stream.Seek(pastEndPosition, SeekOrigin.Begin); headers.Add(arrayHeader); } catch { stream.Dispose(); db.Dispose(); throw; } return(this); }