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

📄 storageimpl.java

📁 这个是perst-269.zip下面的SOURCECODE,和大家分享了。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:

        if (multiclientSupport) { 
            beginThreadTransaction(READ_WRITE_TRANSACTION);
        }            
        byte[] buf = new byte[Header.sizeof];
        int rc = file.read(0, buf);
        if (rc > 0 && rc < Header.sizeof) { 
            throw new StorageError(StorageError.DATABASE_CORRUPTED);
        }
        header.unpack(buf);
        if (header.curr < 0 || header.curr > 1) { 
            throw new StorageError(StorageError.DATABASE_CORRUPTED);
        }
        transactionId = header.transactionId;
        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;
                }
                usedBitmapSize -= Page.pageSize;
                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);
            pool.flush();
        } else {
            int curr = header.curr;
            currIndex = curr;
            if (header.root[curr].indexSize != header.root[curr].shadowIndexSize) {
                throw new StorageError(StorageError.DATABASE_CORRUPTED);
            }           
            if (isDirty()) { 
                if (listener != null) {
                    listener.databaseCorrupted();
                }
                System.err.println("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.err.println("Recovery completed");
            } 
            currIndexSize = header.root[1-curr].indexUsed;
            committedIndexSize = currIndexSize;
            usedSize = header.root[curr].size;
        }
        int bitmapSize = header.root[1-currIndex].bitmapExtent == 0 ? dbBitmapPages : dbLargeBitmapPages;
        bitmapPageAvailableSpace = new int[bitmapSize];
        for (i = 0; i < bitmapPageAvailableSpace.length; i++) { 
            bitmapPageAvailableSpace[i] = Integer.MAX_VALUE;
        }        
        currRBitmapPage = currPBitmapPage = 0;
        currRBitmapOffs = currPBitmapOffs = 0;

        opened = true;
        reloadScheme();

        if (multiclientSupport) { 
            endThreadTransaction();
        }            
    }

    public boolean isOpened() { 
        return opened;
    }

    static void checkIfFinal(ClassDescriptor desc) {
        Class cls = desc.cls;
        if (cls != null) { 
            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;
                }
            }
        }
    }
        


    void reloadScheme() {
        classDescMap.clear();
        customAllocatorMap = null;
        customAllocatorList = null;
        defaultAllocator = new DefaultAllocator(this);
        int descListOid = header.root[1-currIndex].classDescList;
        classDescMap.put(ClassDescriptor.class, 
                         new ClassDescriptor(this, ClassDescriptor.class));
        classDescMap.put(ClassDescriptor.FieldDescriptor.class, 
                         new ClassDescriptor(this, ClassDescriptor.FieldDescriptor.class));
        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.get(desc.cls) == desc) { 
                    desc.resolve();
                }
                if (desc.allocator != null) {
                    if (customAllocatorMap == null) { 
                        customAllocatorMap = new HashMap();
                        customAllocatorList = new ArrayList();
                    }
                    desc.allocator.load();
                    customAllocatorMap.put(desc.cls, desc.allocator);
                    customAllocatorList.add(desc.allocator);
                }
                checkIfFinal(desc);
            }
        } else { 
            descList = null;
        }
    }

    final void assignOid(IPersistent obj, int oid) { 
        obj.assignOid(this, oid, false);
    }

    final void registerClassDescriptor(ClassDescriptor desc) { 
        classDescMap.put(desc.cls, desc);
        desc.next = descList;
        descList = desc;
        checkIfFinal(desc);
        storeObject0(desc, false);
        header.root[1-currIndex].classDescList = desc.getOid();
        modified = true;
    }        

    final ClassDescriptor getClassDescriptor(Class cls) { 
        ClassDescriptor desc = (ClassDescriptor)classDescMap.get(cls);
        if (desc == null) { 
            desc = new ClassDescriptor(this, cls);
            registerClassDescriptor(desc);
        }
        return desc;
    }


    public synchronized IPersistent getRoot() {
        if (!opened) {
            throw new StorageError(StorageError.STORAGE_NOT_OPENED);
        }
        int rootOid = header.root[1-currIndex].rootObject;
        return (rootOid == 0) ? null : lookupObject(rootOid, null);
    }
    
    public synchronized void setRoot(IPersistent root) {
        if (!opened) {
            throw new StorageError(StorageError.STORAGE_NOT_OPENED);
        }
        if (root == null) { 
            header.root[1-currIndex].rootObject = 0;
        } else { 
            if (!root.isPersistent()) { 
                storeObject0(root, false);
            }
            header.root[1-currIndex].rootObject = root.getOid();
        }
        modified = true;
    }
 
    public void commit() {
        synchronized (backgroundGcMonitor) { 
            synchronized (this) { 
                if (!opened) {
                    throw new StorageError(StorageError.STORAGE_NOT_OPENED);
                }
                objectCache.flush();

                if (customAllocatorList != null) { 
                    Iterator iterator = customAllocatorList.iterator();
                    while (iterator.hasNext()) {
                        CustomAllocator alloc = (CustomAllocator)iterator.next();
                        if (alloc.isModified()) {                             
                            alloc.store();
                        }
                        alloc.commit();
                    }
                }

                if (!modified) { 
                    return;
                }
                commit0();
                modified = false;
            }
        }
    }

    private final void commit0() 
    {
        int i, j, n;
        int curr = currIndex;
        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);
        }

⌨️ 快捷键说明

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