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

📄 indexnode.java

📁 Java的面向对象数据库系统的源代码
💻 JAVA
字号:
// You can redistribute this software and/or modify it under the terms of// the Ozone Core License version 1 published by ozone-db.org.//// Copyright (C) 2003-@year@, Leo Mekenkamp. All rights reserved.//// $Id: IndexNode.java,v 1.4 2004/02/01 20:55:47 leomekenkamp Exp $package org.ozoneDB.core.storage.gammaStore;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.util.logging.Level;import java.util.logging.Logger;import org.ozoneDB.OzoneInternalException;import org.ozoneDB.core.storage.Cache;/** * <p>Index nodes are the nodes that make up the tree used for storing * information on where objects can be found (cluster + location). Because * memory is limited, it is impossible to have all index nodes in memory under * all circumstances. Therefor there are no hard references to other index nodes * but only ids are stored.</p> * * <p>There is not much logic here, most logic is in <code>IndexManager</code>. * </p> * * @author <a href="mailto:leoATmekenkampD0Tcom">Leo Mekenkamp (mind the anti sp@m)</a> * @version $Id: IndexNode.java,v 1.4 2004/02/01 20:55:47 leomekenkamp Exp $ */public abstract class IndexNode implements Storable {        private static final long serialVersionUID = 0L;    protected static final Logger log = Logger.getLogger(IndexNode.class.getName());    static {//        log.setLevel(Level.ALL);    }        /**     * alternative <code>null</code> value     */    public static final long LONGNULL = Long.MIN_VALUE;        public static final long MINOBJECTID = Long.MIN_VALUE + 1;    public static final long MAXOBJECTID = Long.MAX_VALUE;        /**     * used for <code>StorageFactory</code> instances     */    private static final String INDEXNODENAMESUFFIX = ".idxnode";        /**     * <p>Used to name indexfiles. We could take any value from 2 to      * <code>Character.MAX_RADIX</code> (36) here, but we settle for 16 because     * it looks nice and nerdy. 36 would look less nice because that would     * inevitably lead to filenames with very nasty words in them, like     * <code>fuck.idxnode</code> and <code>microsoft.idxnode</code>.</p>     * <p>Before you know it, someone sues you for trademark infringement.</p>     * <p>Insiders joke: CAFEBABE is not a trademark, is she?</p>     */    private static final int NAMECONVERTRADIX = 10; // 16;    /**     * Read buffer for instantiating new index nodes from storage.     */    private static ThreadLocal readBufHolder = new ThreadLocal() {        protected synchronized Object initialValue() {            return new byte[1024];        }    };    /**     * our id     */    private long nodeId = LONGNULL;        /**     * parent in the tree     */    private long parentNodeId = LONGNULL;        /**     * maximum number of subnodes or object entries     */    private int maxSize;        /**     * indicates a change which requires a write to storage when finalized     */    private transient boolean dirty;        /**     * sibling node in the tree     */    private long prevNodeId = LONGNULL;    /**     * sibling node in the tree     */    private long nextNodeId = LONGNULL;        /**     * Index manager this instance is in. Set by constructor     * and/or <code>read()</code> factory method.     */    private transient IndexManager indexManager;        private transient int invoked;        /**     * Constructor for an index node. Extending classes should place themselves     * in its index managers cache.     *     * @param indexManager manages this instance     */    protected IndexNode(IndexManager indexManager) {        startInvoke();        nodeId = indexManager.nextNodeId();    }        /**     * Returns the index manager that is 'managing' this tree.     *     * @return IndexManager manager this instance is in     */    protected IndexManager getIndexManager() {        return indexManager;    }        /**     * Sets the index manager that is 'managing' this tree. Also deletes image     * from storage if necessary.     *     * @param indexManager manager this instance is in     */    protected void setIndexManager(IndexManager indexManager) {        Long id = new Long(getNodeId());        if (this.indexManager != null) {            this.indexManager.removeFromCaches(this);            this.indexManager.getNodeSerializer().remove(id);            this.indexManager.getDeleter().delete(this, this.indexManager.getStorageFactory());        }        this.indexManager = indexManager;        setDirty();        if (this.indexManager != null) {            this.indexManager.putInCaches(this);        }    }        public String toString() {        return "id:" + getNodeId() + "; parent:" +                 ((getParentNodeId() == LONGNULL) ? "null" : Long.toString(getParentNodeId())) +//                "; prev:" + //                ((getPrevNodeId() == LONGNULL) ? "null" : Long.toString(getPrevNodeId())) //                + "; next:" + //                ((getNextNodeId()  == LONGNULL) ? "null" : Long.toString(getNextNodeId())) +                 "; dirty:" + isDirty() + "; minObjectId:" + getMinObjectId() +                "; maxObjectId:" + getMaxObjectId() + "; size:" + size() + "; invoked: " + invoked;    }        /**     * Indicates if this node has changed since last call to <code>write()</code>.     */    final boolean isDirty() {        return dirty;    }        final void setDirty(boolean dirty) {        if (log.isLoggable(Level.FINEST)) log.finest(getNodeId() + " dirty: " + dirty);        boolean changed = this.dirty != dirty;        this.dirty = dirty;        if (changed) {            getIndexManager().nodeBecameDirty(this);        }    }        final void setDirty() {        setDirty(true);    }    /**     * Converts a node id to corresponding (file)name for a node.     */    static String nodeIdToStorageName(long nodeId) {        return Long.toString(nodeId, NAMECONVERTRADIX) + INDEXNODENAMESUFFIX;    }    /**     * Converts an index (file)name to its corresponding node id     */    static long storageNameToNodeId(String indexFilename) {        String num = indexFilename.substring(0, indexFilename.length() - 1 - INDEXNODENAMESUFFIX.length());        return Long.parseLong(num, NAMECONVERTRADIX);    }        /** Returnes the filename that this node can be saved to, or to be more     * precise: the name that can be used by a <code>StorageFactory</code> to     * create a unique <code>Storable</code>.     */    public String getStorageName() {        return nodeIdToStorageName(getNodeId());    }        /** Factory method to create a node by reading it from the storage used     * for index nodes by the specified index manager.     *     * @param indexManager index manager that manages this instance     * @param nodeId id of the node to be read     */    static IndexNode read(IndexManager indexManager, long nodeId) throws IOException {        if (log.isLoggable(Level.FINE)) log.fine("about to read indexnode " + nodeId);        String nodeName = nodeIdToStorageName(nodeId);        IndexNode result;        Storage storage = null;        try {            storage = indexManager.getStorageFactory().createStorage(nodeName);            try {                byte[] b = (byte[]) readBufHolder.get();                int numBytesToRead = (int) storage.length();                if (b.length < numBytesToRead) {                    b = new byte[numBytesToRead];                    readBufHolder.set(b);                }                storage.readFully(b, 0, numBytesToRead);                StreamFactory streamFactory = indexManager.getStreamFactory();                ObjectInputStream objIn;                if (streamFactory == null) {                    objIn = new ObjectInputStream(new ByteArrayInputStream(b));                } else {                    objIn = new ObjectInputStream(streamFactory.createInputStream(new ByteArrayInputStream(b)));                }                result = (IndexNode) objIn.readObject();                result.startInvoke();                result.setIndexManager(indexManager);            } catch (ClassNotFoundException e) {                throw new OzoneInternalException("\"Ford, you are turning into a penguin. Stop it.\"", e);            }        } finally {            if (storage != null) {                storage.close();            }        }//if (nodeId == 8 || nodeId == 6) log.severe("read " + result);if (result instanceof IndexLeafNode) {    if (result.getParentNodeId() == LONGNULL) {        log.severe("no parent for " + result.getNodeId());        throw new RuntimeException();    }}        return result;    }        /**     * Returns the number of elements in this node.     * @return number of elements in this node     */    protected abstract int size();        /**     * Returns <code>true</code> if there is no more room for new elements,     * <code>false</code> otherwise     * @return <code>true</code> if this node is full, <code>false</code>     * otherwise     */    protected final boolean isFull() {        return isFull(0);    }        /**     * Returns <code>true</code> if there is no more room for new elements after     * the specified number of elements were added,      * <code>false</code> otherwise     * @return <code>true</code> if this node (+ specified extra) is full,      * <code>false</code> otherwise     */    protected final boolean isFull(int withExtraElements) {        return size() + withExtraElements >= getMaxSize();    }        /**     * Returns the relative size of this node, on a scale of [0 .. 1]     */    final float relSize() {        return (float) size() / (float) getMaxSize();    }    /**     * @throws IllegalStateException when called for the second time     */    protected final void setMaxSize(int maxSize) {        if (this.maxSize != 0) {            throw new IllegalStateException("cannot change max size");        }        this.maxSize = maxSize;    }    final int getMaxSize() {        return maxSize;    }        /**     * Returns the minimum object id that can be found be in this node     */    abstract long getMinObjectId();        /**     * Returns the maximum object id that can be found be in this node     */    abstract long getMaxObjectId();        final long getNodeId() {        return nodeId;    }        final long getParentNodeId() {        return parentNodeId;    }        final void setParentNodeId(long parentNodeId) {        this.parentNodeId = parentNodeId;        setDirty();    }        /**     * Only ment to be called from IndexBranchNode.putChildNode(IndexNode).     */    final void setParentNode(IndexBranchNode parent) {        if (parent == null) {            setParentNodeId(LONGNULL);        } else {            setParentNodeId(parent.getNodeId());        }    }        final IndexBranchNode getParentNode() {        return (IndexBranchNode) getIndexManager().getNode(getParentNodeId());    }        final long getPrevNodeId() {        return prevNodeId;    }    final IndexNode getPrevNode() {        return getIndexManager().getNode(getPrevNodeId());    }        final void setPrevNodeId(long prevNodeId) {        this.prevNodeId = prevNodeId;        setDirty();    }        final void setPrevNode(IndexNode prev) {        if (prev == null) {            setPrevNodeId(LONGNULL);        } else {            setPrevNodeId(prev.getNodeId());        }    }        final long getNextNodeId() {        return nextNodeId;    }        final IndexNode getNextNode() {        return getIndexManager().getNode(getNextNodeId());    }        final void setNextNodeId(long nextNodeId) {        this.nextNodeId = nextNodeId;        setDirty();    }        final void setNextNode(IndexNode next) {        if (next == null) {            setNextNodeId(LONGNULL);        } else {            setNextNodeId(next.getNodeId());        }    }        final void startInvoke() {        invoked++;        if (invoked > 3) throw new OzoneInternalException("pretty big invoke for node: " + getNodeId());    }    final void endInvoke() {        invoked--;        if (invoked < 0) throw new OzoneInternalException("pretty small invoke for node: " + getNodeId());    }        final boolean isInvoked() {        return invoked > 0;    }     protected void finalize() throws Throwable {        if (isDirty()) {            log.severe("how can I (" + getNodeId() + ") be dirty on finalize()?");        }        super.finalize();    }}

⌨️ 快捷键说明

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