code: public int computeDatanodeWork() throws IOException {
      int workFound = 0;
      int blocksToProcess = 0;
      int nodesToProcess = 0;
      // blocks should not be replicated or removed if safe mode is on
      if (isInSafeMode()) {
        updateReplicationCounts(workFound);
        return workFound;
      }
      synchronized (heartbeats) {
        blocksToProcess = (int) (heartbeats.size()
          * ReplicationConfigKeys.replicationWorkMultiplier);
        nodesToProcess = (int) Math.ceil((double) heartbeats.size()
          * ReplicationConfigKeys.INVALIDATE_WORK_PCT_PER_ITERATION / 100);
      }
  
      workFound = computeReplicationWork(blocksToProcess);
  
      // Update FSNamesystemMetrics counters
      updateReplicationCounts(workFound);
  
      workFound += computeInvalidateWork(nodesToProcess);
      return workFound;
    }
docs: Compute block replication and block invalidation work
  that can be scheduled on data-nodes.
  The datanode will be informed of this work at the next heartbeat.
  
  @return number of blocks scheduled for replication or removal.