/** * 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.lock; import io.hops.metadata.common.entity.Variable; import io.hops.metadata.hdfs.entity.INodeIdentifier; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hdfs.DFSConfigKeys; import org.apache.hadoop.hdfs.server.namenode.NameNode; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class LockFactory { private final static LockFactory instance = new LockFactory(); public static enum BLK { /** * Replica */ RE, /** * CorruptReplica */ CR, /** * ExcessReplica */ ER, /** * UnderReplicated */ UR, /** * ReplicaUnderConstruction */ UC, /** * InvalidatedBlock */ IV, /** * PendingBlock */ PE } private LockFactory() { } public static LockFactory getInstance() { return instance; } public Lock getBlockChecksumLock(String target, int blockIndex) { return new BlockChecksumLock(target, blockIndex); } public Lock getBlockLock() { return new BlockLock(); } public Lock getBlockLock(long blockId, INodeIdentifier inode) { return new BlockLock(blockId, inode); } public Lock getReplicaLock() { return new BlockRelatedLock(Lock.Type.Replica); } public Lock getCorruptReplicaLock() { return new BlockRelatedLock(Lock.Type.CorruptReplica); } public Lock getExcessReplicaLock() { return new BlockRelatedLock(Lock.Type.ExcessReplica); } public Lock getReplicatUnderConstructionLock() { return new BlockRelatedLock(Lock.Type.ReplicaUnderConstruction); } public Lock getInvalidatedBlockLock() { return new BlockRelatedLock(Lock.Type.InvalidatedBlock); } public Lock getUnderReplicatedBlockLock() { return new BlockRelatedLock(Lock.Type.UnderReplicatedBlock); } public Lock getPendingBlockLock() { return new BlockRelatedLock(Lock.Type.PendingBlock); } public Lock getSqlBatchedBlocksLock() { return new SqlBatchedBlocksLock(); } public Lock getSqlBatchedReplicasLock() { return new SqlBatchedBlocksRelatedLock(Lock.Type.Replica); } public Lock getSqlBatchedCorruptReplicasLock() { return new SqlBatchedBlocksRelatedLock(Lock.Type.CorruptReplica); } public Lock getSqlBatchedExcessReplicasLock() { return new SqlBatchedBlocksRelatedLock(Lock.Type.ExcessReplica); } public Lock getSqlBatchedReplicasUnderConstructionLock() { return new SqlBatchedBlocksRelatedLock(Lock.Type.ReplicaUnderConstruction); } public Lock getSqlBatchedInvalidatedBlocksLock() { return new SqlBatchedBlocksRelatedLock(Lock.Type.InvalidatedBlock); } public Lock getSqlBatchedUnderReplicatedBlocksLock() { return new SqlBatchedBlocksRelatedLock(Lock.Type.UnderReplicatedBlock); } public Lock getSqlBatchedPendingBlocksLock() { return new SqlBatchedBlocksRelatedLock(Lock.Type.PendingBlock); } public Lock getIndividualBlockLock(long blockId, INodeIdentifier inode) { return new IndividualBlockLock(blockId, inode); } public Lock getBatchedINodesLock(List<INodeIdentifier> inodeIdentifiers) { return new BatchedINodeLock(inodeIdentifiers); } public Lock getIndividualINodeLock( TransactionLockTypes.INodeLockType lockType, INodeIdentifier inodeIdentifier, boolean readUpPathInodes) { return new IndividualINodeLock(lockType, inodeIdentifier, readUpPathInodes); } public Lock getIndividualINodeLock( TransactionLockTypes.INodeLockType lockType, INodeIdentifier inodeIdentifier) { return new IndividualINodeLock(lockType, inodeIdentifier); } public Lock getINodeLock(boolean skipReadingQuotaAttr, NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, boolean resolveLink, boolean ignoreLocalSubtreeLocks, String... paths) { return new INodeLock(lockType, resolveType, resolveLink, ignoreLocalSubtreeLocks, skipReadingQuotaAttr, nameNode.getId(), nameNode.getActiveNameNodes().getActiveNodes(), paths); } public Lock getINodeLock(NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, boolean resolveLink, boolean ignoreLocalSubtreeLocks, String... paths) { return new INodeLock(lockType, resolveType, resolveLink, ignoreLocalSubtreeLocks, false, nameNode.getId(), nameNode.getActiveNameNodes().getActiveNodes(), paths); } public Lock getINodeLock(NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, boolean resolveLink, String... paths) { return new INodeLock(false, lockType, resolveType, resolveLink, nameNode.getActiveNameNodes().getActiveNodes(), paths); } public Lock getINodeLock(NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, String... paths) { return new INodeLock(lockType, resolveType, nameNode.getActiveNameNodes().getActiveNodes(), paths); } public Lock getINodeLock(boolean skipReadingQuotaAttr, NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, String... paths) { return new INodeLock(lockType, resolveType, true, false, skipReadingQuotaAttr, nameNode.getId(), nameNode.getActiveNameNodes().getActiveNodes(), paths); } public Lock getINodeLock(boolean skipReadingQuotaAttr, NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, boolean resolveLink, String... paths) { return new INodeLock(lockType, resolveType, resolveLink, false, skipReadingQuotaAttr, nameNode.getId(), nameNode.getActiveNameNodes().getActiveNodes(), paths); } public Lock getRenameINodeLock(NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, boolean ignoreLocalSubtreeLocks, String src, String dst) { return new RenameINodeLock(lockType, resolveType, ignoreLocalSubtreeLocks, nameNode.getId(), nameNode.getActiveNameNodes().getActiveNodes(), src, dst); } public Lock getRenameINodeLock(NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, String src, String dst) { return new RenameINodeLock(lockType, resolveType, nameNode.getActiveNameNodes().getActiveNodes(), src, dst); } public Lock getLegacyRenameINodeLock(NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, boolean ignoreLocalSubtreeLocks, String src, String dst) { return new RenameINodeLock(lockType, resolveType, ignoreLocalSubtreeLocks, nameNode.getId(), nameNode.getActiveNameNodes().getActiveNodes(), src, dst, true); } public Lock getLegacyRenameINodeLock(boolean skipReadingQuotaAttr,NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, boolean ignoreLocalSubtreeLocks, String src, String dst) { return new RenameINodeLock(skipReadingQuotaAttr,lockType, resolveType, ignoreLocalSubtreeLocks, nameNode.getId(), nameNode.getActiveNameNodes().getActiveNodes(), src, dst, true); } public Lock getLegacyRenameINodeLock(boolean skipReadingQuotaAttr,NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, String src, String dst) { return new RenameINodeLock(skipReadingQuotaAttr, lockType, resolveType, nameNode.getActiveNameNodes().getActiveNodes(), src, dst, true); } public Lock getLegacyRenameINodeLock(NameNode nameNode, TransactionLockTypes.INodeLockType lockType, TransactionLockTypes.INodeResolveType resolveType, String src, String dst) { return new RenameINodeLock(lockType, resolveType, nameNode.getActiveNameNodes().getActiveNodes(), src, dst, true); } public Lock getLeaseLock(TransactionLockTypes.LockType lockType, String leaseHolder) { return new LeaseLock(lockType, leaseHolder); } public Lock getLeaseLock(TransactionLockTypes.LockType lockType) { return new LeaseLock(lockType); } public Lock getLeasePathLock(TransactionLockTypes.LockType lockType, int expectedCount) { return new LeasePathLock(lockType, expectedCount); } public Lock getLeasePathLock(TransactionLockTypes.LockType lockType) { return new LeasePathLock(lockType); } public Lock getLeasePathLock(TransactionLockTypes.LockType lockType, String src) { return new LeasePathLock(lockType, src); } public Lock getNameNodeLeaseLock(TransactionLockTypes.LockType lockType) { return new NameNodeLeaseLock(lockType); } public Lock getQuotaUpdateLock(boolean includeChildren, String... targets) { return new QuotaUpdateLock(includeChildren, targets); } public Lock getQuotaUpdateLock(String... targets) { return new QuotaUpdateLock(targets); } public Lock getVariableLock(Variable.Finder[] finders, TransactionLockTypes.LockType[] lockTypes) { assert finders.length == lockTypes.length; VariablesLock lock = new VariablesLock(); for (int i = 0; i < finders.length; i++) { lock.addVariable(finders[i], lockTypes[i]); } return lock; } public Lock getVariableLock(Variable.Finder finder, TransactionLockTypes.LockType lockType) { VariablesLock lock = new VariablesLock(); lock.addVariable(finder, lockType); return lock; } public List<Lock> getBlockReportingLocks(long[] blockIds, int[] inodeIds, long[] unresolvedBlks, int storageId) { ArrayList<Lock> list = new ArrayList(3); list.add(new BatchedBlockLock(blockIds,inodeIds, unresolvedBlks)); //list.add(new BatchedBlocksRelatedLock.BatchedInvalidatedBlocksLock(storageId)); return list; } public Lock getEncodingStatusLock(TransactionLockTypes.LockType lockType, String... targets) { return new BaseEncodingStatusLock.EncodingStatusLock(lockType, targets); } public Lock getEncodingStatusLock(boolean includeChildren, TransactionLockTypes.LockType lockType, String... targets) { return new BaseEncodingStatusLock.EncodingStatusLock(includeChildren, lockType, targets); } public Lock getIndivdualEncodingStatusLock( TransactionLockTypes.LockType lockType, int inodeId) { return new BaseEncodingStatusLock.IndividualEncodingStatusLock(lockType, inodeId); } public Lock getSubTreeOpsLock(TransactionLockTypes.LockType lockType, String pathPrefix) { return new SubTreeOpLock(lockType, pathPrefix); } public Collection<Lock> getBlockRelated(BLK... relatedBlks) { ArrayList<Lock> list = new ArrayList(); for (BLK b : relatedBlks) { switch (b) { case RE: list.add(getReplicaLock()); break; case CR: list.add(getCorruptReplicaLock()); break; case IV: list.add(getInvalidatedBlockLock()); break; case PE: list.add(getPendingBlockLock()); break; case UC: list.add(getReplicatUnderConstructionLock()); break; case UR: list.add(getUnderReplicatedBlockLock()); break; case ER: list.add(getExcessReplicaLock()); break; } } return list; } public Collection<Lock> getSqlBatchedBlocksRelated(BLK... relatedBlks) { ArrayList<Lock> list = new ArrayList(); for (BLK b : relatedBlks) { switch (b) { case RE: list.add(getSqlBatchedReplicasLock()); break; case CR: list.add(getSqlBatchedCorruptReplicasLock()); break; case IV: list.add(getSqlBatchedInvalidatedBlocksLock()); break; case PE: list.add(getSqlBatchedInvalidatedBlocksLock()); break; case UC: list.add(getSqlBatchedReplicasUnderConstructionLock()); break; case UR: list.add(getUnderReplicatedBlockLock()); break; case ER: list.add(getSqlBatchedExcessReplicasLock()); break; } } return list; } public Lock getLastTwoBlocksLock(String src){ return new LastTwoBlocksLock(src); } public void setConfiguration(Configuration conf) { BaseINodeLock.enableSetPartitionKey( conf.getBoolean(DFSConfigKeys.DFS_SET_PARTITION_KEY_ENABLED, DFSConfigKeys.DFS_SET_PARTITION_KEY_ENABLED_DEFAULT)); BaseINodeLock.enableSetRandomPartitionKey(conf.getBoolean(DFSConfigKeys .DFS_SET_RANDOM_PARTITION_KEY_ENABLED, DFSConfigKeys .DFS_SET_RANDOM_PARTITION_KEY_ENABLED_DEFAULT)); BaseINodeLock.setDefaultLockType(getPrecedingPathLockType(conf)); } private TransactionLockTypes.INodeLockType getPrecedingPathLockType( Configuration conf) { String val = conf.get(DFSConfigKeys.DFS_STORAGE_ANCESTOR_LOCK_TYPE, DFSConfigKeys.DFS_STORAGE_ANCESTOR_LOCK_TYPE_DEFAULT); if (val.compareToIgnoreCase("READ") == 0) { return TransactionLockTypes.INodeLockType.READ; } else if (val.compareToIgnoreCase("READ_COMMITTED") == 0) { return TransactionLockTypes.INodeLockType.READ_COMMITTED; } else { throw new IllegalStateException( "Critical Parameter is not defined. Set " + DFSConfigKeys.DFS_STORAGE_ANCESTOR_LOCK_TYPE); } } }