From 1fe93758013107a69b980bf4968dcf90f2cb6d70 Mon Sep 17 00:00:00 2001
From: eerpini <eerpini@gmail.com>
Date: Thu, 2 Jun 2011 22:14:40 -0700
Subject: [PATCH] Modify the "purge" and "purgeAll" commands to only purge
 nodes which are either in DECOMMISSIONED or LOST state. The
 modified semantics are as follows : purge -> if the
 logical_node given as argument is not in the one of the
 above two states then it is not purged and a warning is
 displayed using the logger on FlumeAgent if the
 lofical_node is in one of the above two states , it is
 purged purgeAll -> Go through the logical node status table
 and collect the names of all the logical nodes which are in
 the above two states, then purge all of these nodes.

Docs changed accordingly
---
 .../com/cloudera/flume/master/StatusManager.java   |   48 +++++++++++++++++---
 src/docs/UserGuide/FlumeShell                      |   11 +++--
 2 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/flume-core/src/main/java/com/cloudera/flume/master/StatusManager.java b/flume-core/src/main/java/com/cloudera/flume/master/StatusManager.java
index 0e6ef53..c2252da 100644
--- a/flume-core/src/main/java/com/cloudera/flume/master/StatusManager.java
+++ b/flume-core/src/main/java/com/cloudera/flume/master/StatusManager.java
@@ -24,6 +24,8 @@ import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
 import java.util.Map.Entry;
+import java.util.ArrayList;
+import java.util.Iterator;
 
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -219,19 +221,51 @@ public class StatusManager implements Reportable {
    * Purge a status entry for the specified logical node
    */
   public boolean purge(String node) {
-    NodeStatus val;
-    synchronized (statuses) {
-      val = statuses.remove(node);
+    NodeStatus val=null;
+    if(statuses.containsKey(node)){
+      val = this.getStatus(node);
+      if(val.state == NodeState.DECOMMISSIONED || val.state == NodeState.LOST){
+        synchronized(statuses){
+	  val = statuses.remove(node);
+	  return val != null;
+        }
+      }
+      else{
+        LOG.warn("Purge : Ignoring "+node+" which is neither DECOMMISSIONED nor LOST");
+	return false;	
+      }
+    }
+    else{
+      LOG.error("Purge : "+node+" not found, tried to purge a node not in statuses");
+      return false;
     }
-    return val != null;
   }
-
   /**
    * Purge all status entries from the logical node status table.
    */
   public void purgeAll() {
-    synchronized (statuses) {
-      statuses.clear();
+  /*
+   *we first need to collect the list of nodes to be purged
+   */
+    ArrayList<String> nodesToPurge = new ArrayList<String>();
+    synchronized(statuses){
+      for(String node : statuses.keySet()){
+        NodeStatus val = this.getStatus(node);
+        if(val.state == NodeState.DECOMMISSIONED || val.state == NodeState.LOST){
+	  nodesToPurge.add(node);
+        }
+        else{
+          LOG.warn("PurgeAll : Ignoring "+node+" which is neither DECOMMISSIONED nor LOST");
+        }
+      }
+      /*
+       * Iterate over the list of nodes and remove them
+       */
+      for(Iterator<String> i = nodesToPurge.iterator();i.hasNext();){
+        synchronized(statuses){
+          statuses.remove(i.next());
+      	}
+      }
     }
   }
 }
diff --git a/src/docs/UserGuide/FlumeShell b/src/docs/UserGuide/FlumeShell
index fc5f223..a47d460 100644
--- a/src/docs/UserGuide/FlumeShell
+++ b/src/docs/UserGuide/FlumeShell
@@ -199,10 +199,11 @@ using the +map+ command.
 
 +purge+ _logicalnode_ :: This command removes an entry from the
 logical node status table.  It is useful for removing DECOMMISSIONED
-or LOST nodes.
+or LOST nodes. If the purge command is used to remove an entry 
+that is not in DECOMMISSIONED or LOST state, then a warning is added
+to the log, but the logical node is not removed from the logical
+node status table.
 
-+purgeAll+ :: This command removes *all* entries from the logical node
-status table.  It is useful for removing DECOMMISSIONED or LOST nodes.
-Note that even nodes that are in ACTIVE/IDLE/ERROR states will be
-removed but added again after their next heartbeat.
++purgeAll+ :: This command removes entries from the logical node
+status table which are in either DECOMMISSIONED or LOST mode.
 
-- 
1.7.5.2

