/**
* Licensed to the Apache Software Foundation (ASF) 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 io.hops.transaction.context;
import com.google.common.collect.Lists;
import io.hops.exception.StorageCallPreventedException;
import io.hops.exception.StorageException;
import io.hops.exception.TransactionContextException;
import io.hops.metadata.common.FinderType;
import io.hops.metadata.hdfs.dal.ReplicaDataAccess;
import io.hops.metadata.hdfs.entity.Replica;
import io.hops.transaction.lock.TransactionLocks;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class ReplicaContext
extends BaseReplicaContext<BlockPK.ReplicaPK, Replica> {
private ReplicaDataAccess dataAccess;
public ReplicaContext(ReplicaDataAccess dataAccess) {
this.dataAccess = dataAccess;
}
@Override
public void update(Replica replica)
throws TransactionContextException {
super.update(replica);
if(isLogDebugEnabled()) {
log("updated-replica", "bid", replica.getBlockId(), "sid",
replica.getStorageId());
}
}
@Override
public void remove(Replica replica)
throws TransactionContextException {
super.remove(replica);
if(isLogDebugEnabled()) {
log("removed-replica", "bid", replica.getBlockId(), "sid",
replica.getStorageId());
}
}
@Override
public void prepare(TransactionLocks tlm)
throws TransactionContextException, StorageException {
dataAccess.prepare(getRemoved(), getAdded(), getModified());
}
@Override
public Collection<Replica> findList(FinderType<Replica> finder,
Object... params) throws TransactionContextException, StorageException {
Replica.Finder iFinder = (Replica.Finder) finder;
switch (iFinder) {
case ByBlockIdAndINodeId:
return findByBlockId(iFinder, params);
case ByINodeId:
return findByINodeId(iFinder, params);
case ByINodeIds:
return findyByINodeIds(iFinder, params);
}
throw new RuntimeException(UNSUPPORTED_FINDER);
}
@Override
public Replica find(FinderType<Replica> finder,
Object... params) throws TransactionContextException, StorageException {
Replica.Finder iFinder = (Replica.Finder) finder;
switch (iFinder) {
case ByBlockIdAndStorageId:
return findByPK(iFinder, params);
}
throw new RuntimeException(UNSUPPORTED_FINDER);
}
@Override
BlockPK.ReplicaPK getKey(Replica hopReplica) {
return new BlockPK.ReplicaPK(hopReplica.getBlockId(),
hopReplica.getInodeId(), hopReplica.getStorageId());
}
@Override
Replica cloneEntity(Replica hopReplica) {
return cloneEntity(hopReplica, hopReplica.getInodeId());
}
@Override
Replica cloneEntity(Replica hopReplica, int inodeId) {
return new Replica(hopReplica.getStorageId(), hopReplica.getBlockId(),
inodeId);
}
@Override
protected boolean snapshotChanged() {
return !getAdded().isEmpty() || !getModified().isEmpty();
}
private Replica findByPK(Replica.Finder iFinder,
Object[] params) {
final long blockId = (Long) params[0];
final int storageId = (Integer) params[1];
Replica result = null;
List<Replica> replicas = getByBlock(blockId);
if (replicas != null) {
for (Replica replica : replicas) {
if (replica != null) {
if (replica.getStorageId() == storageId) {
result = replica;
break;
}
}
}
}
hit(iFinder, result, "bid", blockId, "sid", storageId);
return result;
}
private List<Replica> findByBlockId(Replica.Finder iFinder,
Object[] params) throws StorageCallPreventedException, StorageException {
final long blockId = (Long) params[0];
final int inodeId = (Integer) params[1];
List<Replica> results = null;
if (containsByBlock(blockId) || containsByINode(inodeId)) {
results = getByBlock(blockId);
hit(iFinder, results, "bid", blockId);
} else {
aboutToAccessStorage(iFinder, params);
results = dataAccess.findReplicasById(blockId, inodeId);
gotFromDB(new BlockPK(blockId), results);
miss(iFinder, results, "bid", blockId);
}
return results;
}
private List<Replica> findByINodeId(Replica.Finder iFinder,
Object[] params) throws StorageCallPreventedException, StorageException {
final int inodeId = (Integer) params[0];
List<Replica> results = null;
if (containsByINode(inodeId)) {
results = getByINode(inodeId);
hit(iFinder, results, "inodeid", inodeId);
} else {
aboutToAccessStorage(iFinder, params);
results = dataAccess.findReplicasByINodeId(inodeId);
gotFromDB(new BlockPK(inodeId), results);
miss(iFinder, results, "inodeid", inodeId);
}
return results;
}
private List<Replica> findyByINodeIds(Replica.Finder iFinder,
Object[] params) throws StorageCallPreventedException, StorageException {
int[] ids = (int[]) params[0];
aboutToAccessStorage(iFinder, params);
List<Replica> results = dataAccess.findReplicasByINodeIds(ids);
gotFromDB(BlockPK.ReplicaPK.getKeys(ids), results);
miss(iFinder, results, "inodeIds", Arrays.toString(ids));
return results;
}
}