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

网格计算

开发平台:

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.io;
  19. import java.io.*;
  20. import java.util.*;
  21. import org.apache.hadoop.util.ReflectionUtils;
  22. /** A Comparator for {@link WritableComparable}s.
  23.  *
  24.  * <p>This base implemenation uses the natural ordering.  To define alternate
  25.  * orderings, override {@link #compare(WritableComparable,WritableComparable)}.
  26.  *
  27.  * <p>One may optimize compare-intensive operations by overriding
  28.  * {@link #compare(byte[],int,int,byte[],int,int)}.  Static utility methods are
  29.  * provided to assist in optimized implementations of this method.
  30.  */
  31. public class WritableComparator implements RawComparator {
  32.   private static HashMap<Class, WritableComparator> comparators =
  33.     new HashMap<Class, WritableComparator>(); // registry
  34.   /** Get a comparator for a {@link WritableComparable} implementation. */
  35.   public static synchronized WritableComparator get(Class<? extends WritableComparable> c) {
  36.     WritableComparator comparator = comparators.get(c);
  37.     if (comparator == null)
  38.       comparator = new WritableComparator(c, true);
  39.     return comparator;
  40.   }
  41.   /** Register an optimized comparator for a {@link WritableComparable}
  42.    * implementation. */
  43.   public static synchronized void define(Class c,
  44.                                          WritableComparator comparator) {
  45.     comparators.put(c, comparator);
  46.   }
  47.   private final Class<? extends WritableComparable> keyClass;
  48.   private final WritableComparable key1;
  49.   private final WritableComparable key2;
  50.   private final DataInputBuffer buffer;
  51.   /** Construct for a {@link WritableComparable} implementation. */
  52.   protected WritableComparator(Class<? extends WritableComparable> keyClass) {
  53.     this(keyClass, false);
  54.   }
  55.   protected WritableComparator(Class<? extends WritableComparable> keyClass,
  56.       boolean createInstances) {
  57.     this.keyClass = keyClass;
  58.     if (createInstances) {
  59.       key1 = newKey();
  60.       key2 = newKey();
  61.       buffer = new DataInputBuffer();
  62.     } else {
  63.       key1 = key2 = null;
  64.       buffer = null;
  65.     }
  66.   }
  67.   /** Returns the WritableComparable implementation class. */
  68.   public Class<? extends WritableComparable> getKeyClass() { return keyClass; }
  69.   /** Construct a new {@link WritableComparable} instance. */
  70.   public WritableComparable newKey() {
  71.     return ReflectionUtils.newInstance(keyClass, null);
  72.   }
  73.   /** Optimization hook.  Override this to make SequenceFile.Sorter's scream.
  74.    *
  75.    * <p>The default implementation reads the data into two {@link
  76.    * WritableComparable}s (using {@link
  77.    * Writable#readFields(DataInput)}, then calls {@link
  78.    * #compare(WritableComparable,WritableComparable)}.
  79.    */
  80.   public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
  81.     try {
  82.       buffer.reset(b1, s1, l1);                   // parse key1
  83.       key1.readFields(buffer);
  84.       
  85.       buffer.reset(b2, s2, l2);                   // parse key2
  86.       key2.readFields(buffer);
  87.       
  88.     } catch (IOException e) {
  89.       throw new RuntimeException(e);
  90.     }
  91.     
  92.     return compare(key1, key2);                   // compare them
  93.   }
  94.   /** Compare two WritableComparables.
  95.    *
  96.    * <p> The default implementation uses the natural ordering, calling {@link
  97.    * Comparable#compareTo(Object)}. */
  98.   @SuppressWarnings("unchecked")
  99.   public int compare(WritableComparable a, WritableComparable b) {
  100.     return a.compareTo(b);
  101.   }
  102.   public int compare(Object a, Object b) {
  103.     return compare((WritableComparable)a, (WritableComparable)b);
  104.   }
  105.   /** Lexicographic order of binary data. */
  106.   public static int compareBytes(byte[] b1, int s1, int l1,
  107.                                  byte[] b2, int s2, int l2) {
  108.     int end1 = s1 + l1;
  109.     int end2 = s2 + l2;
  110.     for (int i = s1, j = s2; i < end1 && j < end2; i++, j++) {
  111.       int a = (b1[i] & 0xff);
  112.       int b = (b2[j] & 0xff);
  113.       if (a != b) {
  114.         return a - b;
  115.       }
  116.     }
  117.     return l1 - l2;
  118.   }
  119.   /** Compute hash for binary data. */
  120.   public static int hashBytes(byte[] bytes, int length) {
  121.     int hash = 1;
  122.     for (int i = 0; i < length; i++)
  123.       hash = (31 * hash) + (int)bytes[i];
  124.     return hash;
  125.   }
  126.   /** Parse an unsigned short from a byte array. */
  127.   public static int readUnsignedShort(byte[] bytes, int start) {
  128.     return (((bytes[start]   & 0xff) <<  8) +
  129.             ((bytes[start+1] & 0xff)));
  130.   }
  131.   /** Parse an integer from a byte array. */
  132.   public static int readInt(byte[] bytes, int start) {
  133.     return (((bytes[start  ] & 0xff) << 24) +
  134.             ((bytes[start+1] & 0xff) << 16) +
  135.             ((bytes[start+2] & 0xff) <<  8) +
  136.             ((bytes[start+3] & 0xff)));
  137.   }
  138.   /** Parse a float from a byte array. */
  139.   public static float readFloat(byte[] bytes, int start) {
  140.     return Float.intBitsToFloat(readInt(bytes, start));
  141.   }
  142.   /** Parse a long from a byte array. */
  143.   public static long readLong(byte[] bytes, int start) {
  144.     return ((long)(readInt(bytes, start)) << 32) +
  145.       (readInt(bytes, start+4) & 0xFFFFFFFFL);
  146.   }
  147.   /** Parse a double from a byte array. */
  148.   public static double readDouble(byte[] bytes, int start) {
  149.     return Double.longBitsToDouble(readLong(bytes, start));
  150.   }
  151.   /**
  152.    * Reads a zero-compressed encoded long from a byte array and returns it.
  153.    * @param bytes byte array with decode long
  154.    * @param start starting index
  155.    * @throws java.io.IOException 
  156.    * @return deserialized long
  157.    */
  158.   public static long readVLong(byte[] bytes, int start) throws IOException {
  159.     int len = bytes[start];
  160.     if (len >= -112) {
  161.       return len;
  162.     }
  163.     boolean isNegative = (len < -120);
  164.     len = isNegative ? -(len + 120) : -(len + 112);
  165.     if (start+1+len>bytes.length)
  166.       throw new IOException(
  167.                             "Not enough number of bytes for a zero-compressed integer");
  168.     long i = 0;
  169.     for (int idx = 0; idx < len; idx++) {
  170.       i = i << 8;
  171.       i = i | (bytes[start+1+idx] & 0xFF);
  172.     }
  173.     return (isNegative ? (i ^ -1L) : i);
  174.   }
  175.   
  176.   /**
  177.    * Reads a zero-compressed encoded integer from a byte array and returns it.
  178.    * @param bytes byte array with the encoded integer
  179.    * @param start start index
  180.    * @throws java.io.IOException 
  181.    * @return deserialized integer
  182.    */
  183.   public static int readVInt(byte[] bytes, int start) throws IOException {
  184.     return (int) readVLong(bytes, start);
  185.   }
  186. }