hadoop Unsigned16 源码

  • 2022-10-20
  • 浏览 (151)

haddop Unsigned16 代码

文件路径:/hadoop-mapreduce-project/hadoop-mapreduce-examples/src/main/java/org/apache/hadoop/examples/terasort/Unsigned16.java

/**
 * 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.examples.terasort;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.Writable;

/**
 * An unsigned 16 byte integer class that supports addition, multiplication,
 * and left shifts.
 */
class Unsigned16 implements Writable {
  private long hi8;
  private long lo8;

  public Unsigned16() {
    hi8 = 0;
    lo8 = 0;
  }

  public Unsigned16(long l) {
    hi8 = 0;
    lo8 = l;
  }

  public Unsigned16(Unsigned16 other) {
    hi8 = other.hi8;
    lo8 = other.lo8;
  }
  
  @Override
  public boolean equals(Object o) {
    if (o instanceof Unsigned16) {
      Unsigned16 other = (Unsigned16) o;
      return other.hi8 == hi8 && other.lo8 == lo8;
    }
    return false;
  }

  @Override
  public int hashCode() {
    return (int) lo8;
  }

  /**
   * Parse a hex string
   * @param s the hex string
   */
  public Unsigned16(String s) throws NumberFormatException {
    set(s);
  }

  /**
   * Set the number from a hex string
   * @param s the number in hexadecimal
   * @throws NumberFormatException if the number is invalid
   */
  public void set(String s) throws NumberFormatException {
    hi8 = 0;
    lo8 = 0;
    final long lastDigit = 0xfl << 60;
    for (int i = 0; i < s.length(); ++i) {
      int digit = getHexDigit(s.charAt(i));
      if ((lastDigit & hi8) != 0) {
        throw new NumberFormatException(s + " overflowed 16 bytes");
      }
      hi8 <<= 4;
      hi8 |= (lo8 & lastDigit) >>> 60;
      lo8 <<= 4;
      lo8 |= digit;
    }    
  }

  /**
   * Set the number to a given long.
   * @param l the new value, which is treated as an unsigned number
   */
  public void set(long l) {
    lo8 = l;
    hi8 = 0;
  }

  /**
   * Map a hexadecimal character into a digit.
   * @param ch the character
   * @return the digit from 0 to 15
   * @throws NumberFormatException
   */
  private static int getHexDigit(char ch) throws NumberFormatException {
    if (ch >= '0' && ch <= '9') {
      return ch - '0';
    }
    if (ch >= 'a' && ch <= 'f') {
      return ch - 'a' + 10;
    }
    if (ch >= 'A' && ch <= 'F') {
      return ch - 'A' + 10;
    }
    throw new NumberFormatException(ch + " is not a valid hex digit");
  }

  private static final Unsigned16 TEN = new Unsigned16(10);

  public static Unsigned16 fromDecimal(String s) throws NumberFormatException {
    Unsigned16 result = new Unsigned16();
    Unsigned16 tmp = new Unsigned16();
    for(int i=0; i < s.length(); i++) {
      char ch = s.charAt(i);
      if (ch < '0' || ch > '9') {
        throw new NumberFormatException(ch + " not a valid decimal digit");
      }
      int digit = ch - '0';
      result.multiply(TEN);
      tmp.set(digit);
      result.add(tmp);
    }
    return result;
  }

  /**
   * Return the number as a hex string.
   */
  public String toString() {
    if (hi8 == 0) {
      return Long.toHexString(lo8);
    } else {
      StringBuilder result = new StringBuilder();
      result.append(Long.toHexString(hi8));
      String loString = Long.toHexString(lo8);
      for(int i=loString.length(); i < 16; ++i) {
        result.append('0');
      }
      result.append(loString);
      return result.toString();
    }
  }

  /**
   * Get a given byte from the number.
   * @param b the byte to get with 0 meaning the most significant byte
   * @return the byte or 0 if b is outside of 0..15
   */
  public byte getByte(int b) {
    if (b >= 0 && b < 16) {
      if (b < 8) {
        return (byte) (hi8 >> (56 - 8*b));
      } else {
        return (byte) (lo8 >> (120 - 8*b));
      }
    }
    return 0;
  }

  /**
   * Get the hexadecimal digit at the given position.
   * @param p the digit position to get with 0 meaning the most significant
   * @return the character or '0' if p is outside of 0..31
   */
  public char getHexDigit(int p) {
    byte digit = getByte(p / 2);
    if (p % 2 == 0) {
      digit >>>= 4;
    }
    digit &= 0xf;
    if (digit < 10) {
      return (char) ('0' + digit);
    } else {
      return (char) ('A' + digit - 10);
    }
  }

  /**
   * Get the high 8 bytes as a long.
   */
  public long getHigh8() {
    return hi8;
  }
  
  /**
   * Get the low 8 bytes as a long.
   */
  public long getLow8() {
    return lo8;
  }

  /**
   * Multiple the current number by a 16 byte unsigned integer. Overflow is not
   * detected and the result is the low 16 bytes of the result. The numbers 
   * are divided into 32 and 31 bit chunks so that the product of two chucks
   * fits in the unsigned 63 bits of a long.
   * @param b the other number
   */
  void multiply(Unsigned16 b) {
    // divide the left into 4 32 bit chunks
    long[] left = new long[4];
    left[0] = lo8 & 0xffffffffl;
    left[1] = lo8 >>> 32;
    left[2] = hi8 & 0xffffffffl;
    left[3] = hi8 >>> 32;
    // divide the right into 5 31 bit chunks
    long[] right = new long[5];
    right[0] = b.lo8 & 0x7fffffffl;
    right[1] = (b.lo8 >>> 31) & 0x7fffffffl;
    right[2] = (b.lo8 >>> 62) + ((b.hi8 & 0x1fffffffl) << 2);
    right[3] = (b.hi8 >>> 29) & 0x7fffffffl;
    right[4] = (b.hi8 >>> 60);
    // clear the cur value
    set(0);
    Unsigned16 tmp = new Unsigned16();
    for(int l=0; l < 4; ++l) {
      for (int r=0; r < 5; ++r) {
        long prod = left[l] * right[r];
        if (prod != 0) {
          int off = l*32 + r*31;
          tmp.set(prod);
          tmp.shiftLeft(off);
          add(tmp);
        }
      }
    }
  }

  /**
   * Add the given number into the current number.
   * @param b the other number
   */
  public void add(Unsigned16 b) {
    long sumHi;
    long sumLo;
    long  reshibit, hibit0, hibit1;

    sumHi = hi8 + b.hi8;

    hibit0 = (lo8 & 0x8000000000000000L);
    hibit1 = (b.lo8 & 0x8000000000000000L);
    sumLo = lo8 + b.lo8;
    reshibit = (sumLo & 0x8000000000000000L);
    if ((hibit0 & hibit1) != 0 | ((hibit0 ^ hibit1) != 0 && reshibit == 0))
      sumHi++;  /* add carry bit */
    hi8 = sumHi;
    lo8 = sumLo;
  }

  /**
   * Shift the number a given number of bit positions. The number is the low
   * order bits of the result.
   * @param bits the bit positions to shift by
   */
  public void shiftLeft(int bits) {
    if (bits != 0) {
      if (bits < 64) {
        hi8 <<= bits;
        hi8 |= (lo8 >>> (64 - bits));
        lo8 <<= bits;
      } else if (bits < 128) {
        hi8 = lo8 << (bits - 64);
        lo8 = 0;
      } else {
        hi8 = 0;
        lo8 = 0;
      }
    }
  }
  
  @Override
  public void readFields(DataInput in) throws IOException {
    hi8 = in.readLong();
    lo8 = in.readLong();
  }

  @Override
  public void write(DataOutput out) throws IOException {
    out.writeLong(hi8);
    out.writeLong(lo8);
  }
  
  
}

相关信息

hadoop 源码目录

相关文章

hadoop GenSort 源码

hadoop Random16 源码

hadoop TeraChecksum 源码

hadoop TeraGen 源码

hadoop TeraInputFormat 源码

hadoop TeraOutputFormat 源码

hadoop TeraScheduler 源码

hadoop TeraSort 源码

hadoop TeraSortConfigKeys 源码

hadoop TeraValidate 源码

0  赞