📄 indexmanager.java
字号:
* places itself in the node cache. Returned node is invoked. * * @param nodeId the id of the node * @return IndexNode node containing the specified node, or <code>null</code> * when there is no such node */ IndexNode getNode(long nodeId) { Long nodeIdLong = new Long(nodeId); nodeLoaded++; if (log.isLoggable(Level.FINER)) log.finer("getting node " + nodeId); IndexNode result = getRootNode(); if (result.getNodeId() == nodeId) { if (log.isLoggable(Level.FINEST)) log.finest(nodeId + " is the root node"); nodeLoadedDirect++; } else { result.endInvoke(); result = getNewestLeafNode(); if (result.getNodeId() == nodeId) { if (log.isLoggable(Level.FINEST)) log.finest(nodeId + " is the newest leaf node"); nodeLoadedDirect++; } else { result.endInvoke(); result = getNodeFromCaches(nodeIdLong); if (result != null) {//if (nodeId == 6) log.severe(nodeId + " was in the cache"); if (log.isLoggable(Level.FINEST)) log.finest(nodeId + " was in some cache"); nodeLoadedCache++; result.startInvoke(); } else {//if (nodeId == 6) log.severe(nodeId + " was NOT in the cache"); if (log.isLoggable(Level.FINEST)) log.finest(nodeId + " was not in some cache"); result = (IndexNode) getNodeSerializer().remove(nodeIdLong); if (result != null) {//if (nodeId == 6) log.severe(nodeId + " was in the nodeSerializer"); if (log.isLoggable(Level.FINEST)) log.finest(nodeId + " was in the nodeSerializer"); nodeLoadedSerializer++; result.startInvoke(); // Since a node is set to 'not dirty' when it is put // into the serializer, we must now set it back to dirty // again. It might be that the node has just been // written and thus should not have to be set dirty // again, but in that case we just write it twice, // rather than risk skipping a write. result.setDirty(); putInCaches(result); } else {//if (nodeId == 6) log.severe(nodeId + " was NOT in the nodeSerializer"); if (log.isLoggable(Level.FINEST)) log.finest(nodeId + " was not in the nodeSerializer"); result = loadNode(nodeId); } } } } return result; } /** * Loads an indexnode from disk. * @throws OzoneInternalException if error during reading */ private IndexNode loadNode(long nodeId) { IndexNode result; try { result = IndexNode.read(this, nodeId); nodeLoadedDisk++; } catch (IOException e) { log.log(Level.SEVERE, "could not read index node " + nodeId, e); throw new OzoneInternalException("could not read index node " + nodeId, e); } return result; } /** * Checks the size of the serializer and suspends the current thread (sleep) * if the serializer has too many nodes in it. Needed to ensure there is * never an out of memory because nodes that have to be removed from memory * and stored on disk are still in memory; those nodes are to be swapped * out because of low memory condition (probably). */ void checkSerializerSize() { int size = getNodeSerializer().size(); int timeout = (size - 100) * 10; // TODO: config params if (timeout > 0) { if (log.isLoggable(Level.INFO)) log.info("timeout needed because serializer contains " + size + " indexnodes"); try { Thread.sleep(timeout); } catch (InterruptedException ignore) { } } } private IndexLeafNode getLeafNode(long objectId) { if (log.isLoggable(Level.FINER)) log.finer("getting leafnode for " + objectId); IndexLeafNode result = null; IndexBranchNode parentNode = getRootNode(); do { if (log.isLoggable(Level.FINEST)) log.finest("current branchnode: " + parentNode.getNodeId()); IndexNode childNode = getNode(parentNode.getChildNodeId(objectId)); parentNode.endInvoke(); if (childNode instanceof IndexLeafNode) { result = (IndexLeafNode) childNode; } else { parentNode = (IndexBranchNode) childNode; } } while (result == null); if (log.isLoggable(Level.FINER)) log.finer("found leafnode: " + result.getNodeId()); return result; }// /** * @param objectId id of the object for which the location is returned * @return ContainerLocation location for the specified object * @throws ObjectNotFoundException if no container location can be found * for specified objectId */ public synchronized ContainerLocation getContainerLocation(long objectId) { IndexLeafNode l = getLeafNode(objectId); try { ContainerLocation result = l.getContainerLocation(objectId); return result; } finally { l.endInvoke(); } } /** */ public synchronized void putContainerLocation(long objectId, ContainerLocation containerLocation) { IndexLeafNode leafNode; leafNode = getNewestLeafNode(); if (objectId < leafNode.getMinObjectId()) { leafNode.endInvoke(); leafNode = getLeafNode(objectId); } if (!leafNode.existsContainerLocation(objectId)) { size++; } leafNode.putContainerLocation(objectId, containerLocation); leafNode.endInvoke(); } public synchronized void removeContainerLocation(long objectId) { ContainerLocation containerLocation; IndexLeafNode leafNode = getLeafNode(objectId); leafNode.removeContainerLocation(objectId); leafNode.endInvoke(); size--; } /** * Returns the number of container locations in this instance. */ public long getSize() { return size; } long nextNodeId() { return ++nodeIdCounter; } private long getNodeIdCounter() { return nodeIdCounter; } private void setNodeIdCounter(long nodeIdCounter) { this.nodeIdCounter = nodeIdCounter; } private void setSize(long size) { this.size = size; } int getMaxLeafNodeSize() { return maxLeafNodeSize; // TODO: config param } private void setMaxLeafNodeSize(int maxLeafNodeSize) { if (maxLeafNodeSize < MINMAXLEAFNODESIZE) { throw new ConfigurationException("max leaf node size must be >= " + MINMAXLEAFNODESIZE); } this.maxLeafNodeSize = maxLeafNodeSize; } int getMaxBranchNodeSize() { return maxBranchNodeSize; // TODO: config param } private void setMaxBranchNodeSize(int maxBranchNodeSize) { if (maxBranchNodeSize < MINMAXBRANCHNODESIZE) { throw new ConfigurationException("max branch node size must be >= " + MINMAXBRANCHNODESIZE); } this.maxBranchNodeSize = maxBranchNodeSize; } private float getLeafNodeMergeThreshhold() { return 0.5F; // TODO: config param } private int getLeafNodeMergeDistance() { return 4; // TODO: config param } private int getNodeCacheSize() { return 200; // TODO: config param } private IndexBranchNode getRootNode() { rootNode.startInvoke(); return rootNode; } void putInCaches(IndexNode indexNode) { Long id = new Long(indexNode.getNodeId()); // for performance reasons we do not put the node into the backup cache // this will happen when trimmed from general cache if (indexNode.isDirty()) { getDirtyNodeCache().put(id, indexNode); } else { getGeneralNodeCache().put(id, indexNode); } } void removeFromCaches(IndexNode indexNode) { Long id = new Long(indexNode.getNodeId()); getBackupNodeCache().remove(id); getGeneralNodeCache().remove(id); getDirtyNodeCache().remove(id); } private IndexNode getNodeFromCaches(Long id) { IndexNode result = (IndexNode) getGeneralNodeCache().get(id); if (result == null) { result = (IndexNode) getDirtyNodeCache().get(id); if (result == null) { // Node may be thrown out of general cache, but may be dirty and // still in dirty cache. "Money talks, money talks. Dirty cash, I // want you, dirty cash I need you, woo-ooh." // In any case, if it is not in the backup cache, it has to be // re-read from storage result = (IndexNode) getBackupNodeCache().get(id); if (result != null) { // since the node was only found in the backup cache, we now // put it back into the general cache, since it may be // needed again soon getGeneralNodeCache().put(id, result); } } } return result; } void setRootNode(IndexBranchNode rootNode) { if (log.isLoggable(Level.FINE)) log.fine("old root node: " + this.rootNode); if (this.rootNode != null) { putInCaches(this.rootNode); } this.rootNode = rootNode; if (log.isLoggable(Level.FINE)) log.fine("new root node: " + this.rootNode); } private IndexLeafNode getNewestLeafNode() { newestLeafNode.startInvoke(); return newestLeafNode; } void setNewestLeafNode(IndexLeafNode newestLeafNode) { if (this.newestLeafNode != null) { putInCaches(this.newestLeafNode); } this.newestLeafNode = newestLeafNode; } StorageFactory getStorageFactory() { return storageFactory; } StreamFactory getStreamFactory() { return streamFactory; } private void setStorageFactory(StorageFactory storageFactory) { this.storageFactory = storageFactory; } private void setStreamFactory(StreamFactory streamFactory) { this.streamFactory = streamFactory; } private TrimmingCache getDirtyNodeCache() { return dirtyNodeCache; } private void setDirtyNodeCache(TrimmingCache dirtyNodeCache) { this.dirtyNodeCache = dirtyNodeCache; } /** * Keep in mind that dirty nodes may also be in this cache. */ private TrimmingCache getGeneralNodeCache() { return generalNodeCache; } private void setGeneralNodeCache(TrimmingCache generalNodeCache) { this.generalNodeCache = generalNodeCache; } private WeakReferenceCache getBackupNodeCache() { return backupNodeCache; } synchronized void serialize(IndexNode indexNode) { if (log.isLoggable(Level.FINER)) log.finer("putting indexnode " + indexNode.getNodeId() + " into serializer"); // Note that we MUST put dirty back to true if we take the node out of the serializer!!! indexNode.setDirty(false); getNodeSerializer().put(new Long(indexNode.getNodeId()), indexNode); } Serializer getNodeSerializer() { return nodeSerializer; } Deleter getDeleter() { return deleter; } private void setNodeSerializer(Serializer nodeSerializer) { this.nodeSerializer = nodeSerializer; } public Collection getPropertyInfos() { Collection result = new LinkedList(); result.add(INDEXSTREAMFACTORY); result.add(GENERALINDEXNODECACHE); result.add(DIRTYINDEXNODECACHE); result.add(MAXBRANCHNODESIZE); result.add(MAXLEAFNODESIZE); result.add(INDEXNODESTORAGEFACTORY); return result; } int getLeafNodeMergeReach() { return leafNodeMergeReach; } private void setLeafNodeMergeReach(int leafNodeMergeReach) { this.leafNodeMergeReach = leafNodeMergeReach; } int getBranchNodeMergeSize() { return branchNodeMergeSize; } private void setBranchNodeMergeSize(int branchNodeMergeSize) { this.branchNodeMergeSize = branchNodeMergeSize; } int getBranchNodeMergeReach() { return branchNodeMergeReach; } private void setBranchNodeMergeReach(int branchNodeMergeReach) { this.branchNodeMergeReach = branchNodeMergeReach; } void nodeBecameDirty(IndexNode indexNode) { getDirtyNodeCache().put(new Long(indexNode.getNodeId()), indexNode); } public String getPrefix() { return prefix; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -