INodeFile extends INodeWithAdditionalFields implements INodeFileAttributes, BlockCollection { void concatBlocks(INodeFile[] inodes, BlockManager bm) { int size = this.blocks.length; int totalAddedBlocks = 0; for(INodeFile f : inodes) { Preconditions.checkState(f.isStriped() == this.isStriped()); totalAddedBlocks += f.blocks.length; } BlockInfo[] newlist = new BlockInfo[size + totalAddedBlocks]; System.arraycopy(this.blocks, 0, newlist, 0, size); for(INodeFile in: inodes) { System.arraycopy(in.blocks, 0, newlist, size, in.blocks.length); size += in.blocks.length; } setBlocks(newlist); for(BlockInfo b : blocks) { b.setBlockCollectionId(getId()); short oldRepl = b.getReplication(); short repl = getPreferredBlockReplication(); if (oldRepl != repl) { bm.setReplication(oldRepl, repl, b); } } } INodeFile(long id, byte[] name, PermissionStatus permissions, long mtime,
            long atime, BlockInfo[] blklist, short replication,
            long preferredBlockSize);   INodeFile(long id, byte[] name, PermissionStatus permissions, long mtime,
      long atime, BlockInfo[] blklist, short replication,
      long preferredBlockSize, byte storagePolicyID, boolean isStriped);  INodeFile(INodeFile that);  INodeFile(INodeFile that, FileDiffList diffs); static INodeFile valueOf(INode inode, String path
      ); static INodeFile valueOf(INode inode, String path, boolean acceptNull); @Override final boolean isFile(); @Override final INodeFile asFile(); @Override boolean metadataEquals(INodeFileAttributes other); final FileUnderConstructionFeature getFileUnderConstructionFeature(); @Override // BlockCollection boolean isUnderConstruction(); INodeFile toCompleteFile(long mtime); @Override // BlockCollection void setBlock(int index, BlockInfo blk); @Override // BlockCollection, the file should be under construction void convertLastBlockToUC(BlockInfo lastBlock,
      DatanodeStorageInfo[] locations); FileWithSnapshotFeature addSnapshotFeature(FileDiffList diffs); final FileWithSnapshotFeature getFileWithSnapshotFeature(); final boolean isWithSnapshot(); @Override String toDetailString(); @Override INodeFileAttributes getSnapshotINode(final int snapshotId); @Override void recordModification(final int latestSnapshotId); void recordModification(final int latestSnapshotId, boolean withBlocks); FileDiffList getDiffs(); final short getFileReplication(int snapshot); @Override // INodeFileAttributes // TODO properly handle striped files final short getFileReplication(); short getPreferredBlockReplication(); final INodeFile setFileReplication(short replication,
      int latestSnapshotId); @Override long getPreferredBlockSize(); @Override byte getLocalStoragePolicyID(); @Override byte getStoragePolicyID(); final void setStoragePolicyID(byte storagePolicyId,
      int latestSnapshotId); @VisibleForTesting @Override byte getErasureCodingPolicyID(); @VisibleForTesting @Override boolean isStriped(); @Override // INodeFileAttributes long getHeaderLong(); @Override // BlockCollection BlockInfo[] getBlocks(); BlockInfo[] getBlocks(int snapshot); void clearBlocks(); @Override void cleanSubtree(ReclaimContext reclaimContext,
      final int snapshot, int priorSnapshotId); @Override void destroyAndCollectBlocks(ReclaimContext reclaimContext); void clearFile(ReclaimContext reclaimContext); @Override String getName(); @Override final QuotaCounts computeQuotaUsage(BlockStoragePolicySuite bsps,
      byte blockStoragePolicyId, boolean useCache, int lastSnapshotId); final QuotaCounts computeQuotaUsageWithStriped(
      BlockStoragePolicy bsp, QuotaCounts counts); @Override final ContentSummaryComputationContext computeContentSummary(
      int snapshotId, final ContentSummaryComputationContext summary); final long computeFileSize(); final long computeFileSize(int snapshotId); final long computeFileSizeNotIncludingLastUcBlock(); final long computeFileSize(boolean includesLastUcBlock,
      boolean usePreferredBlockSize4LastUcBlock); final QuotaCounts storagespaceConsumed(BlockStoragePolicy bsp); final QuotaCounts storagespaceConsumedStriped(); final QuotaCounts storagespaceConsumedContiguous(
      BlockStoragePolicy bsp); @Override BlockInfo getLastBlock(); @Override int numBlocks(); @VisibleForTesting @Override void dumpTreeRecursively(PrintWriter out, StringBuilder prefix,
      final int snapshotId); long collectBlocksBeyondMax(final long max,
      final BlocksMapUpdateInfo collectedBlocks); void collectBlocksBeyondSnapshot(BlockInfo[] snapshotBlocks,
                                          BlocksMapUpdateInfo collectedBlocks);  }
@Test public void testConcatBlocks() { INodeFile origFile = createINodeFiles(1, "origfile")[0]; assertEquals("Number of blocks didn't match", origFile.numBlocks(), 1L); INodeFile[] appendFiles = createINodeFiles(4, "appendfile"); BlockManager bm = Mockito.mock(BlockManager.class); origFile.concatBlocks(appendFiles, bm); assertEquals("Number of blocks didn't match", origFile.numBlocks(), 5L); }