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();
     }
 }