package org.apache.hadoop.hdfs; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.Arrays; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.hdfs.protocol.Block; import org.apache.hadoop.io.Writable; public class FileStatusExtended extends FileStatus implements Writable { private Block[] blocks; private String leaseHolder; // HardLink id of -1 denotes the file is not hardlinked. private long hardlinkId; public FileStatusExtended() {} public FileStatusExtended(FileStatus stat, Block[] blocks, String leaseHolder, long hardlinkId) { super(stat.getLen(), stat.isDir(), stat.getReplication(), stat.getBlockSize(), stat.getModificationTime(), stat.getAccessTime(), stat.getPermission(), stat.getOwner(), stat.getGroup(), stat.getPath()); this.blocks = blocks; this.leaseHolder = (leaseHolder == null) ? "" : leaseHolder; this.hardlinkId = hardlinkId; } public Block[] getBlocks() { return this.blocks; } public String getHolder() { return leaseHolder; } public void write(DataOutput out) throws IOException { super.write(out); int nblocks = (blocks == null) ? 0 : blocks.length; out.writeInt(nblocks); for (int i = 0; i < nblocks; i++) { blocks[i].write(out); } out.writeUTF(leaseHolder); out.writeLong(hardlinkId); } public void readFields(DataInput in) throws IOException { super.readFields(in); int nblocks = in.readInt(); blocks = new Block[nblocks]; for (int i = 0; i < nblocks; i++) { blocks[i] = new Block(); blocks[i].readFields(in); } leaseHolder = in.readUTF(); hardlinkId = in.readLong(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (getClass() != obj.getClass()) return false; FileStatusExtended other = (FileStatusExtended) obj; if (!leaseHolder.equals(other.leaseHolder) || hardlinkId != other.hardlinkId) return false; boolean closedFile = leaseHolder.isEmpty(); if (!super.compareFull(obj, closedFile)) { return false; } if (!blocksEquals(blocks, other.blocks, closedFile)) return false; return true; } /** * Comapre two arrays of blocks. If the file is open, do not compare * sizes of the blocks. */ private boolean blocksEquals(Block[] a1, Block[] a2, boolean closedFile) { if (a1 == a2) return true; if (a1 == null || a2 == null || a2.length != a1.length) return false; for (int i = 0; i < a1.length; i++) { Block b1 = a1[i]; Block b2 = a2[i]; if (b1 == b2) continue; if (b1 == null || b2 == null) return false; // compare ids and gen stamps if (!(b1.getBlockId() == b2.getBlockId() && b1.getGenerationStamp() == b2 .getGenerationStamp())) return false; // for open files check len-2 blocks only if (!closedFile && i >= a1.length - 2) continue; // check block size if (b1.getNumBytes() != b2.getNumBytes()) return false; } return true; } @Override public String toString() { return "FileStatusExtended [blocks=" + Arrays.toString(blocks) + ", leaseHolder=" + leaseHolder + ", hardlinkId =" + hardlinkId + "]" + super.toString(); } }