📄 indexleafnode.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: IndexLeafNode.java,v 1.3 2004/01/27 21:28:53 leomekenkamp Exp $package org.ozoneDB.core.storage.gammaStore;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.logging.Level;import org.ozoneDB.ObjectNotFoundException;import org.ozoneDB.OzoneInternalException;/** * @author <a href="mailto:leoATmekenkampD0Tcom">Leo Mekenkamp (mind the anti sp@m)</a> * @version $Id: IndexLeafNode.java,v 1.3 2004/01/27 21:28:53 leomekenkamp Exp $ */final class IndexLeafNode extends IndexNode { private static final long serialVersionUID = 0L; private ContainerLocationLoc containerLocationLoc; IndexLeafNode(IndexManager indexManager) { super(indexManager); setMaxSize(indexManager.getMaxLeafNodeSize()); containerLocationLoc = new ContainerLocationLoc(getMaxSize(), 0); setIndexManager(indexManager); } private void rawPutContainerLocation(long objectId, ContainerLocation containerLocation) {//if (objectId == 1690734402) log.severe("raw add " + objectId + " to indexLeafNode " + this); long oldMinObjectId = MINOBJECTID; if (size() > 0) { oldMinObjectId = getMinObjectId(); } int pos = getContainerLocationLoc().putKey(objectId); getContainerLocationLoc().putContainerLocation(pos, containerLocation); if (getParentNodeId() != LONGNULL && getMinObjectId() != oldMinObjectId) { if (log.isLoggable(Level.FINE)) log.finest("informing parent " + getParentNodeId() + " our minimum changed to " + getMinObjectId()); IndexBranchNode p = getParentNode(); p.childMinObjectIdChanged(this, oldMinObjectId); p.endInvoke(); } setDirty();//if (objectId == 1690734402) log.severe("raw just added " + objectId + " to indexLeafNode " + this); } void putContainerLocation(long objectId, ContainerLocation containerLocation) {//if (objectId == 1690734402) log.severe("about to add " + objectId + " to indexLeafNode " + this); if (log.isLoggable(Level.FINE)) log.fine("put " + objectId + " in indexLeafNode " + getNodeId()); if (!isFull()) { rawPutContainerLocation(objectId, containerLocation); } else { if (log.isLoggable(Level.FINEST)) log.finest("indexLeafNode " + getNodeId() + " is full; splitting up"); // we are full but should store this object, so we are splitting // this node into 2 nodes; putting it in the other node takes // care of the case where the objectId is the newest created // object id (the largest one of all) split(objectId, containerLocation); } if (log.isLoggable(Level.FINER)) log.fine("ready putting " + objectId + " in indexLeafNode " + getNodeId()); } /** * @throws ObjectNotFoundException when given id not found */ ContainerLocation getContainerLocation(long objectId) { int pos = getContainerLocationLoc().getKeyPos(objectId); if (pos < 0) { throw new ObjectNotFoundException("no such object id: " + objectId); } return getContainerLocationLoc().getContainerLocation(pos); } boolean existsContainerLocation(long objectId) { return getContainerLocationLoc().getKeyPos(objectId) >= 0; } /** * @throws ObjectNotFoundException when given id not found */ ContainerLocation removeContainerLocation(long objectId) {//if (objectId == 1690734402) log.severe("remove " + objectId + " from indexLeafNode " + this); if (log.isLoggable(Level.FINE)) log.fine("remove " + objectId + " from indexLeafNode " + this); int pos = getContainerLocationLoc().getKeyPos(objectId); if (pos < 0) { throw new ObjectNotFoundException("no such object id (" + objectId + ") found in indexLeafNode " + this); } // "Goodbye, cruel world; I'm leaving you today. Goodbye, goodbye, goodbye." if (size() == 1) { boolean hasSibling = false; if (getPrevNodeId() != LONGNULL) { IndexNode p = getPrevNode(); p.setNextNodeId(getNextNodeId()); p.endInvoke(); hasSibling = true; } if (getNextNodeId() != LONGNULL) { IndexNode n = getNextNode(); n.setPrevNodeId(getPrevNodeId()); n.endInvoke(); hasSibling = true; } else if (hasSibling) { // have a prev, but no next, so this must be the newest IndexLeafNode p = (IndexLeafNode) getPrevNode(); getIndexManager().setNewestLeafNode(p); p.endInvoke(); } // must ensure there is always one leaf node, if we have no siblings // then we must be the last one, so we do not remove ourselves if (hasSibling) { IndexBranchNode p = getParentNode(); p.removeChildNode(this); p.endInvoke(); // removes us from the index manager cache and deletes from // storage setIndexManager(null); } } long oldMinObjectId = getMinObjectId(); ContainerLocation result = getContainerLocationLoc().getContainerLocation(pos); getContainerLocationLoc().removePos(pos); // if we have detached ourselves from our parent there is no need to // inform our former parent that we have changed if (getParentNodeId() != LONGNULL) { long newMinObjectId = getMinObjectId(); if (oldMinObjectId != newMinObjectId) { IndexBranchNode p = getParentNode(); p.childMinObjectIdChanged(this, oldMinObjectId); p.endInvoke(); } } setDirty(); return result; } protected int size() { return getContainerLocationLoc().size(); } // private so it can be inlined private ContainerLocationLoc getContainerLocationLoc() { return containerLocationLoc; } /** * Will enter in endless recursion if empty and next node is also empty; * when a node becomes empty it will remove itself from the tree, so this is * not a problem. */ long getMaxObjectId() { long result; if (size() == 0) { result = MINOBJECTID; } else { result = getContainerLocationLoc().getMaxKey(); } return result; } /** */ long getMinObjectId() { long result; if (size() == 0) { result = MINOBJECTID; } else { result = getContainerLocationLoc().getMinKey(); } return result; } /** * Splits this instance into two nodes; the specified id is used to find * out which container locations should remain in this instance, and which * should be put in the other one. Say we have a full node with object * ids [10, 20, 30, 40, 50] and we are adding 35, then we would split into * [10, 20, 30] and [40, 50]. */ private void split(long objectId, ContainerLocation containerLocation) { if (log.isLoggable(Level.FINE)) log.fine("split around " + objectId + " for indexLeafNode " + this); // since we are about to create a new node, we wait a little if the // serializer has too much still to do getIndexManager().checkSerializerSize(); IndexLeafNode result = new IndexLeafNode(getIndexManager()); if (log.isLoggable(Level.FINE)) log.fine("split created " + result.getNodeId()); // Must test if new node is not full, because the maximum size may // change at runtime. If we don't, the new node may split itself also, // and since the new node does not know its parent yet we will then have // a problem... while (!result.isFull(1) && size() > 1) { int pos = getContainerLocationLoc().getMaxPos(); if (getContainerLocationLoc().getKey(pos) < objectId) { break; } ContainerLocation moveContainer = getContainerLocationLoc().getContainerLocation(pos); long moveObjectId = getContainerLocationLoc().getKey(pos); removeContainerLocation(moveObjectId); result.putContainerLocation(moveObjectId, moveContainer); } if (objectId > getContainerLocationLoc().getMaxKey()) { result.rawPutContainerLocation(objectId, containerLocation); } else { rawPutContainerLocation(objectId, containerLocation); } // make new node known to our peers result.setPrevNode(this); if (getNextNodeId() == LONGNULL) { getIndexManager().setNewestLeafNode(result); } else { result.setNextNodeId(getNextNodeId()); IndexNode n = getNextNode(); n.setPrevNode(result); n.endInvoke(); } setNextNode(result); // make new node known to our parent IndexBranchNode p = getParentNode(); p.putChildNode(result); p.endInvoke(); } public String toString() { return super.toString() + " " + getContainerLocationLoc(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -