org.apache.hadoop.hdfs.protocol.Block.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.hdfs.protocol.Block.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.hdfs.protocol;

import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.io.*;

import javax.annotation.Nonnull;

/**************************************************
 * A Block is a Hadoop FS primitive, identified by a
 * long.
 *
 **************************************************/
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class Block implements Writable, Comparable<Block> {
    public static final String BLOCK_FILE_PREFIX = "blk_";
    public static final String METADATA_EXTENSION = ".meta";
    static { // register a ctor
        WritableFactories.setFactory(Block.class, new WritableFactory() {
            @Override
            public Writable newInstance() {
                return new Block();
            }
        });
    }

    public static final Pattern blockFilePattern = Pattern.compile(BLOCK_FILE_PREFIX + "(-??\\d++)$");
    public static final Pattern metaFilePattern = Pattern
            .compile(BLOCK_FILE_PREFIX + "(-??\\d++)_(\\d++)\\" + METADATA_EXTENSION + "$");
    public static final Pattern metaOrBlockFilePattern = Pattern
            .compile(BLOCK_FILE_PREFIX + "(-??\\d++)(_(\\d++)\\" + METADATA_EXTENSION + ")?$");

    public static boolean isBlockFilename(File f) {
        String name = f.getName();
        return blockFilePattern.matcher(name).matches();
    }

    public static long filename2id(String name) {
        Matcher m = blockFilePattern.matcher(name);
        return m.matches() ? Long.parseLong(m.group(1)) : 0;
    }

    public static boolean isMetaFilename(String name) {
        return metaFilePattern.matcher(name).matches();
    }

    public static File metaToBlockFile(File metaFile) {
        return new File(metaFile.getParent(), metaFile.getName().substring(0, metaFile.getName().lastIndexOf('_')));
    }

    /**
     * Get generation stamp from the name of the metafile name
     */
    public static long getGenerationStamp(String metaFile) {
        Matcher m = metaFilePattern.matcher(metaFile);
        return m.matches() ? Long.parseLong(m.group(2)) : HdfsConstants.GRANDFATHER_GENERATION_STAMP;
    }

    /**
     * Get the blockId from the name of the meta or block file
     */
    public static long getBlockId(String metaOrBlockFile) {
        Matcher m = metaOrBlockFilePattern.matcher(metaOrBlockFile);
        return m.matches() ? Long.parseLong(m.group(1)) : 0;
    }

    private long blockId;
    private long numBytes;
    private long generationStamp;

    public Block() {
        this(0, 0, 0);
    }

    public Block(final long blkid, final long len, final long generationStamp) {
        set(blkid, len, generationStamp);
    }

    public Block(final long blkid) {
        this(blkid, 0, HdfsConstants.GRANDFATHER_GENERATION_STAMP);
    }

    public Block(Block blk) {
        this(blk.blockId, blk.numBytes, blk.generationStamp);
    }

    /**
     * Find the blockid from the given filename
     */
    public Block(File f, long len, long genstamp) {
        this(filename2id(f.getName()), len, genstamp);
    }

    public void set(long blkid, long len, long genStamp) {
        this.blockId = blkid;
        this.numBytes = len;
        this.generationStamp = genStamp;
    }

    /**
     */
    public long getBlockId() {
        return blockId;
    }

    public void setBlockId(long bid) {
        blockId = bid;
    }

    /**
     */
    public String getBlockName() {
        return new StringBuilder().append(BLOCK_FILE_PREFIX).append(blockId).toString();
    }

    /**
     */
    public long getNumBytes() {
        return numBytes;
    }

    public void setNumBytes(long len) {
        this.numBytes = len;
    }

    public long getGenerationStamp() {
        return generationStamp;
    }

    public void setGenerationStamp(long stamp) {
        generationStamp = stamp;
    }

    /**
     * A helper method to output the string representation of the Block portion of
     * a derived class' instance.
     *
     * @param b the target object
     * @return the string representation of the block
     */
    public static String toString(final Block b) {
        StringBuilder sb = new StringBuilder();
        sb.append(BLOCK_FILE_PREFIX).append(b.blockId).append("_").append(b.generationStamp);
        return sb.toString();
    }

    /**
     */
    @Override
    public String toString() {
        return toString(this);
    }

    public void appendStringTo(StringBuilder sb) {
        sb.append(BLOCK_FILE_PREFIX).append(blockId).append("_").append(getGenerationStamp());
    }

    /////////////////////////////////////
    // Writable
    /////////////////////////////////////
    @Override // Writable
    public void write(DataOutput out) throws IOException {
        writeHelper(out);
    }

    @Override // Writable
    public void readFields(DataInput in) throws IOException {
        readHelper(in);
    }

    final void writeHelper(DataOutput out) throws IOException {
        out.writeLong(blockId);
        out.writeLong(numBytes);
        out.writeLong(generationStamp);
    }

    final void readHelper(DataInput in) throws IOException {
        this.blockId = in.readLong();
        this.numBytes = in.readLong();
        this.generationStamp = in.readLong();
        if (numBytes < 0) {
            throw new IOException("Unexpected block size: " + numBytes);
        }
    }

    // write only the identifier part of the block
    public void writeId(DataOutput out) throws IOException {
        out.writeLong(blockId);
        out.writeLong(generationStamp);
    }

    // Read only the identifier part of the block
    public void readId(DataInput in) throws IOException {
        this.blockId = in.readLong();
        this.generationStamp = in.readLong();
    }

    @Override // Comparable
    public int compareTo(@Nonnull Block b) {
        return blockId < b.blockId ? -1 : blockId > b.blockId ? 1 : 0;
    }

    @Override // Object
    public boolean equals(Object o) {
        return this == o || o instanceof Block && compareTo((Block) o) == 0;
    }

    /**
     * @return true if the two blocks have the same block ID and the same
     * generation stamp, or if both blocks are null.
     */
    public static boolean matchingIdAndGenStamp(Block a, Block b) {
        if (a == b)
            return true; // same block, or both null
        // only one null
        return !(a == null || b == null) && a.blockId == b.blockId && a.generationStamp == b.generationStamp;
    }

    @Override // Object
    public int hashCode() {
        //GenerationStamp is IRRELEVANT and should not be used here
        return (int) (blockId ^ (blockId >>> 32));
    }
}