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

📄 storageimpl.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 5 页
字号:
                int bitOffs = (int) quantNo & 7;
			
                allocatedDelta -= (long)objBitSize << dbAllocationQuantumBits;
                usedSize -= (long)objBitSize << dbAllocationQuantumBits;
			
                if ((pos & (Page.pageSize - 1)) == 0 && size >= Page.pageSize)
                {
                    if (pageId == currPBitmapPage && offs < currPBitmapOffs)
                    {
                        currPBitmapOffs = offs;
                    }
                }
                if (pageId == currRBitmapPage && offs < currRBitmapOffs)
                {
                    currRBitmapOffs = offs;
                }
                bitmapPageAvailableSpace[pageId] = System.Int32.MaxValue;
			
                if (objBitSize > 8 - bitOffs)
                {
                    objBitSize -= 8 - bitOffs;
                    pg.data[offs++] &= (byte)((1 << bitOffs) - 1);
                    while (objBitSize + offs * 8 > Page.pageSize * 8)
                    {
                        memset(pg, offs, 0, Page.pageSize - offs);
                        pool.unfix(pg);
                        pg = putBitmapPage(++pageId);
                        bitmapPageAvailableSpace[pageId] = System.Int32.MaxValue;
                        objBitSize -= (Page.pageSize - offs) * 8;
                        offs = 0;
                    }
                    while ((objBitSize -= 8) > 0)
                    {
                        pg.data[offs++] = (byte) 0;
                    }
                    pg.data[offs] &= (byte) (~ ((1 << (objBitSize + 8)) - 1));
                }
                else
                {
                    pg.data[offs] &= (byte) (~ (((1 << objBitSize) - 1) << bitOffs));
                }
                pool.unfix(pg);
            }
        }
		
        internal void  cloneBitmap(long pos, long size)
        {
            lock (objectCache) 
            {
                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;
                int  bitOffs = (int) quantNo & 7;
                int  oid = getBitmapPageId(pageId);
                pos = getPos(oid);
                if ((pos & dbModifiedFlag) == 0)
                {
                    dirtyPagesMap[oid >> (dbHandlesPerPageBits + 5)] 
                        |= 1 << ((oid >> dbHandlesPerPageBits) & 31);
                    allocate(Page.pageSize, oid);
                    cloneBitmap(pos & ~ dbFlagsMask, Page.pageSize);
                }
			
                if (objBitSize > 8 - bitOffs)
                {
                    objBitSize -= 8 - bitOffs;
                    offs += 1;
                    while (objBitSize + offs * 8 > Page.pageSize * 8)
                    {
                        oid = getBitmapPageId(++pageId);
                        pos = getPos(oid);
                        if ((pos & dbModifiedFlag) == 0)
                        {
                            dirtyPagesMap[oid >> (dbHandlesPerPageBits + 5)] 
                                |= 1 << ((oid >> dbHandlesPerPageBits) & 31);
                            allocate(Page.pageSize, oid);
                            cloneBitmap(pos & ~ dbFlagsMask, Page.pageSize);
                        }
                        objBitSize -= (Page.pageSize - offs) * 8;
                        offs = 0;
                    }
                }
            }
        }
		
        public void Open(String filePath)
        {
            Open(filePath, DEFAULT_PAGE_POOL_SIZE);
        }

        public void Open(IFile file)
        {
            Open(file, DEFAULT_PAGE_POOL_SIZE);
        }

        public void Open(String filePath, int pagePoolSize)
        {
            IFile file = filePath.StartsWith("@") 
                ? (IFile)new MultiFile(filePath.Substring(1), readOnly, noFlush)
                : (IFile)new OSFile(filePath, readOnly, noFlush);      
            try 
            {
                Open(file, pagePoolSize);
            } 
            catch (StorageError ex) 
            {
                file.Close();            
                throw ex;
            }
        }
        
        public void ClearObjectCache()
        {
            objectCache.clear();
        }

        protected virtual OidHashTable createObjectCache(string kind, int pagePoolSize, int objectCacheSize) 
        { 
            if (pagePoolSize == 0 || "strong".Equals(kind)) 
            {
                return new StrongHashTable(objectCacheSize);
            }
            if ("weak".Equals(kind)) 
            { 
                return new WeakHashTable(objectCacheSize);
            }
            if ("pinned".Equals(kind)) 
            { 
                return new PinWeakHashTable(objectCacheSize);
            }
            return new LruObjectCache(objectCacheSize);
        }
        

        public void Open(String filePath, int pagePoolSize, String cipherKey)
        {
            Rc4File file = new Rc4File(filePath, readOnly, noFlush, cipherKey);      
            try 
            {
                Open(file, pagePoolSize);
            } 
            catch (StorageError ex) 
            {
                file.Close();            
                throw ex;
            }
        }

        protected void initialize(IFile file, int pagePoolSize) 
        { 
            if (lockFile) 
            { 
                file.Lock();
            }
            dirtyPagesMap = new int[dbDirtyPageBitmapSize/4+1];
            gcThreshold = Int64.MaxValue;
            backgroundGcMonitor = new object();
            backgroundGcStartMonitor = new object();
            gcGo = false;
            gcThread = null;
            gcActive = false;
            gcDone = false;
            allocatedDelta = 0;
    
            resolvedTypes = new Hashtable();                

            nNestedTransactions = 0;
            nBlockedTransactions = 0;
            nCommittedTransactions = 0;
            scheduledCommitTime = Int64.MaxValue;
#if COMPACT_NET_FRAMEWORK
            transactionMonitor = new CNetMonitor();
#else
            transactionMonitor = new object();
#endif
            transactionLock = new PersistentResource();
    
            modified = false; 
    
            objectCache = createObjectCache(cacheKind, pagePoolSize, objectCacheInitSize);
    
            classDescMap = new Hashtable();
            descList = null;
            
#if SUPPORT_RAW_TYPE
            objectFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
#endif                

            header = new Header();
            pool = new PagePool(pagePoolSize/Page.pageSize, pagePoolLruLimit);
            pool.open(file);
        }        

        public virtual void Open(IFile file, int pagePoolSize)
        {
            lock(this)
            {
                Page pg;
                int i;

                if (opened)
                {
                    throw new StorageError(StorageError.ErrorCode.STORAGE_ALREADY_OPENED);
                }
                initialize(file, pagePoolSize);

                scheduledCommitTime = Int64.MaxValue;
				
                byte[] buf = new byte[Header.Sizeof];
                int rc = file.Read(0, buf);
                if (rc > 0 && rc < Header.Sizeof)
                {
                    throw new StorageError(StorageError.ErrorCode.DATABASE_CORRUPTED);
                }
                header.unpack(buf);
                if (header.curr < 0 || header.curr > 1)
                {
                    throw new StorageError(StorageError.ErrorCode.DATABASE_CORRUPTED);
                }
                if (!header.initialized)
                {
                    int indexSize = initIndexSize;
                    if (indexSize < dbFirstUserId)
                    {
                        indexSize = dbFirstUserId;
                    }
                    indexSize = (indexSize + dbHandlesPerPage - 1) & ~ (dbHandlesPerPage - 1);

                    header.curr = currIndex = 0;
                    long used = Page.pageSize;
                    header.root[0].index = used;
                    header.root[0].indexSize = indexSize;
                    header.root[0].indexUsed = dbFirstUserId;
                    header.root[0].freeList = 0;
                    used += indexSize * 8L;
                    header.root[1].index = used;
                    header.root[1].indexSize = indexSize;
                    header.root[1].indexUsed = dbFirstUserId;
                    header.root[1].freeList = 0;
                    used += indexSize * 8L;
					
                    header.root[0].shadowIndex = header.root[1].index;
                    header.root[1].shadowIndex = header.root[0].index;
                    header.root[0].shadowIndexSize = indexSize;
                    header.root[1].shadowIndexSize = indexSize;
					
                    int bitmapPages = (int) ((used + Page.pageSize * (dbAllocationQuantum * 8 - 1) - 1) / (Page.pageSize * (dbAllocationQuantum * 8 - 1)));
                    long bitmapSize = (long)bitmapPages * Page.pageSize;
                    int usedBitmapSize = (int) ((used + bitmapSize) >> (dbAllocationQuantumBits + 3));
					
                    for (i = 0; i < bitmapPages; i++) 
                    { 
                        pg = pool.putPage(used + (long)i*Page.pageSize);
                        byte[] bitmap = pg.data;
                        int n = usedBitmapSize > Page.pageSize ? Page.pageSize : usedBitmapSize;
                        for (int j = 0; j < n; j++) 
                        { 
                            bitmap[j] = (byte)0xFF;
                        }
                        pool.unfix(pg);
                    }
                    
                    int bitmapIndexSize = ((dbBitmapId + dbBitmapPages) * 8 + Page.pageSize - 1) & ~ (Page.pageSize - 1);
                    byte[] index = new byte[bitmapIndexSize];
                    Bytes.pack8(index, dbInvalidId * 8, dbFreeHandleFlag);
                    for (i = 0; i < bitmapPages; i++)
                    {
                        Bytes.pack8(index, (dbBitmapId + i) * 8, used | dbPageObjectFlag);
                        used += Page.pageSize;
                    }
                    header.root[0].bitmapEnd = dbBitmapId + i;
                    header.root[1].bitmapEnd = dbBitmapId + i;
                    while (i < dbBitmapPages)
                    {
                        Bytes.pack8(index, (dbBitmapId + i) * 8, dbFreeHandleFlag);
                        i += 1;
                    }
                    header.root[0].size = used;
                    header.root[1].size = used;
                    usedSize = used;
                    committedIndexSize = currIndexSize = dbFirstUserId;
					
                    pool.write(header.root[1].index, index);
                    pool.write(header.root[0].index, index);

                    header.dirty = true;
                    header.root[0].size = header.root[1].size;
                    pg = pool.putPage(0);
                    header.pack(pg.data);
                    pool.flush();
                    pool.modify(pg);
                    header.initialized = true;
                    header.pack(pg.data);
                    pool.unfix(pg);

⌨️ 快捷键说明

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