code: private int invalidateWorkForOneNode(String nodeId) {
      List<Block> blocksToInvalidate = null;
      DatanodeDescriptor dn = null;
      writeLock();
      try {
        // blocks should not be replicated or removed if safe mode is on
        if (isInSafeMode()) {
          return 0;
        }
        // get blocks to invalidate for the nodeId
        assert nodeId != null;
        dn = datanodeMap.get(nodeId);
        if (dn == null) {
          recentInvalidateSets.remove(nodeId);
          return 0;
        }
  
        LightWeightHashSet<Block> invalidateSet = recentInvalidateSets
            .get(nodeId);
        if (invalidateSet == null) {
          return 0;
        }
        // # blocks that can be sent in one message is limited
        blocksToInvalidate = invalidateSet.pollN(ReplicationConfigKeys.blockInvalidateLimit);
  
        // If we send everything in this message, remove this node entry
        if (invalidateSet.isEmpty()) {
          recentInvalidateSets.remove(nodeId);
        }
  
        dn.addBlocksToBeInvalidated(blocksToInvalidate);
        pendingDeletionBlocksCount -= blocksToInvalidate.size();
      } finally {
        writeUnlock();
        if (NameNode.stateChangeLog.isInfoEnabled() && blocksToInvalidate != null
            && blocksToInvalidate.size() != 0) {
          StringBuffer blockList = new StringBuffer();
          for (Block blk : blocksToInvalidate) {
            blockList.append(' ');
            blockList.append(blk);
          }
          NameNode.stateChangeLog.info("BLOCK* ask "
            + dn.getName() + " to delete " + blockList);
        }
      }
      return blocksToInvalidate.size();
    }
docs: Get blocks to invalidate for <i>nodeId</i>
  in {@link #recentInvalidateSets}.
  
  @return number of blocks scheduled for removal during this iteration.