/** * 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 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.InvalidateBlockDataAccess; import io.hops.metadata.hdfs.entity.InvalidatedBlock; import io.hops.transaction.lock.TransactionLocks; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; public class InvalidatedBlockContext extends BaseReplicaContext<BlockPK.ReplicaPK, InvalidatedBlock> { private final InvalidateBlockDataAccess<InvalidatedBlock> dataAccess; private boolean allInvBlocksRead = false; public InvalidatedBlockContext(InvalidateBlockDataAccess dataAccess) { this.dataAccess = dataAccess; } @Override public void update(InvalidatedBlock hopInvalidatedBlock) throws TransactionContextException { super.update(hopInvalidatedBlock); if(isLogDebugEnabled()) { log("added-invblock", "bid", hopInvalidatedBlock.getBlockId(), "sid", hopInvalidatedBlock.getStorageId()); } } @Override public void remove(InvalidatedBlock hopInvalidatedBlock) throws TransactionContextException { super.remove(hopInvalidatedBlock); if(isLogDebugEnabled()) { log("removed-invblock", "bid", hopInvalidatedBlock.getBlockId(), "sid", hopInvalidatedBlock.getStorageId()); } } @Override public InvalidatedBlock find(FinderType<InvalidatedBlock> finder, Object... params) throws TransactionContextException, StorageException { InvalidatedBlock.Finder iFinder = (InvalidatedBlock.Finder) finder; switch (iFinder) { case ByBlockIdStorageIdAndINodeId: return findByPrimaryKey(iFinder, params); } throw new RuntimeException(UNSUPPORTED_FINDER); } @Override public Collection<InvalidatedBlock> findList( FinderType<InvalidatedBlock> finder, Object... params) throws TransactionContextException, StorageException { InvalidatedBlock.Finder iFinder = (InvalidatedBlock.Finder) finder; switch (iFinder) { case ByBlockIdAndINodeId: return findByBlockId(iFinder, params); case ByINodeId: return findByINodeId(iFinder, params); case All: return findAll(iFinder); case ByStorageId: return findByStorageId(iFinder, params); case ByINodeIds: return findByINodeIds(iFinder, params); } throw new RuntimeException(UNSUPPORTED_FINDER); } @Override public void prepare(TransactionLocks tlm) throws TransactionContextException, StorageException { dataAccess.prepare(getRemoved(), getAdded(), getModified()); } @Override public void clear() throws TransactionContextException { super.clear(); allInvBlocksRead = false; } @Override InvalidatedBlock cloneEntity(InvalidatedBlock hopInvalidatedBlock) { return cloneEntity(hopInvalidatedBlock, hopInvalidatedBlock.getInodeId()); } @Override InvalidatedBlock cloneEntity(InvalidatedBlock hopInvalidatedBlock, int inodeId) { return new InvalidatedBlock(hopInvalidatedBlock.getStorageId(), hopInvalidatedBlock.getBlockId(), inodeId); } @Override BlockPK.ReplicaPK getKey(InvalidatedBlock hopInvalidatedBlock) { return new BlockPK.ReplicaPK(hopInvalidatedBlock.getBlockId(), hopInvalidatedBlock.getInodeId(), hopInvalidatedBlock.getStorageId()); } @Override protected boolean snapshotChanged() { return !getRemoved().isEmpty(); } private InvalidatedBlock findByPrimaryKey(InvalidatedBlock.Finder iFinder, Object[] params) throws StorageCallPreventedException, StorageException { final long blockId = (Long) params[0]; final int storageId = (Integer) params[1]; final int inodeId = (Integer) params[2]; final BlockPK.ReplicaPK key = new BlockPK.ReplicaPK(blockId, inodeId, storageId); InvalidatedBlock result = null; if (contains(key) || containsByBlock(blockId) || containsByINode(inodeId)) { result = get(key); hit(iFinder, result, "bid", blockId, "sid", storageId, "inodeId", inodeId); } else { aboutToAccessStorage(iFinder, params); result = dataAccess.findInvBlockByPkey(blockId, storageId, inodeId); gotFromDB(key, result); miss(iFinder, result, "bid", blockId, "sid", storageId, "inodeId", inodeId); } return result; } private List<InvalidatedBlock> findByBlockId(InvalidatedBlock.Finder iFinder, Object[] params) throws StorageCallPreventedException, StorageException { final long blockId = (Long) params[0]; final int inodeId = (Integer) params[1]; List<InvalidatedBlock> result = null; if (containsByBlock(blockId) || containsByINode(inodeId)) { result = getByBlock(blockId); hit(iFinder, result, "bid", blockId, "inodeId", inodeId); } else { aboutToAccessStorage(iFinder, params); result = dataAccess.findInvalidatedBlocksByBlockId(blockId, inodeId); Collections.sort(result); gotFromDB(new BlockPK(blockId), result); miss(iFinder, result, "bid", blockId, "inodeId", inodeId); } return result; } private List<InvalidatedBlock> findByINodeId(InvalidatedBlock.Finder iFinder, Object[] params) throws StorageCallPreventedException, StorageException { final int inodeId = (Integer) params[0]; List<InvalidatedBlock> result = null; if (containsByINode(inodeId)) { result = getByINode(inodeId); hit(iFinder, result, "inodeId", inodeId); } else { aboutToAccessStorage(iFinder, params); result = dataAccess.findInvalidatedBlocksByINodeId(inodeId); gotFromDB(new BlockPK(inodeId), result); miss(iFinder, result, "inodeId", inodeId); } return result; } private List<InvalidatedBlock> findAll(InvalidatedBlock.Finder iFinder) throws StorageCallPreventedException, StorageException { List<InvalidatedBlock> result = null; if (allInvBlocksRead) { result = new ArrayList<InvalidatedBlock>(getAll()); hit(iFinder, result); } else { aboutToAccessStorage(iFinder); result = dataAccess.findAllInvalidatedBlocks(); gotFromDB(result); allInvBlocksRead = true; miss(iFinder, result); } return result; } private List<InvalidatedBlock> findByStorageId( InvalidatedBlock.Finder iFinder, Object[] params) throws StorageCallPreventedException, StorageException { final long[] blockIds = (long[]) params[0]; final int[] inodeIds = (int[]) params[1]; final int sid = (Integer) params[2]; aboutToAccessStorage(iFinder, params); List<InvalidatedBlock> result = dataAccess.findInvalidatedBlockByStorageId(sid); gotFromDB(BlockPK.ReplicaPK.getKeys(blockIds, inodeIds, sid), result); miss(iFinder, result, "bids", Arrays.toString(blockIds), "inodeIds", Arrays.toString(inodeIds), "sid", sid); return result; } private List<InvalidatedBlock> findByINodeIds(InvalidatedBlock.Finder iFinder, Object[] params) throws StorageCallPreventedException, StorageException { final int[] inodeIds = (int[]) params[0]; aboutToAccessStorage(iFinder, params); List<InvalidatedBlock> result = dataAccess.findInvalidatedBlocksByINodeIds(inodeIds); gotFromDB(BlockPK.ReplicaPK.getKeys(inodeIds), result); miss(iFinder, result, "inodeIds", Arrays.toString(inodeIds)); return result; } }