⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storageimpl.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 5 页
字号:
                                    currRBitmapPage = i;
                                    currRBitmapOffs = offs;
                                    extend(pos + size);
                                    if (oid != 0) 
                                    { 
                                        long prev = getPos(oid);
                                        uint marker = (uint)prev & dbFlagsMask;
                                        pool.copy(pos, prev - marker, size);
                                        setPos(oid, pos | marker | dbModifiedFlag);
                                    }
                                    pool.unfix(pg);
                                    pg = putBitmapPage(i);
                                    pg.data[offs] |= (byte)((1 << (objBitSize - holeBitSize)) - 1); 
                                    if (holeBitSize != 0) 
                                    { 
                                        if (holeBitSize > offs*8) 
                                        { 
                                            memset(pg, 0, 0xFF, offs);
                                            holeBitSize -= offs*8;
                                            pool.unfix(pg);
                                            pg = putBitmapPage(--i);
                                            offs = Page.pageSize;
                                        }
                                        while (holeBitSize > pageBits) 
                                        { 
                                            memset(pg, 0, 0xFF, Page.pageSize);
                                            holeBitSize -= pageBits;
                                            bitmapPageAvailableSpace[i] = 0;
                                            pool.unfix(pg);
                                            pg = putBitmapPage(--i);
                                        }
                                        while ((holeBitSize -= 8) > 0) 
                                        { 
                                            pg.data[--offs] = (byte)0xFF; 
                                        }
                                        pg.data[offs-1] |= (byte)~((1 << -holeBitSize) - 1);
                                    }
                                    pool.unfix(pg);
                                    commitLocation();
                                    return pos;
                                } 
                                else if (maxHoleSize[mask] >= objBitSize) 
                                { 
                                    int holeBitOffset = maxHoleOffset[mask];
                                    pos = (((long)i*Page.pageSize + offs)*8 + holeBitOffset) << dbAllocationQuantumBits;
                                    if (wasReserved(pos, size)) 
                                    { 
                                        startOffs = offs += 1;
                                        holeBitSize = 0;
                                        continue;
                                    }       
                                    reserveLocation(pos, size);
                                    currRBitmapPage = i;
                                    currRBitmapOffs = offs;
                                    extend(pos + size);
                                    if (oid != 0) 
                                    { 
                                        long prev = getPos(oid);
                                        uint marker = (uint)prev & dbFlagsMask;
                                        pool.copy(pos, prev - marker, size);
                                        setPos(oid, pos | marker | dbModifiedFlag);
                                    }
                                    pool.unfix(pg);
                                    pg = putBitmapPage(i);
                                    pg.data[offs] |= (byte)(((1<<objBitSize) - 1) << holeBitOffset);
                                    pool.unfix(pg);
                                    commitLocation();
                                    return pos;
                                }
                                offs += 1;
                                if (lastHoleSize[mask] == 8) 
                                { 
                                    holeBitSize += 8;
                                } 
                                else 
                                { 
                                    holeBitSize = lastHoleSize[mask];
                                }
                            }
                            if (startOffs == 0 && holeBitSize == 0
                                && spaceNeeded < bitmapPageAvailableSpace[i]) 
                            {
                                bitmapPageAvailableSpace[i] = spaceNeeded;
                            }
                            offs = 0;
                            pool.unfix(pg);
                        }
                    }
                    if (firstPage == 0) 
                    { 
                        if (freeBitmapPage > i) 
                        { 
                            i = freeBitmapPage;
                            holeBitSize = holeBeforeFreePage;
                        }
                        objBitSize -= holeBitSize;
                        // number of bits reserved for the object and aligned on page boundary
                        int skip = (objBitSize + Page.pageSize/dbAllocationQuantum - 1) 
                            & ~(Page.pageSize/dbAllocationQuantum - 1);
                        // page aligned position after allocated object
                        pos = ((long)i << dbBitmapSegmentBits) + ((long)skip << dbAllocationQuantumBits);

                        long extension = (size > extensionQuantum) ? size : extensionQuantum;
                        int oldIndexSize = 0;
                        long oldIndex = 0;
                        int morePages = (int)((extension + Page.pageSize*(dbAllocationQuantum*8-1) - 1)
                            / (Page.pageSize*(dbAllocationQuantum*8-1)));
                        if (i + morePages > dbLargeBitmapPages) 
                        { 
                            throw new StorageError(StorageError.ErrorCode.NOT_ENOUGH_SPACE);
                        }
                        if (i <= dbBitmapPages && i + morePages > dbBitmapPages) 
                        {   
                            // We are out of space mapped by memory default allocation bitmap
                            oldIndexSize = header.root[curr].indexSize;
                            if (oldIndexSize <= currIndexSize + dbLargeBitmapPages - dbBitmapPages) 
                            {
                                int newIndexSize = oldIndexSize;
                                oldIndex = header.root[curr].index;
                                do 
                                { 
                                    newIndexSize <<= 1;                    
                                    if (newIndexSize < 0) 
                                    { 
                                        newIndexSize = int.MaxValue & ~(dbHandlesPerPage-1);
                                        if (newIndexSize < currIndexSize + dbLargeBitmapPages - dbBitmapPages) 
                                        {
                                            throw new StorageError(StorageError.ErrorCode.NOT_ENOUGH_SPACE);
                                        }
                                        break;
                                    }
                                } while (newIndexSize <= currIndexSize + dbLargeBitmapPages - dbBitmapPages);

                                if (size + newIndexSize*8L > extensionQuantum) 
                                { 
                                    extension = size + newIndexSize*8L;
                                    morePages = (int)((extension + Page.pageSize*(dbAllocationQuantum*8-1) - 1)
                                        / (Page.pageSize*(dbAllocationQuantum*8-1)));
                                }
                                extend(pos + (long)morePages*Page.pageSize + newIndexSize*8L);
                                long newIndex = pos + (long)morePages*Page.pageSize;                        
                                fillBitmap(pos + (skip>>3) + (long)morePages * (Page.pageSize/dbAllocationQuantum/8),
                                    newIndexSize >> dbAllocationQuantumBits);
                                pool.copy(newIndex, oldIndex, oldIndexSize*8L);
                                header.root[curr].index = newIndex;
                                header.root[curr].indexSize = newIndexSize;
                            }
                            int[] newBitmapPageAvailableSpace = new int[dbLargeBitmapPages];
                            Array.Copy(bitmapPageAvailableSpace, 0, newBitmapPageAvailableSpace, 0, dbBitmapPages);
                            for (j = dbBitmapPages; j < dbLargeBitmapPages; j++) 
                            { 
                                newBitmapPageAvailableSpace[j] = int.MaxValue;
                            }
                            bitmapPageAvailableSpace = newBitmapPageAvailableSpace;
                        
                            for (j = 0; j < dbLargeBitmapPages - dbBitmapPages; j++) 
                            { 
                                setPos(currIndexSize + j, dbFreeHandleFlag);
                            }

                            header.root[curr].bitmapExtent = currIndexSize;
                            header.root[curr].indexUsed = currIndexSize += dbLargeBitmapPages - dbBitmapPages;
                        }
                        extend(pos + (long)morePages*Page.pageSize);
                        long adr = pos;
                        int len = objBitSize >> 3;
                        // fill bitmap pages used for allocation of object space with 0xFF 
                        while (len >= Page.pageSize) 
                        { 
                            pg = pool.putPage(adr);
                            memset(pg, 0, 0xFF, Page.pageSize);
                            pool.unfix(pg);
                            adr += Page.pageSize;
                            len -= Page.pageSize;
                        }
                        // fill part of last page responsible for allocation of object space
                        pg = pool.putPage(adr);
                        memset(pg, 0, 0xFF, len);
                        pg.data[len] = (byte)((1 << (objBitSize&7))-1);
                        pool.unfix(pg);

                        // mark in bitmap newly allocated object
                        fillBitmap(pos + (skip>>3), morePages * (Page.pageSize/dbAllocationQuantum/8));
                    
                        j = i;
                        while (--morePages >= 0) 
                        { 
                            setPos(getBitmapPageId(j++), pos | dbPageObjectFlag | dbModifiedFlag);
                            pos += Page.pageSize;
                        }
                        header.root[curr].bitmapEnd = j + dbBitmapId;
                        j = i + objBitSize / pageBits; 
                        if (alignment != 0) 
                        { 
                            currRBitmapPage = j;
                            currRBitmapOffs = 0;
                        } 
                        else 
                        { 
                            currPBitmapPage = j;
                            currPBitmapOffs = 0;
                        }
                        while (j > i) 
                        { 
                            bitmapPageAvailableSpace[--j] = 0;
                        }
                
                        pos = ((long)i*Page.pageSize*8 - holeBitSize)  << dbAllocationQuantumBits;
                        if (oid != 0) 
                        { 
                            long prev = getPos(oid);
                            uint marker = (uint)prev & dbFlagsMask;
                            pool.copy(pos, prev - marker, size);
                            setPos(oid, pos | marker | dbModifiedFlag);
                        }
                
                        if (holeBitSize != 0) 
                        { 
                            reserveLocation(pos, size);
                            while (holeBitSize > pageBits) 
                            { 
                                holeBitSize -= pageBits;
                                pg = putBitmapPage(--i);
                                memset(pg, 0, 0xFF, Page.pageSize);
                                bitmapPageAvailableSpace[i] = 0;
                                pool.unfix(pg);
                            }
                            pg = putBitmapPage(--i);
                            offs = Page.pageSize;
                            while ((holeBitSize -= 8) > 0) 
                            { 
                                pg.data[--offs] = (byte)0xFF; 
                            }
                            pg.data[offs-1] |= (byte)~((1 << -holeBitSize) - 1);
                            pool.unfix(pg);
                            commitLocation();
                        }
                        if (oldIndex != 0) 
                        { 
                            free(oldIndex, oldIndexSize*8L);
                        }
                        return pos;
                    }
                    if (gcThreshold != Int64.MaxValue && !gcDone) 
                    {
                        allocatedDelta -= size;
                        usedSize -= size;
                        gc0();
                        currRBitmapPage = currPBitmapPage = 0;
                        currRBitmapOffs = currPBitmapOffs = 0;                
                        return allocate(size, oid);
                    }
                    freeBitmapPage = i;
                    holeBeforeFreePage = holeBitSize;
                    holeBitSize = 0;
                    lastPage = firstPage + 1;
                    firstPage = 0;
                    offs = 0;
                }
            }
        }
		
        void fillBitmap(long adr, int len) 
        { 
            while (true) 
            { 
                int off = (int)adr & (Page.pageSize-1);
                Page pg = pool.putPage(adr - off);
                if (Page.pageSize - off >= len) 
                { 
                    memset(pg, off, 0xFF, len);
                    pool.unfix(pg);
                    break;
                } 
                else 
                { 
                    memset(pg, off, 0xFF, Page.pageSize - off);
                    pool.unfix(pg);
                    adr += Page.pageSize - off;
                    len -= Page.pageSize - off;
                }
            }
        }
		
		
        internal void  free(long pos, long size)
        {
            lock (objectCache) 
            {
                Debug.Assert(pos != 0 && (pos & (dbAllocationQuantum - 1)) == 0);
                long quantNo = pos >> dbAllocationQuantumBits;
                int objBitSize = (int)((size+dbAllocationQuantum-1) >> dbAllocationQuantumBits);
                int pageId = (int) (quantNo >> (Page.pageSizeLog + 3));
                int offs = (int) (quantNo & (Page.pageSize * 8 - 1)) >> 3;
                Page pg = putBitmapPage(pageId);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -