private void ensureCapacity() {
    if (iPointer + 1 < data.length || jPointer < data[iPointer].length) {
      return;
    }
    int prevLength = data.length;

    Object[][] newData = new Object[prevLength * 2][];

    iPointer = prevLength / 2;

    for (int i = 0; i < iPointer; i++) {
      newData[i] = new Object[prevLength * 2];

      for (int j = 0; j < newData[i].length; j++) {
        newData[i][j] = data[i % prevLength + j / prevLength][j % prevLength];
      }
    }
    jPointer = 0;
    newData[iPointer] = new Object[prevLength * 2];
    this.data = newData;

  }
this method checks capacity and extend it if needed.
all data copied to new storage and only one empty leaf will be available to insert
Extra wasted space is equal to 2*SQRT(n);
src/ds/HashedArrayTree.java