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

📄 storageimpl.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 5 页
字号:
                    pool.flush();
                }
                else
                {
                    int curr = header.curr;
                    currIndex = curr;
                    if (header.root[curr].indexSize != header.root[curr].shadowIndexSize)
                    {
                        throw new StorageError(StorageError.ErrorCode.DATABASE_CORRUPTED);
                    }
                    if (isDirty())
                    {
                        if (listener != null) 
                        {
                            listener.DatabaseCorrupted();
                        }
                        System.Console.WriteLine("Database was not normally closed: start recovery");
                        header.root[1-curr].size = header.root[curr].size;
                        header.root[1-curr].indexUsed = header.root[curr].indexUsed;
                        header.root[1-curr].freeList = header.root[curr].freeList;
                        header.root[1-curr].index = header.root[curr].shadowIndex;
                        header.root[1-curr].indexSize = header.root[curr].shadowIndexSize;
                        header.root[1-curr].shadowIndex = header.root[curr].index;
                        header.root[1-curr].shadowIndexSize = header.root[curr].indexSize;
                        header.root[1-curr].bitmapEnd = header.root[curr].bitmapEnd;
                        header.root[1-curr].rootObject = header.root[curr].rootObject;
                        header.root[1-curr].classDescList = header.root[curr].classDescList;
                        header.root[1-curr].bitmapExtent = header.root[curr].bitmapExtent;

                        pg = pool.putPage(0);
                        header.pack(pg.data);
                        pool.unfix(pg);
						
                        pool.copy(header.root[1-curr].index,    
                            header.root[curr].index, 
                            (header.root[curr].indexUsed * 8L + Page.pageSize - 1) & ~ (Page.pageSize - 1));
                        if (listener != null) 
                        {
                            listener.RecoveryCompleted();
                        }
                        System.Console.WriteLine("Recovery completed");
                    }
                    currIndexSize = header.root[1-curr].indexUsed;
                    committedIndexSize = currIndexSize;
                    usedSize = header.root[curr].size;
                }
                int nBitmapPages = header.root[1-currIndex].bitmapExtent == 0 ? dbBitmapPages : dbLargeBitmapPages;
                bitmapPageAvailableSpace = new int[nBitmapPages];
                for (i = 0; i < bitmapPageAvailableSpace.Length; i++) 
                { 
                    bitmapPageAvailableSpace[i] = int.MaxValue;
                }        
                currRBitmapPage = currPBitmapPage = 0;
                currRBitmapOffs = currPBitmapOffs = 0;

                opened = true;
                reloadScheme();
            }
        }

        public bool IsOpened() 
        { 
            return opened;
        }
		
        internal static void  checkIfFinal(ClassDescriptor desc)
        {
            System.Type cls = desc.cls;
            for (ClassDescriptor next = desc.next; next != null; next = next.next)
            {
                next.Load();
                if (cls.IsAssignableFrom(next.cls))
                {
                    desc.hasSubclasses = true;
                }
                else if (next.cls.IsAssignableFrom(cls))
                {
                    next.hasSubclasses = true;
                }
            }
        }
		
		
        internal void  reloadScheme()
        {
            classDescMap.Clear();
            customAllocatorMap = null;
            customAllocatorList = null;
            defaultAllocator = new DefaultAllocator(this);
            int descListOid = header.root[1-currIndex].classDescList;
            classDescMap[typeof(ClassDescriptor)] = new ClassDescriptor(this, typeof(ClassDescriptor));
            classDescMap[typeof(ClassDescriptor.FieldDescriptor)] = new ClassDescriptor(this, typeof(ClassDescriptor.FieldDescriptor));
            if (descListOid != 0)
            {
                ClassDescriptor desc;
                descList = findClassDescriptor(descListOid);
                for (desc = descList; desc != null; desc = desc.next)
                {
                    desc.Load();
                }
                for (desc = descList; desc != null; desc = desc.next)
                {
                    if (classDescMap[desc.cls] == desc) 
                    { 
                        desc.resolve();
                    }
                    if (desc.allocator != null) 
                    {
                        if (customAllocatorMap == null) 
                        { 
                            customAllocatorMap = new Hashtable();
                            customAllocatorList = new ArrayList();
                        }
                        desc.allocator.Load();
                        customAllocatorMap[desc.cls] = desc.allocator;
                        customAllocatorList.Add(desc.allocator);
                    }
                    checkIfFinal(desc);
                }
            }
            else
            {
                descList = null;
            }
#if !COMPACT_NET_FRAMEWORK
            if (runtimeCodeGeneration == RuntimeCodeGeneration.Asynchronous) 
            { 
                codeGenerationThread = new Thread(new ThreadStart(generateSerializers));
                codeGenerationThread.Priority = ThreadPriority.BelowNormal;
                codeGenerationThread.IsBackground = true;
                codeGenerationThread.Start();
            } 
            else if (runtimeCodeGeneration == RuntimeCodeGeneration.Synchronous)
            {
                generateSerializers();
            }                
#endif
        }
 

        internal void generateSerializers() 
        {
            for (ClassDescriptor desc = descList; desc != null; desc = desc.next) 
            {
                desc.generateSerializer();
            }
        }

        internal void  assignOid(IPersistent obj, int oid)
        {
            obj.AssignOid(this, oid, false);
        }
			
        internal void registerClassDescriptor(ClassDescriptor desc) 
        { 
            classDescMap[desc.cls] = desc;
            desc.next = descList;
            descList = desc;
            checkIfFinal(desc);
            storeObject0(desc, false);
            header.root[1-currIndex].classDescList = desc.Oid;
            modified = true;
        }      


        internal ClassDescriptor getClassDescriptor(System.Type cls)
        {
            ClassDescriptor desc = (ClassDescriptor) classDescMap[cls];
            if (desc == null)
            {
                desc = new ClassDescriptor(this, cls);
                desc.generateSerializer();
                registerClassDescriptor(desc);
            }
            return desc;
        }
		    

        public void Commit()
        {
            lock (backgroundGcMonitor) 
            { 
                lock(this)
                {
                    if (!opened)
                    {
                        throw new StorageError(StorageError.ErrorCode.STORAGE_NOT_OPENED);
                    }
                    objectCache.flush();
                               
                    if (customAllocatorList != null)
                    {
                        foreach (CustomAllocator alloc in customAllocatorList)
                        {
                            if (alloc.IsModified())
                            {
                                alloc.Store();
                            }
                            alloc.Commit();
                        }
                    }
                    if (!modified)
                    {
                        return;
                    }
                    commit0();
                    modified = false;
                }
            }
        }

        private void commit0()
        {
            int curr = currIndex;
            int i, j, n;
            int[] map = dirtyPagesMap;
            int oldIndexSize = header.root[curr].indexSize;
            int newIndexSize = header.root[1-curr].indexSize;
            int nPages = committedIndexSize >> dbHandlesPerPageBits;
            Page pg;
            if (newIndexSize > oldIndexSize)
            {
                cloneBitmap(header.root[curr].index, oldIndexSize*8L);
                long newIndex;
                while (true) 
                { 
                    newIndex = allocate(newIndexSize*8L, 0);
                    if (newIndexSize == header.root[1-curr].indexSize) 
                    { 
                        break;
                    }
                    free(newIndex, newIndexSize*8L);
                    newIndexSize = header.root[1-curr].indexSize;
                }
                header.root[1-curr].shadowIndex = newIndex;
                header.root[1-curr].shadowIndexSize = newIndexSize;
                free(header.root[curr].index, oldIndexSize*8L);
            }
            long currSize = header.root[1-curr].size;
            for (i = 0; i < nPages; i++)
            {
                if ((map[i >> 5] & (1 << (i & 31))) != 0)
                {
                    Page srcIndex = pool.getPage(header.root[1-curr].index + (long)i * Page.pageSize);
                    Page dstIndex = pool.getPage(header.root[curr].index + (long)i * Page.pageSize);
                    for (j = 0; j < Page.pageSize; j += 8)
                    {
                        long pos = Bytes.unpack8(dstIndex.data, j);
                        if (Bytes.unpack8(srcIndex.data, j) != pos && pos < currSize)
                        {
                            if ((pos & dbFreeHandleFlag) == 0)
                            {
                                if ((pos & dbPageObjectFlag) != 0)
                                {
                                    free(pos & ~ dbFlagsMask, Page.pageSize);
                                }
                                else if (pos != 0)
                                {
                                    int offs = (int) pos & (Page.pageSize - 1);
                                    pg = pool.getPage(pos - offs);
                                    free(pos, ObjectHeader.getSize(pg.data, offs));
                                    pool.unfix(pg);
                                }
                            }
                        }
                    }
                    pool.unfix(srcIndex);
                    pool.unfix(dstIndex);
                }
            }
            n = committedIndexSize & (dbHandlesPerPage - 1);
            if (n != 0 && (map[i >> 5] & (1 << (i & 31))) != 0)
            {
                Page srcIndex = pool.getPage(header.root[1-curr].index + (long)i * Page.pageSize);
                Page dstIndex = pool.getPage(header.root[curr].index + (long)i * Page.pageSize);
                j = 0;
                do 
                {
                    long pos = Bytes.unpack8(dstIndex.data, j);
                    if (Bytes.unpack8(srcIndex.data, j) != pos && pos < currSize)
                    {
                        if ((pos & dbFreeHandleFlag) == 0)
                        {
                            if ((pos & dbPageObjectFlag) != 0)
                            {
                                free(pos & ~ dbFlagsMask, Page.pageSize);
                            }
                            else if (pos != 0)
                            {
                                int offs = (int) pos & (Page.pageSize - 1);
                                pg = pool.getPage(pos - offs);
                                free(pos, ObjectHeader.getSize(pg.data, offs));
                                pool.unfix(pg);
                            }
               

⌨️ 快捷键说明

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