/* * 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.client.file.policy; import alluxio.client.block.BlockWorkerInfo; import alluxio.client.block.policy.BlockLocationPolicy; import alluxio.client.block.policy.options.GetWorkerOptions; import alluxio.util.network.NetworkAddressUtils; import alluxio.wire.WorkerNetAddress; import com.google.common.base.Objects; import com.google.common.collect.Lists; import java.util.Collections; import java.util.List; import javax.annotation.concurrent.ThreadSafe; /** * A policy that returns local host first, and if the local worker doesn't have enough availability, * it randomly picks a worker from the active workers list for each block write. */ // TODO(peis): Move the BlockLocationPolicy implementation to alluxio.client.block.policy. @ThreadSafe public final class LocalFirstPolicy implements FileWriteLocationPolicy, BlockLocationPolicy { private String mLocalHostName; /** * Constructs a {@link LocalFirstPolicy}. */ public LocalFirstPolicy() { mLocalHostName = NetworkAddressUtils.getClientHostName(); } @Override public WorkerNetAddress getWorkerForNextBlock(Iterable<BlockWorkerInfo> workerInfoList, long blockSizeBytes) { // first try the local host for (BlockWorkerInfo workerInfo : workerInfoList) { if (workerInfo.getNetAddress().getHost().equals(mLocalHostName) && workerInfo.getCapacityBytes() >= blockSizeBytes) { return workerInfo.getNetAddress(); } } // otherwise randomly pick a worker that has enough availability List<BlockWorkerInfo> shuffledWorkers = Lists.newArrayList(workerInfoList); Collections.shuffle(shuffledWorkers); for (BlockWorkerInfo workerInfo : workerInfoList) { if (workerInfo.getCapacityBytes() >= blockSizeBytes) { return workerInfo.getNetAddress(); } } return null; } @Override public WorkerNetAddress getWorker(GetWorkerOptions options) { return getWorkerForNextBlock(options.getBlockWorkerInfos(), options.getBlockSize()); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof LocalFirstPolicy)) { return false; } LocalFirstPolicy that = (LocalFirstPolicy) o; return Objects.equal(mLocalHostName, that.mLocalHostName); } @Override public int hashCode() { return Objects.hashCode(mLocalHostName); } @Override public String toString() { return Objects.toStringHelper(this) .add("localHostName", mLocalHostName) .toString(); } }