code: int computeInvalidateWork(int nodesToProcess) {
      int numOfNodes = 0;
      ArrayList<String> keyArray = null;
  
      readLock();
      try {
        numOfNodes = recentInvalidateSets.size();
        // get an array of the keys
        keyArray = new ArrayList<String>(recentInvalidateSets.keySet());
      } finally {
        readUnlock();
      }
  
      nodesToProcess = Math.min(numOfNodes, nodesToProcess);
  
      // randomly pick up <i>nodesToProcess</i> nodes
      // and put them at [0, nodesToProcess)
      int remainingNodes = numOfNodes - nodesToProcess;
      if (nodesToProcess < remainingNodes) {
        for (int i = 0; i < nodesToProcess; i++) {
          int keyIndex = r.nextInt(numOfNodes - i) + i;
          Collections.swap(keyArray, keyIndex, i); // swap to front
        }
      } else {
        for (int i = 0; i < remainingNodes; i++) {
          int keyIndex = r.nextInt(numOfNodes - i);
          Collections.swap(keyArray, keyIndex, numOfNodes - i - 1); // swap to end
        }
      }
  
      int blockCnt = 0;
      for (int nodeCnt = 0; nodeCnt < nodesToProcess; nodeCnt++) {
        blockCnt += invalidateWorkForOneNode(keyArray.get(nodeCnt));
      }
      return blockCnt;
    }
docs: Schedule blocks for deletion at datanodes
  
  @param nodesToProcess number of datanodes to schedule deletion work
  @return total number of block for deletion