private void free0(long pos, long size)
        {
            long       quantNo    = (pos - baseAddr) >> quantumBits;
            long       objBitSize = (size + quantum - 1) >> quantumBits;
            int        pageId     = (int)(quantNo / BITMAP_PAGE_BITS);
            int        offs       = (int)(quantNo - (long)pageId * BITMAP_PAGE_BITS) >> 3;
            BitmapPage pg         = (BitmapPage)pages[pageId];
            int        bitOffs    = (int)quantNo & 7;

            if (objBitSize > 8 - bitOffs)
            {
                objBitSize      -= 8 - bitOffs;
                pg.data[offs++] &= (byte)((1 << bitOffs) - 1);
                while (objBitSize + offs * 8 > BITMAP_PAGE_BITS)
                {
                    memset(pg, offs, 0, BITMAP_PAGE_SIZE - offs);
                    pg          = (BitmapPage)pages[++pageId];
                    objBitSize -= (BITMAP_PAGE_SIZE - offs) * 8;
                    offs        = 0;
                }
                while ((objBitSize -= 8) > 0)
                {
                    pg.data[offs++] = (byte)0;
                }
                pg.data[offs] &= (byte)~((1 << ((int)objBitSize + 8)) - 1);
            }
            else
            {
                pg.data[offs] &= (byte)~(((1 << (int)objBitSize) - 1) << bitOffs);
            }
            pg.Modify();
        }
Beispiel #2
0
 public void Add( BitmapPage page, string fontname, int fontsize )
 {
     var key = new EntryKey() { Name = fontname, Size = fontsize };
     if ( !entries.ContainsKey(key) ) entries.Add( key, new Entry() { FontName = fontname, FontSize = fontsize } );
     var entry = entries[key];
     entry.BitmapPages.Add( page );
 }
        static void memset(BitmapPage pg, int offs, int pattern, int len)
        {
            byte[] arr = pg.data;
            byte   pat = (byte)pattern;

            while (--len >= 0)
            {
                arr[offs++] = pat;
            }
            pg.Modify();
        }
        public long Allocate(long size)
        {
            size = (size + quantum - 1) & ~(quantum - 1);
            long objBitSize = size >> quantumBits;
            long pos;
            long holeBitSize  = 0;
            int  firstPage    = currPage;
            int  lastPage     = pages.Count;
            int  offs         = currOffs;
            long lastHoleSize = 0;

            while (true)
            {
                for (int i = firstPage; i < lastPage; i++)
                {
                    BitmapPage pg = (BitmapPage)pages[i];
                    while (offs < BITMAP_PAGE_SIZE)
                    {
                        int mask = pg.data[offs] & 0xFF;
                        if (holeBitSize + StorageImpl.firstHoleSize[mask] >= objBitSize)
                        {
                            pos = baseAddr + ((((long)i * BITMAP_PAGE_SIZE + offs) * 8 - holeBitSize) << quantumBits);
                            long nextPos = wasReserved(pos, size);
                            if (nextPos != 0)
                            {
                                long quantNo = ((nextPos - baseAddr) >> quantumBits);
                                i           = (int)(quantNo / BITMAP_PAGE_BITS);
                                pg          = (BitmapPage)pages[i];
                                offs        = (int)(quantNo + 7 - (long)i * BITMAP_PAGE_BITS) >> 3;
                                holeBitSize = 0;
                                continue;
                            }
                            currPage       = i;
                            currOffs       = offs;
                            pg.data[offs] |= (byte)((1 << (int)(objBitSize - holeBitSize)) - 1);
                            pg.Modify();
                            if (holeBitSize != 0)
                            {
                                if (holeBitSize > offs * 8)
                                {
                                    memset(pg, 0, 0xFF, offs);
                                    holeBitSize -= offs * 8;
                                    pg           = (BitmapPage)pages[--i];
                                    offs         = BITMAP_PAGE_SIZE;
                                }
                                while (holeBitSize > BITMAP_PAGE_BITS)
                                {
                                    memset(pg, 0, 0xFF, BITMAP_PAGE_SIZE);
                                    holeBitSize -= BITMAP_PAGE_BITS;
                                    pg           = (BitmapPage)pages[--i];
                                }
                                while ((holeBitSize -= 8) > 0)
                                {
                                    pg.data[--offs] = (byte)0xFF;
                                }
                                pg.data[offs - 1] |= (byte)~((1 << -(int)holeBitSize) - 1);
                                pg.Modify();
                            }
                            return(pos);
                        }
                        else if (StorageImpl.maxHoleSize[mask] >= objBitSize)
                        {
                            int holeBitOffset = StorageImpl.maxHoleOffset[mask];
                            pos = baseAddr + ((((long)i * BITMAP_PAGE_SIZE + offs) * 8 + holeBitOffset) << quantumBits);
                            long nextPos = wasReserved(pos, size);
                            if (nextPos != 0)
                            {
                                long quantNo = ((nextPos - baseAddr) >> quantumBits);
                                i           = (int)(quantNo / BITMAP_PAGE_BITS);
                                pg          = (BitmapPage)pages[i];
                                offs        = (int)(quantNo + 7 - (long)i * BITMAP_PAGE_BITS) >> 3;
                                holeBitSize = 0;
                                continue;
                            }
                            currPage       = i;
                            currOffs       = offs;
                            pg.data[offs] |= (byte)(((1 << (int)objBitSize) - 1) << holeBitOffset);
                            pg.Modify();
                            return(pos);
                        }
                        offs += 1;
                        if (StorageImpl.lastHoleSize[mask] == 8)
                        {
                            holeBitSize += 8;
                        }
                        else
                        {
                            holeBitSize = StorageImpl.lastHoleSize[mask];
                        }
                    }
                    offs = 0;
                }
                if (firstPage == 0)
                {
                    firstPage = pages.Count;
                    int nPages = (int)((size + BITMAP_PAGE_BITS * quantum - 1) / (BITMAP_PAGE_BITS * quantum));
                    lastPage = firstPage + (nPages > extensionPages ? nPages : extensionPages);
                    if ((long)lastPage * BITMAP_PAGE_BITS * quantum > limit)
                    {
                        throw new StorageError(StorageError.ErrorCode.NOT_ENOUGH_SPACE);
                    }
                    pages.Length = lastPage;
                    for (int i = firstPage; i < lastPage; i++)
                    {
                        BitmapPage pg = new BitmapPage();
                        pg.data  = new byte[BITMAP_PAGE_SIZE];
                        pages[i] = pg;
                    }
                    holeBitSize = lastHoleSize;
                }
                else
                {
                    lastHoleSize = holeBitSize;
                    holeBitSize  = 0;
                    lastPage     = firstPage + 1;
                    firstPage    = 0;
                }
            }
        }