@Override
  boolean removeStorage(DatanodeStorageInfo storage) {
    int dnIndex = findStorageInfoFromEnd(storage);
    if (dnIndex < 0) { // the node is not found
      return false;
    }
    assert getPrevious(dnIndex) == null && getNext(dnIndex) == null :
        "Block is still in the list and must be removed first.";
    // set the triplet to null
    setStorageInfo(dnIndex, null);
    setNext(dnIndex, null);
    setPrevious(dnIndex, null);
    indices[dnIndex] = -1;
    return true;
  }
@Test
  public void testRemoveStorage() {
    // first add TOTAL_NUM_BLOCKS into the BlockInfoStriped
    DatanodeStorageInfo[] storages = DFSTestUtil.createDatanodeStorageInfos(
        totalBlocks);
    Block[] blocks = createReportedBlocks(totalBlocks);
    for (int i = 0; i < storages.length; i++) {
      info.addStorage(storages[i], blocks[i]);
    }

    // remove two storages
    info.removeStorage(storages[0]);
    info.removeStorage(storages[2]);

    // check
    Assert.assertEquals(totalBlocks, info.getCapacity());
    Assert.assertEquals(totalBlocks - 2, info.numNodes());
    byte[] indices = (byte[]) Whitebox.getInternalState(info, "indices");
    for (int i = 0; i < storages.length; i++) {
      int index = info.findStorageInfo(storages[i]);
      if (i != 0 && i != 2) {
        Assert.assertEquals(i, index);
        Assert.assertEquals(index, indices[index]);
      } else {
        Assert.assertEquals(-1, index);
        Assert.assertEquals(-1, indices[i]);
      }
    }

    // the same block is reported from another storage
    DatanodeStorageInfo[] storages2 = DFSTestUtil.createDatanodeStorageInfos(
        totalBlocks * 2);
    for (int i = totalBlocks; i < storages2.length; i++) {
      info.addStorage(storages2[i], blocks[i % totalBlocks]);
    }
    // now we should have 8 storages
    Assert.assertEquals(totalBlocks * 2 - 2, info.numNodes());
    Assert.assertEquals(totalBlocks * 2 - 2, info.getCapacity());
    indices = (byte[]) Whitebox.getInternalState(info, "indices");
    Assert.assertEquals(totalBlocks * 2 - 2, indices.length);
    int j = totalBlocks;
    for (int i = totalBlocks; i < storages2.length; i++) {
      int index = info.findStorageInfo(storages2[i]);
      if (i == totalBlocks || i == totalBlocks + 2) {
        Assert.assertEquals(i - totalBlocks, index);
      } else {
        Assert.assertEquals(j++, index);
      }
    }

    // remove the storages from storages2
    for (int i = 0; i < totalBlocks; i++) {
      info.removeStorage(storages2[i + totalBlocks]);
    }
    // now we should have 3 storages
    Assert.assertEquals(totalBlocks - 2, info.numNodes());
    Assert.assertEquals(totalBlocks * 2 - 2, info.getCapacity());
    indices = (byte[]) Whitebox.getInternalState(info, "indices");
    Assert.assertEquals(totalBlocks * 2 - 2, indices.length);
    for (int i = 0; i < totalBlocks; i++) {
      if (i == 0 || i == 2) {
        int index = info.findStorageInfo(storages2[i + totalBlocks]);
        Assert.assertEquals(-1, index);
      } else {
        int index = info.findStorageInfo(storages[i]);
        Assert.assertEquals(i, index);
      }
    }
    for (int i = totalBlocks; i < totalBlocks * 2 - 2; i++) {
      Assert.assertEquals(-1, indices[i]);
      Assert.assertNull(info.getDatanode(i));
    }
  }