public override void Write(long pageAddr, byte[] buf) { long pageOffs = 0; if (pageAddr != 0) { Debug.Assert(buf.Length == Page.pageSize); Debug.Assert((pageAddr & (Page.pageSize - 1)) == 0); long pagePos = pageMap.get(pageAddr); bool firstUpdate = false; if (pagePos == 0) { long bp = (pageAddr >> (Page.pageSizeLog - 3)); byte[] posBuf = new byte[8]; indexFile.Read(bp, posBuf); pagePos = Bytes.unpack8(posBuf, 0); firstUpdate = true; } int pageSize = ((int)pagePos & (Page.pageSize - 1)) + 1; MemoryStream ms = new MemoryStream(); GZipStream stream = new GZipStream(ms, CompressionMode.Compress, true); stream.Write(buf, 0, buf.Length); #if WINRT_NET_FRAMEWORK stream.Dispose(); #else stream.Close(); #endif if (ms.Length < Page.pageSize) { buf = ms.ToArray(); } else { byte[] copy = new byte[buf.Length]; Array.Copy(buf, 0, copy, 0, buf.Length); } crypt(buf, buf.Length); int newPageBitSize = (buf.Length + ALLOCATION_QUANTUM - 1) >> ALLOCATION_QUANTUM_LOG; int oldPageBitSize = (pageSize + ALLOCATION_QUANTUM - 1) >> ALLOCATION_QUANTUM_LOG; if (firstUpdate || newPageBitSize != oldPageBitSize) { if (!firstUpdate) { Bitmap.free(bitmap, pagePos >> (Page.pageSizeLog + ALLOCATION_QUANTUM_LOG), oldPageBitSize); } pageOffs = allocate(newPageBitSize); } else { pageOffs = pagePos >> Page.pageSizeLog; } pageMap.put(pageAddr, (pageOffs << Page.pageSizeLog) | (buf.Length - 1), pagePos); } base.Write(pageOffs, buf); }
public override void Sync() { base.Sync(); if (pageMap.size() != 0) { byte[] buf = new byte[8]; foreach (PageMap.Entry e in pageMap) { Bytes.pack8(buf, 0, e.newPos); long bp = (e.addr >> (Page.pageSizeLog - 3)); indexFile.Write(bp, buf); if (e.oldPos != 0) { Bitmap.free(bitmap, e.oldPos >> (Page.pageSizeLog + ALLOCATION_QUANTUM_LOG), ((e.oldPos & (Page.pageSize - 1)) + ALLOCATION_QUANTUM) >> ALLOCATION_QUANTUM_LOG); } } indexFile.Sync(); pageMap.clear(); } }