code: boolean addTarget(DatanodeDescriptor node, long generationStamp) {
      
      if (this.targets == null) {
        this.targets = new DatanodeDescriptor[0];
      }
  
      for (int i=0; i<targets.length; i++) {
        if (targets[i].equals(node)) {
          if (generationStamp != targetGSs[i]) {
            targetGSs[i] = generationStamp;
            return true;
          }
          return false;
        }
      }
      
      if (node != null) {
        node.addINode(this);
      }
  
      // allocate new data structure to store additional target
      DatanodeDescriptor[] newt = new DatanodeDescriptor[targets.length + 1];
      long[] newgs = new long[targets.length + 1];
      for (int i = 0; i < targets.length; i++) {
        newt[i] = this.targets[i];
        newgs[i] = this.targetGSs[i];
      }
      newt[targets.length] = node;
      newgs[targets.length] = generationStamp;
  
      this.targets = newt;
      this.targetGSs = newgs;
      this.primaryNodeIndex = -1;
      return true;
    }
docs: add this target if it does not already exists. Returns true if the target
  was added.
  
  @param node
  data node having the block
  @param generationStamp
  the generation of the block on the data node
  @return true if the data node is added to the target list, or previous
  generation stamp for the datanode is updated. Otherwise, false,
  which means the data node is already in the target list with
  the same generation stamp.