public Heap(Stream stream, bool useCompression = false, AllocationStrategy strategy = AllocationStrategy.FromTheCurrentBlock) { stream.Seek(0, SeekOrigin.Begin); //support Seek? Stream = stream; space = new Space(); used = new Dictionary <long, Pointer>(); reserved = new Dictionary <long, Pointer>(); if (stream.Length < AtomicHeader.SIZE) //create new { header = new AtomicHeader(); header.UseCompression = useCompression; space.Add(new Ptr(AtomicHeader.SIZE, long.MaxValue - AtomicHeader.SIZE)); } else //open exist (ignore the useCompression flag) { header = AtomicHeader.Deserialize(Stream); stream.Seek(header.SystemData.Position, SeekOrigin.Begin); Deserialize(new BinaryReader(stream)); //manual alloc header.SystemData var ptr = space.Alloc(header.SystemData.Size); if (ptr.Position != header.SystemData.Position) { throw new Exception("Logical error."); } } Strategy = strategy; currentVersion++; }
public Heap(Stream stream, bool useCompression = false, AllocationStrategy strategy = AllocationStrategy.FromTheCurrentBlock) { stream.Seek(0, SeekOrigin.Begin); //support Seek? Stream = stream; space = new Space(); used = new Dictionary<long, Pointer>(); reserved = new Dictionary<long, Pointer>(); if (stream.Length < AtomicHeader.SIZE) //create new { header = new AtomicHeader(); header.UseCompression = useCompression; space.Add(new Ptr(AtomicHeader.SIZE, long.MaxValue - AtomicHeader.SIZE)); } else //open exist (ignore the useCompression flag) { header = AtomicHeader.Deserialize(Stream); stream.Seek(header.SystemData.Position, SeekOrigin.Begin); Deserialize(new BinaryReader(stream)); //manual alloc header.SystemData var ptr = space.Alloc(header.SystemData.Size); if (ptr.Position != header.SystemData.Position) throw new Exception("Logical error."); } Strategy = strategy; currentVersion++; }
/// <summary> /// Before writting, handle must be obtained (registered). /// New block will be written always with version = CurrentVersion /// If new block is written to handle and the last block of this handle have same version with the new one, occupied space by the last block will be freed. /// </summary> public void Write(long handle, byte[] buffer, int index, int count) { int originalCount = count; if (UseCompression) { using (MemoryStream stream = new MemoryStream()) { using (DeflateStream compress = new DeflateStream(stream, CompressionMode.Compress, true)) compress.Write(buffer, index, count); buffer = stream.GetBuffer(); index = 0; count = (int)stream.Length; } } lock (SyncRoot) { if (handle >= maxHandle) { throw new ArgumentException("Invalid handle."); } Pointer pointer; if (used.TryGetValue(handle, out pointer)) { if (pointer.Version == currentVersion) { space.Free(pointer.Ptr); } else { pointer.IsReserved = true; reserved.Add(handle, pointer); } } long size = UseCompression ? sizeof(int) + count : count; Ptr ptr = space.Alloc(size); used[handle] = pointer = new Pointer(currentVersion, ptr); InternalWrite(ptr.Position, originalCount, buffer, index, count); } }