DataChecksum.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:8k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.util;
  19. import java.util.zip.Checksum;
  20. import java.util.zip.CRC32;
  21. import java.io.*;
  22. /**
  23.  * This class provides inteface and utilities for processing checksums for
  24.  * DFS data transfers.
  25.  */
  26. public class DataChecksum implements Checksum {
  27.   
  28.   // Misc constants
  29.   public static final int HEADER_LEN = 5; /// 1 byte type and 4 byte len
  30.   
  31.   // checksum types
  32.   public static final int CHECKSUM_NULL    = 0;
  33.   public static final int CHECKSUM_CRC32   = 1;
  34.   
  35.   private static final int CHECKSUM_NULL_SIZE  = 0;
  36.   private static final int CHECKSUM_CRC32_SIZE = 4;
  37.   
  38.   
  39.   public static DataChecksum newDataChecksum( int type, int bytesPerChecksum ) {
  40.     if ( bytesPerChecksum <= 0 ) {
  41.       return null;
  42.     }
  43.     
  44.     switch ( type ) {
  45.     case CHECKSUM_NULL :
  46.       return new DataChecksum( CHECKSUM_NULL, new ChecksumNull(), 
  47.                                CHECKSUM_NULL_SIZE, bytesPerChecksum );
  48.     case CHECKSUM_CRC32 :
  49.       return new DataChecksum( CHECKSUM_CRC32, new CRC32(), 
  50.                                CHECKSUM_CRC32_SIZE, bytesPerChecksum );
  51.     default:
  52.       return null;  
  53.     }
  54.   }
  55.   
  56.   /**
  57.    * Creates a DataChecksum from HEADER_LEN bytes from arr[offset].
  58.    * @return DataChecksum of the type in the array or null in case of an error.
  59.    */
  60.   public static DataChecksum newDataChecksum( byte bytes[], int offset ) {
  61.     if ( offset < 0 || bytes.length < offset + HEADER_LEN ) {
  62.       return null;
  63.     }
  64.     
  65.     // like readInt():
  66.     int bytesPerChecksum = ( (bytes[offset+1] & 0xff) << 24 ) | 
  67.                            ( (bytes[offset+2] & 0xff) << 16 ) |
  68.                            ( (bytes[offset+3] & 0xff) << 8 )  |
  69.                            ( (bytes[offset+4] & 0xff) );
  70.     return newDataChecksum( bytes[0], bytesPerChecksum );
  71.   }
  72.   
  73.   /**
  74.    * This constructucts a DataChecksum by reading HEADER_LEN bytes from
  75.    * input stream <i>in</i>
  76.    */
  77.   public static DataChecksum newDataChecksum( DataInputStream in )
  78.                                  throws IOException {
  79.     int type = in.readByte();
  80.     int bpc = in.readInt();
  81.     DataChecksum summer = newDataChecksum( type, bpc );
  82.     if ( summer == null ) {
  83.       throw new IOException( "Could not create DataChecksum of type " +
  84.                              type + " with bytesPerChecksum " + bpc );
  85.     }
  86.     return summer;
  87.   }
  88.   
  89.   /**
  90.    * Writes the checksum header to the output stream <i>out</i>.
  91.    */
  92.   public void writeHeader( DataOutputStream out ) 
  93.                            throws IOException { 
  94.     out.writeByte( type );
  95.     out.writeInt( bytesPerChecksum );
  96.   }
  97.   public byte[] getHeader() {
  98.     byte[] header = new byte[DataChecksum.HEADER_LEN];
  99.     header[0] = (byte) (type & 0xff);
  100.     // Writing in buffer just like DataOutput.WriteInt()
  101.     header[1+0] = (byte) ((bytesPerChecksum >>> 24) & 0xff);
  102.     header[1+1] = (byte) ((bytesPerChecksum >>> 16) & 0xff);
  103.     header[1+2] = (byte) ((bytesPerChecksum >>> 8) & 0xff);
  104.     header[1+3] = (byte) (bytesPerChecksum & 0xff);
  105.     return header;
  106.   }
  107.   
  108.   /**
  109.    * Writes the current checksum to the stream.
  110.    * If <i>reset</i> is true, then resets the checksum.
  111.    * @return number of bytes written. Will be equal to getChecksumSize();
  112.    */
  113.    public int writeValue( DataOutputStream out, boolean reset )
  114.                           throws IOException {
  115.      if ( size <= 0 ) {
  116.        return 0;
  117.      }
  118.      if ( type == CHECKSUM_CRC32 ) {
  119.        out.writeInt( (int) summer.getValue() );
  120.      } else {
  121.        throw new IOException( "Unknown Checksum " + type );
  122.      }
  123.      
  124.      if ( reset ) {
  125.        reset();
  126.      }
  127.      
  128.      return size;
  129.    }
  130.    
  131.    /**
  132.     * Writes the current checksum to a buffer.
  133.     * If <i>reset</i> is true, then resets the checksum.
  134.     * @return number of bytes written. Will be equal to getChecksumSize();
  135.     */
  136.     public int writeValue( byte[] buf, int offset, boolean reset )
  137.                            throws IOException {
  138.       if ( size <= 0 ) {
  139.         return 0;
  140.       }
  141.       if ( type == CHECKSUM_CRC32 ) {
  142.         int checksum = (int) summer.getValue();
  143.         buf[offset+0] = (byte) ((checksum >>> 24) & 0xff);
  144.         buf[offset+1] = (byte) ((checksum >>> 16) & 0xff);
  145.         buf[offset+2] = (byte) ((checksum >>> 8) & 0xff);
  146.         buf[offset+3] = (byte) (checksum & 0xff);
  147.       } else {
  148.         throw new IOException( "Unknown Checksum " + type );
  149.       }
  150.       
  151.       if ( reset ) {
  152.         reset();
  153.       }
  154.       
  155.       return size;
  156.     }
  157.    
  158.    /**
  159.     * Compares the checksum located at buf[offset] with the current checksum.
  160.     * @return true if the checksum matches and false otherwise.
  161.     */
  162.    public boolean compare( byte buf[], int offset ) {
  163.      if ( size > 0 && type == CHECKSUM_CRC32 ) {
  164.        int checksum = ( (buf[offset+0] & 0xff) << 24 ) | 
  165.                       ( (buf[offset+1] & 0xff) << 16 ) |
  166.                       ( (buf[offset+2] & 0xff) << 8 )  |
  167.                       ( (buf[offset+3] & 0xff) );
  168.        return checksum == (int) summer.getValue();
  169.      }
  170.      return size == 0;
  171.    }
  172.    
  173.   private final int type;
  174.   private final int size;
  175.   private final Checksum summer;
  176.   private final int bytesPerChecksum;
  177.   private int inSum = 0;
  178.   
  179.   private DataChecksum( int checksumType, Checksum checksum,
  180.                         int sumSize, int chunkSize ) {
  181.     type = checksumType;
  182.     summer = checksum;
  183.     size = sumSize;
  184.     bytesPerChecksum = chunkSize;
  185.   }
  186.   
  187.   // Accessors
  188.   public int getChecksumType() {
  189.     return type;
  190.   }
  191.   public int getChecksumSize() {
  192.     return size;
  193.   }
  194.   public int getBytesPerChecksum() {
  195.     return bytesPerChecksum;
  196.   }
  197.   public int getNumBytesInSum() {
  198.     return inSum;
  199.   }
  200.      public static final int SIZE_OF_INTEGER = Integer.SIZE / Byte.SIZE;   static public int getChecksumHeaderSize() {
  201.     return 1 + SIZE_OF_INTEGER; // type byte, bytesPerChecksum int   }
  202.   //Checksum Interface. Just a wrapper around member summer.
  203.   public long getValue() {
  204.     return summer.getValue();
  205.   }
  206.   public void reset() {
  207.     summer.reset();
  208.     inSum = 0;
  209.   }
  210.   public void update( byte[] b, int off, int len ) {
  211.     if ( len > 0 ) {
  212.       summer.update( b, off, len );
  213.       inSum += len;
  214.     }
  215.   }
  216.   public void update( int b ) {
  217.     summer.update( b );
  218.     inSum += 1;
  219.   }
  220.   
  221.   /**
  222.    * This just provides a dummy implimentation for Checksum class
  223.    * This is used when there is no checksum available or required for 
  224.    * data
  225.    */
  226.   static class ChecksumNull implements Checksum {
  227.     
  228.     public ChecksumNull() {}
  229.     
  230.     //Dummy interface
  231.     public long getValue() { return 0; }
  232.     public void reset() {}
  233.     public void update(byte[] b, int off, int len) {}
  234.     public void update(int b) {}
  235.   };
  236. }