tachyon.worker.block.BlockHeartbeatReporter Maven / Gradle / Ivy
/*
* Licensed to the University of California, Berkeley under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package tachyon.worker.block;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.Lists;
/**
* Represents the delta of the block store within one heartbeat period. For now, newly committed
* blocks do not pass through this master communication mechanism, instead it is synchronized
* through {@link tachyon.worker.block.BlockDataManager#commitBlock(long, long)}. This class is
* thread safe.
*/
public final class BlockHeartbeatReporter extends BlockStoreEventListenerBase {
/** Lock for operations on the removed and added block collections */
private final Object mLock;
/** List of blocks that were removed in the last heartbeat period */
private final List mRemovedBlocks;
/** Map of storage dirs to a list of blocks that were added in the last heartbeat period */
private final Map> mAddedBlocks;
public BlockHeartbeatReporter() {
mLock = new Object();
mRemovedBlocks = new ArrayList(100);
mAddedBlocks = new HashMap>(20);
}
/**
* Generates the report of the block store delta in the last heartbeat period. Calling this method
* marks the end of a period and the start of a new heartbeat period.
*
* @return the block store delta report for the last heartbeat period
*/
public BlockHeartbeatReport generateReport() {
synchronized (mLock) {
// Copy added and removed blocks
Map> addedBlocks = new HashMap>(mAddedBlocks);
List removedBlocks = new ArrayList(mRemovedBlocks);
// Clear added and removed blocks
mAddedBlocks.clear();
mRemovedBlocks.clear();
return new BlockHeartbeatReport(addedBlocks, removedBlocks);
}
}
@Override
public void onMoveBlockByClient(long sessionId, long blockId, BlockStoreLocation oldLocation,
BlockStoreLocation newLocation) {
Long storageDirId = newLocation.getStorageDirId();
synchronized (mLock) {
// Remove the block from our list of added blocks in this heartbeat, if it was added, to
// prevent adding the block twice.
removeBlockFromAddedBlocks(blockId);
// Add the block back with the new storagedir.
addBlockToAddedBlocks(blockId, storageDirId);
}
}
@Override
public void onRemoveBlockByClient(long sessionId, long blockId) {
synchronized (mLock) {
// Remove the block from list of added blocks, in case it was added in this heartbeat period.
removeBlockFromAddedBlocks(blockId);
// Add to the list of removed blocks in this heartbeat period.
if (!mRemovedBlocks.contains(blockId)) {
mRemovedBlocks.add(blockId);
}
}
}
@Override
public void onRemoveBlockByWorker(long sessionId, long blockId) {
synchronized (mLock) {
// Remove the block from list of added blocks, in case it was added in this heartbeat period.
removeBlockFromAddedBlocks(blockId);
// Add to the list of removed blocks in this heartbeat period.
if (!mRemovedBlocks.contains(blockId)) {
mRemovedBlocks.add(blockId);
}
}
}
@Override
public void onMoveBlockByWorker(long sessionId, long blockId, BlockStoreLocation oldLocation,
BlockStoreLocation newLocation) {
Long storageDirId = newLocation.getStorageDirId();
synchronized (mLock) {
// Remove the block from our list of added blocks in this heartbeat, if it was added, to
// prevent adding the block twice.
removeBlockFromAddedBlocks(blockId);
// Add the block back with the new storagedir.
addBlockToAddedBlocks(blockId, storageDirId);
}
}
/**
* Adds a block to the list of added blocks in this heartbeat period.
*
* @param blockId The id of the block to add
* @param storageDirId The storage directory id containing the block
*/
private void addBlockToAddedBlocks(long blockId, long storageDirId) {
if (mAddedBlocks.containsKey(storageDirId)) {
mAddedBlocks.get(storageDirId).add(blockId);
} else {
mAddedBlocks.put(storageDirId, Lists.newArrayList(blockId));
}
}
/**
* Removes the block from the added blocks map, if it exists.
*
* @param blockId The block to remove
*/
private void removeBlockFromAddedBlocks(long blockId) {
Iterator>> iterator = mAddedBlocks.entrySet().iterator();
while (iterator.hasNext()) {
Entry> entry = iterator.next();
List blockList = entry.getValue();
if (blockList.contains(blockId)) {
blockList.remove(blockId);
if (blockList.isEmpty()) {
iterator.remove();
}
// exit the loop when already find and remove blockId from mAddedBlocks
break;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy