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