/*
* The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
* (the "License"). You may not use this work except in compliance with the License, which is
* available at www.apache.org/licenses/LICENSE-2.0
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied, as more fully set forth in the License.
*
* See the NOTICE file distributed with this work for information regarding copyright ownership.
*/
package alluxio.worker.block.meta;
import alluxio.worker.block.BlockMetadataManagerView;
import alluxio.worker.block.BlockStoreLocation;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.concurrent.NotThreadSafe;
/**
* This class is a wrapper of {@link StorageDir} to provide more limited access and a filtered list
* of blocks.
*/
@NotThreadSafe
public final class StorageDirView {
/** The {@link StorageDir} this view is derived from. */
private final StorageDir mDir;
/** The {@link StorageTierView} this view under. */
private final StorageTierView mTierView;
/** The {@link BlockMetadataManagerView} this view is associated with. */
private final BlockMetadataManagerView mManagerView;
// The below data structures are used by the evictor to mark blocks to move in/out during
// generating an eviction plan.
private final Set<Long> mBlocksToMoveIn = new HashSet<>();
private final Set<Long> mBlocksToMoveOut = new HashSet<>();
private long mBlocksToMoveInSize = 0L;
private long mBlocksToMoveOutSize = 0L;
/**
* Creates a {@link StorageDirView} using the actual {@link StorageDir} and the associated
* {@link BlockMetadataManagerView}.
*
* @param dir which the dirView is constructed from
* @param tierView which the dirView is under
* @param managerView which the dirView is associated with
*/
public StorageDirView(StorageDir dir, StorageTierView tierView,
BlockMetadataManagerView managerView) {
mDir = Preconditions.checkNotNull(dir);
mTierView = Preconditions.checkNotNull(tierView);
mManagerView = Preconditions.checkNotNull(managerView);
}
/**
* Gets the index of this Dir.
*
* @return index of the dir
*/
public int getDirViewIndex() {
return mDir.getDirIndex();
}
/**
* Gets a filtered list of block metadata, for blocks that are neither pinned or being blocked.
*
* @return a list of metadata for all evictable blocks
*/
public List<BlockMeta> getEvictableBlocks() {
List<BlockMeta> filteredList = new ArrayList<>();
for (BlockMeta blockMeta : mDir.getBlocks()) {
long blockId = blockMeta.getBlockId();
if (mManagerView.isBlockEvictable(blockId)) {
filteredList.add(blockMeta);
}
}
return filteredList;
}
/**
* Gets capacity bytes for this dir.
*
* @return capacity bytes for this dir
*/
public long getCapacityBytes() {
return mDir.getCapacityBytes();
}
/**
* Gets available bytes for this dir.
*
* @return available bytes for this dir
*/
public long getAvailableBytes() {
return mDir.getAvailableBytes() + mBlocksToMoveOutSize - mBlocksToMoveInSize;
}
/**
* Gets committed bytes for this dir. This includes all blocks, locked, pinned, committed etc.
*
* @return committed bytes for this dir
*/
public long getCommittedBytes() {
return mDir.getCommittedBytes();
}
/**
* Gets evictable bytes for this dir, i.e., the total bytes of total evictable blocks.
*
* @return evictable bytes for this dir
*/
public long getEvitableBytes() {
long bytes = 0;
for (BlockMeta blockMeta : mDir.getBlocks()) {
long blockId = blockMeta.getBlockId();
if (mManagerView.isBlockEvictable(blockId)) {
bytes += blockMeta.getBlockSize();
}
}
return bytes;
}
/**
* Clears all marks about blocks to move in/out in this view.
*/
public void clearBlockMarks() {
mBlocksToMoveIn.clear();
mBlocksToMoveOut.clear();
mBlocksToMoveInSize = mBlocksToMoveOutSize = 0L;
}
/**
* Creates a {@link TempBlockMeta} given sessionId, blockId, and initialBlockSize.
*
* @param sessionId of the owning session
* @param blockId of the new block
* @param initialBlockSize of the new block
* @return a new {@link TempBlockMeta} under the underlying directory
*/
public TempBlockMeta createTempBlockMeta(long sessionId, long blockId, long initialBlockSize) {
return new TempBlockMeta(sessionId, blockId, initialBlockSize, mDir);
}
/**
* @return parent tier view
*/
public StorageTierView getParentTierView() {
return mTierView;
}
/**
* Returns an indication whether the given block is marked to be moved out.
*
* @param blockId the block ID
* @return whether the block is marked to be moved out
*/
public boolean isMarkedToMoveOut(long blockId) {
return mBlocksToMoveOut.contains(blockId);
}
/**
* Marks a block to move into this dir view, which is used by the evictor.
*
* @param blockId the Id of the block
* @param blockSize the block size
*/
public void markBlockMoveIn(long blockId, long blockSize) {
if (mBlocksToMoveIn.add(blockId)) {
mBlocksToMoveInSize += blockSize;
}
}
/**
* Marks a block to move out of this dir view, which is used by the evictor.
*
* @param blockId the Id of the block
* @param blockSize the block size
*/
public void markBlockMoveOut(long blockId, long blockSize) {
if (mBlocksToMoveOut.add(blockId)) {
mBlocksToMoveOutSize += blockSize;
}
}
/**
* Creates a {@link BlockStoreLocation} for this directory view. Redirecting to
* {@link StorageDir#toBlockStoreLocation}
*
* @return {@link BlockStoreLocation} created
*/
public BlockStoreLocation toBlockStoreLocation() {
return mDir.toBlockStoreLocation();
}
}