/* * Copyright(C) 2010 Alibaba Group Holding Limited All rights reserved. Licensed 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 com.alibaba.doris.dataserver.migrator.task; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; import org.jboss.netty.util.internal.ConcurrentHashMap; import com.alibaba.doris.common.route.MigrationRoutePair; /** * ProgressComputer * * @author Raymond He ( He Kun), raymond.he.kk@gmail.com * @since 1.0 2011-6-23 */ public class ProgressComputer { private Map<String, ProgressUnit> migrationProgressMap = new ConcurrentHashMap<String, ProgressUnit>(); private List<MigrationRoutePair> migrationRoutePairs; private int finishCount; private int grossProgress = -1; private ReentrantLock reentrantLock = new ReentrantLock(); public ProgressComputer(List<MigrationRoutePair> migrationRoutePairs) { this.migrationRoutePairs = migrationRoutePairs; for (int i = 0; i < migrationRoutePairs.size(); i++) { MigrationRoutePair routePair = migrationRoutePairs.get(i); String targetId = routePair.getTargetPhysicalId(); ProgressUnit unit = migrationProgressMap.get(routePair.getTargetPhysicalId()); if (unit == null) { unit = new ProgressUnit(); unit.setTargetNodeId(targetId); } unit.getMigrateVNodes().add(routePair.getVnode()); migrationProgressMap.put(targetId, unit); } } /** * 做完一个虚拟节点的迁移 * * @param targetNodeId * @param vnodeId */ public synchronized boolean completeOneVNode(String targetNodeId, Integer vnodeId) { reentrantLock.lock(); try { /* 源节点的总进度 */ finishCount++; int newGrossProgress = (finishCount * 100) / migrationRoutePairs.size(); ProgressUnit unit = migrationProgressMap.get(targetNodeId); int p = unit.getProgress(); int newProgress = p + (1 * 100) / unit.getMigrateVNodes().size(); unit.setProgress(newProgress); unit.setLastTime(System.currentTimeMillis()); if (newGrossProgress > this.grossProgress) { // true: need to notify new progress this.grossProgress = newGrossProgress; return true; } else { this.grossProgress = newGrossProgress; return false; } }finally { reentrantLock.unlock(); } } public int getGrossProgress() { reentrantLock.lock(); try { return grossProgress; }finally { reentrantLock.unlock(); } } public int getFinishCount() { return finishCount; } /** * 迁移进度 * * @param tNodeId 目标节点Id * @return */ public int getProgressOfTarget(String tNodeId) { reentrantLock.lock(); try { ProgressUnit unit = migrationProgressMap.get(tNodeId); return unit.getProgress(); }finally { reentrantLock.unlock(); } } public static class ProgressUnit { private String targetNodeId; private List<Integer> migrateVNodes = new ArrayList<Integer>(); private int progress; private long lastTime; public String getTargetNodeId() { return targetNodeId; } public void setTargetNodeId(String targetNodeId) { this.targetNodeId = targetNodeId; } public List<Integer> getMigrateVNodes() { return migrateVNodes; } public void setMigrateVNodes(List<Integer> migrateVNodes) { this.migrateVNodes = migrateVNodes; } public int getProgress() { return progress; } public void setProgress(int progress) { this.progress = progress; } public void setLastTime(long lastTime) { this.lastTime = lastTime; } public long getLastTime() { return lastTime; } @Override public String toString() { StringBuilder s = new StringBuilder(); return s.append("[ProgressUnit:").append("targetNodeId=").append(targetNodeId).append(",").append( "progress=").append( progress).append( "]").toString(); } } }