/**
 * 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 org.apache.hadoop.hdfs.server.datanode;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/*
 * This class is a container of multiple thread pools, each for a volume,
 * so that we can schedule async disk operations easily.
 * 
 * Examples of async disk operations are deletion of block files in FSDataset.
 * We don't want to create a new thread for each of the deletion request, and
 * we don't want to do all deletions in the heartbeat thread since deletion
 * can be slow, and we don't want to use a single thread pool because that
 * is inefficient when we have more than 1 volume.  AsyncDiskService is the
 * solution for these.
 * 
 * This class is used inside FSDataset.
 * 
 * In the future, we should extract AsyncDiskService and put it into common.
 * The FSDataset-specific logic should reside here. 
 */
class FSDatasetAsyncDiskService {
  
  public static final Log LOG = LogFactory.getLog(FSDatasetAsyncDiskService.class);
  
  // ThreadPool core pool size
  private static final int CORE_THREADS_PER_VOLUME = 1;
  // ThreadPool maximum pool size
  private static final int MAXIMUM_THREADS_PER_VOLUME = 4;
  // ThreadPool keep-alive time for threads over core pool size
  private static final long THREADS_KEEP_ALIVE_SECONDS = 60; 
  
  private final ThreadGroup threadGroup = new ThreadGroup("async disk service");
  
  private HashMap<File, ThreadPoolExecutor> executors
      = new HashMap<File, ThreadPoolExecutor>();
  
  /**
   * Create a AsyncDiskServices with a set of volumes (specified by their
   * root directories).
   * 
   * The AsyncDiskServices uses one ThreadPool per volume to do the async
   * disk operations.
   * 
   * @param volumes The roots of the data volumes.
   */
  FSDatasetAsyncDiskService(File[] volumes) {

    // Create one ThreadPool per volume
    for (int v = 0 ; v < volumes.length; v++) {
      final File vol = volumes[v];
      ThreadFactory threadFactory = new ThreadFactory() {
          int counter = 0;

          @Override
          public Thread newThread(Runnable r) {
            int thisIndex;
            synchronized (this) {
              thisIndex = counter++;
            }
            Thread t = new Thread(threadGroup, r);
            t.setName("Async disk worker #" + thisIndex +
                      " for volume " + vol);
            return t;
          }
        };

      ThreadPoolExecutor executor = new ThreadPoolExecutor(
          CORE_THREADS_PER_VOLUME, MAXIMUM_THREADS_PER_VOLUME, 
          THREADS_KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, 
          new LinkedBlockingQueue<Runnable>(), threadFactory);

      // This can reduce the number of running threads
      executor.allowCoreThreadTimeOut(true);
      executors.put(vol, executor);
    }
    
  }
  
  /**
   * Execute the task sometime in the future, using ThreadPools.
   */
  synchronized void execute(File root, Runnable task) {
    if (executors == null) {
      throw new RuntimeException("AsyncDiskService is already shutdown");
    }
    ThreadPoolExecutor executor = executors.get(root);
    if (executor == null) {
      throw new RuntimeException("Cannot find root " + root
          + " for execution of task " + task);
    } else {
      executor.execute(task);
    }
  }
  
  /**
   * Gracefully shut down all ThreadPool. Will wait for all deletion
   * tasks to finish.
   */
  synchronized void shutdown() {
    
    if (executors == null) {
      
      LOG.warn("AsyncDiskService has already shut down.");
      
    } else {
      LOG.info("Shutting down all async disk service threads...");
      
      for (Map.Entry<File, ThreadPoolExecutor> e
          : executors.entrySet()) {
        e.getValue().shutdown();
      }
      // clear the executor map so that calling execute again will fail.
      executors = null;
      
      LOG.info("All async disk service threads have been shut down.");
    }
  }

  /**
   * Delete the block file and meta file from the disk asynchronously, adjust
   * dfsUsed statistics accordingly.
   */
  void deleteAsync(FSDataset.FSVolume volume, String bpid, File blockFile,
      File metaFile, String blockName) {
    DataNode.LOG.info("Scheduling block " + blockName + " file " + blockFile
        + " for deletion");
    ReplicaFileDeleteTask deletionTask = 
        new ReplicaFileDeleteTask(volume, bpid, blockFile, metaFile,
            blockName);
    execute(volume.getCurrentDir(), deletionTask);
  }
  
  /** A task for deleting a block file and its associated meta file, as well
   *  as decrement the dfs usage of the volume. 
   */
  static class ReplicaFileDeleteTask implements Runnable {
    final FSDataset.FSVolume volume;
    final String blockPoolId;
    final File blockFile;
    final File metaFile;
    final String blockName;
    
    ReplicaFileDeleteTask(FSDataset.FSVolume volume, String bpid,
        File blockFile, File metaFile, String blockName) {
      this.volume = volume;
      this.blockPoolId = bpid;
      this.blockFile = blockFile;
      this.metaFile = metaFile;
      this.blockName = blockName;
    }
    
    FSDataset.FSVolume getVolume() {
      return volume;
    }

    @Override
    public String toString() {
      // Called in AsyncDiskService.execute for displaying error messages.
      return "deletion of block " + blockPoolId + " " + blockName
          + " with block file " + blockFile + " and meta file " + metaFile
          + " from volume " + volume;
    }

    @Override
    public void run() {
      long dfsBytes = blockFile.length() + metaFile.length();
      if ( !blockFile.delete() || ( !metaFile.delete() && metaFile.exists() ) ) {
        DataNode.LOG.warn("Unexpected error trying to delete block "
            + blockPoolId + " " + blockName + " at file " + blockFile
            + ". Ignored.");
      } else {
        volume.decDfsUsed(blockPoolId, dfsBytes);
        DataNode.LOG.info("Deleted block " + blockPoolId + " " + blockName
            + " at file " + blockFile);
      }
    }
  };
  
  
}
