/**
 * 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.blockmanagement;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.hdfs.protocol.Block;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.hdfs.server.namenode.NameNode;

/** 
 * Keeps a Collection for every named machine containing blocks
 * that have recently been invalidated and are thought to live
 * on the machine in question.
 */
@InterfaceAudience.Private
class InvalidateBlocks {
  /** Mapping: StorageID -> Collection of Blocks */
  private final Map<String, Collection<Block>> node2blocks =
      new TreeMap<String, Collection<Block>>();
  /** The total number of blocks in the map. */
  private long numBlocks = 0L;

  private final DatanodeManager datanodeManager;

  InvalidateBlocks(final DatanodeManager datanodeManager) {
    this.datanodeManager = datanodeManager;
  }

  /** @return the number of blocks to be invalidated . */
  synchronized long numBlocks() {
    return numBlocks;
  }

  /** Does this contain the block which is associated with the storage? */
  synchronized boolean contains(final String storageID, final Block block) {
    final Collection<Block> s = node2blocks.get(storageID);
    return s != null && s.contains(block);
  }

  /**
   * Add a block to the block collection
   * which will be invalidated on the specified datanode.
   */
  synchronized void add(final Block block, final DatanodeInfo datanode,
      final boolean log) {
    Collection<Block> set = node2blocks.get(datanode.getStorageID());
    if (set == null) {
      set = new HashSet<Block>();
      node2blocks.put(datanode.getStorageID(), set);
    }
    if (set.add(block)) {
      numBlocks++;
      if (log) {
        NameNode.stateChangeLog.info("BLOCK* " + getClass().getSimpleName()
            + ": add " + block + " to " + datanode.getName());
      }
    }
  }

  /** Remove a storage from the invalidatesSet */
  synchronized void remove(final String storageID) {
    final Collection<Block> blocks = node2blocks.remove(storageID);
    if (blocks != null) {
      numBlocks -= blocks.size();
    }
  }

  /** Remove the block from the specified storage. */
  synchronized void remove(final String storageID, final Block block) {
    final Collection<Block> v = node2blocks.get(storageID);
    if (v != null && v.remove(block)) {
      numBlocks--;
      if (v.isEmpty()) {
        node2blocks.remove(storageID);
      }
    }
  }

  /** Print the contents to out. */
  synchronized void dump(final PrintWriter out) {
    final int size = node2blocks.values().size();
    out.println("Metasave: Blocks " + numBlocks 
        + " waiting deletion from " + size + " datanodes.");
    if (size == 0) {
      return;
    }

    for(Map.Entry<String,Collection<Block>> entry : node2blocks.entrySet()) {
      final Collection<Block> blocks = entry.getValue();
      if (blocks.size() > 0) {
        out.println(datanodeManager.getDatanode(entry.getKey()).getName() + blocks);
      }
    }
  }

  /** @return a list of the storage IDs. */
  synchronized List<String> getStorageIDs() {
    return new ArrayList<String>(node2blocks.keySet());
  }

  /** Invalidate work for the storage. */
  int invalidateWork(final String storageId) {
    final DatanodeDescriptor dn = datanodeManager.getDatanode(storageId);
    if (dn == null) {
      remove(storageId);
      return 0;
    }
    final List<Block> toInvalidate = invalidateWork(storageId, dn);
    if (toInvalidate == null) {
      return 0;
    }

    if (NameNode.stateChangeLog.isInfoEnabled()) {
      NameNode.stateChangeLog.info("BLOCK* " + getClass().getSimpleName()
          + ": ask " + dn.getName() + " to delete " + toInvalidate);
    }
    return toInvalidate.size();
  }

  private synchronized List<Block> invalidateWork(
      final String storageId, final DatanodeDescriptor dn) {
    final Collection<Block> set = node2blocks.get(storageId);
    if (set == null) {
      return null;
    }

    // # blocks that can be sent in one message is limited
    final int limit = datanodeManager.blockInvalidateLimit;
    final List<Block> toInvalidate = new ArrayList<Block>(limit);
    final Iterator<Block> it = set.iterator();
    for(int count = 0; count < limit && it.hasNext(); count++) {
      toInvalidate.add(it.next());
      it.remove();
    }
    // If we send everything in this message, remove this node entry
    if (!it.hasNext()) {
      remove(storageId);
    }

    dn.addBlocksToBeInvalidated(toInvalidate);
    numBlocks -= toInvalidate.size();
    return toInvalidate;
  }
}
