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

网格计算

开发平台:

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.mapred.join;
  19. import java.io.DataOutput;
  20. import java.io.DataInput;
  21. import java.io.IOException;
  22. import java.util.Iterator;
  23. import java.util.NoSuchElementException;
  24. import org.apache.hadoop.io.Text;
  25. import org.apache.hadoop.io.Writable;
  26. import org.apache.hadoop.io.WritableUtils;
  27. /**
  28.  * Writable type storing multiple {@link org.apache.hadoop.io.Writable}s.
  29.  *
  30.  * This is *not* a general-purpose tuple type. In almost all cases, users are
  31.  * encouraged to implement their own serializable types, which can perform
  32.  * better validation and provide more efficient encodings than this class is
  33.  * capable. TupleWritable relies on the join framework for type safety and
  34.  * assumes its instances will rarely be persisted, assumptions not only
  35.  * incompatible with, but contrary to the general case.
  36.  *
  37.  * @see org.apache.hadoop.io.Writable
  38.  */
  39. public class TupleWritable implements Writable, Iterable<Writable> {
  40.   private long written;
  41.   private Writable[] values;
  42.   /**
  43.    * Create an empty tuple with no allocated storage for writables.
  44.    */
  45.   public TupleWritable() { }
  46.   /**
  47.    * Initialize tuple with storage; unknown whether any of them contain
  48.    * &quot;written&quot; values.
  49.    */
  50.   public TupleWritable(Writable[] vals) {
  51.     written = 0L;
  52.     values = vals;
  53.   }
  54.   /**
  55.    * Return true if tuple has an element at the position provided.
  56.    */
  57.   public boolean has(int i) {
  58.     return 0 != ((1L << i) & written);
  59.   }
  60.   /**
  61.    * Get ith Writable from Tuple.
  62.    */
  63.   public Writable get(int i) {
  64.     return values[i];
  65.   }
  66.   /**
  67.    * The number of children in this Tuple.
  68.    */
  69.   public int size() {
  70.     return values.length;
  71.   }
  72.   /**
  73.    * {@inheritDoc}
  74.    */
  75.   public boolean equals(Object other) {
  76.     if (other instanceof TupleWritable) {
  77.       TupleWritable that = (TupleWritable)other;
  78.       if (this.size() != that.size() || this.written != that.written) {
  79.         return false;
  80.       }
  81.       for (int i = 0; i < values.length; ++i) {
  82.         if (!has(i)) continue;
  83.         if (!values[i].equals(that.get(i))) {
  84.           return false;
  85.         }
  86.       }
  87.       return true;
  88.     }
  89.     return false;
  90.   }
  91.   public int hashCode() {
  92.     assert false : "hashCode not designed";
  93.     return (int)written;
  94.   }
  95.   /**
  96.    * Return an iterator over the elements in this tuple.
  97.    * Note that this doesn't flatten the tuple; one may receive tuples
  98.    * from this iterator.
  99.    */
  100.   public Iterator<Writable> iterator() {
  101.     final TupleWritable t = this;
  102.     return new Iterator<Writable>() {
  103.       long i = written;
  104.       long last = 0L;
  105.       public boolean hasNext() {
  106.         return 0L != i;
  107.       }
  108.       public Writable next() {
  109.         last = Long.lowestOneBit(i);
  110.         if (0 == last)
  111.           throw new NoSuchElementException();
  112.         i ^= last;
  113.         // numberOfTrailingZeros rtn 64 if lsb set
  114.         return t.get(Long.numberOfTrailingZeros(last) % 64);
  115.       }
  116.       public void remove() {
  117.         t.written ^= last;
  118.         if (t.has(Long.numberOfTrailingZeros(last))) {
  119.           throw new IllegalStateException("Attempt to remove non-existent val");
  120.         }
  121.       }
  122.     };
  123.   }
  124.   /**
  125.    * Convert Tuple to String as in the following.
  126.    * <tt>[<child1>,<child2>,...,<childn>]</tt>
  127.    */
  128.   public String toString() {
  129.     StringBuffer buf = new StringBuffer("[");
  130.     for (int i = 0; i < values.length; ++i) {
  131.       buf.append(has(i) ? values[i].toString() : "");
  132.       buf.append(",");
  133.     }
  134.     if (values.length != 0)
  135.       buf.setCharAt(buf.length() - 1, ']');
  136.     else
  137.       buf.append(']');
  138.     return buf.toString();
  139.   }
  140.   // Writable
  141.   /** Writes each Writable to <code>out</code>.
  142.    * TupleWritable format:
  143.    * {@code
  144.    *  <count><type1><type2>...<typen><obj1><obj2>...<objn>
  145.    * }
  146.    */
  147.   public void write(DataOutput out) throws IOException {
  148.     WritableUtils.writeVInt(out, values.length);
  149.     WritableUtils.writeVLong(out, written);
  150.     for (int i = 0; i < values.length; ++i) {
  151.       Text.writeString(out, values[i].getClass().getName());
  152.     }
  153.     for (int i = 0; i < values.length; ++i) {
  154.       if (has(i)) {
  155.         values[i].write(out);
  156.       }
  157.     }
  158.   }
  159.   /**
  160.    * {@inheritDoc}
  161.    */
  162.   @SuppressWarnings("unchecked") // No static typeinfo on Tuples
  163.   public void readFields(DataInput in) throws IOException {
  164.     int card = WritableUtils.readVInt(in);
  165.     values = new Writable[card];
  166.     written = WritableUtils.readVLong(in);
  167.     Class<? extends Writable>[] cls = new Class[card];
  168.     try {
  169.       for (int i = 0; i < card; ++i) {
  170.         cls[i] = Class.forName(Text.readString(in)).asSubclass(Writable.class);
  171.       }
  172.       for (int i = 0; i < card; ++i) {
  173.           values[i] = cls[i].newInstance();
  174.         if (has(i)) {
  175.           values[i].readFields(in);
  176.         }
  177.       }
  178.     } catch (ClassNotFoundException e) {
  179.       throw (IOException)new IOException("Failed tuple init").initCause(e);
  180.     } catch (IllegalAccessException e) {
  181.       throw (IOException)new IOException("Failed tuple init").initCause(e);
  182.     } catch (InstantiationException e) {
  183.       throw (IOException)new IOException("Failed tuple init").initCause(e);
  184.     }
  185.   }
  186.   /**
  187.    * Record that the tuple contains an element at the position provided.
  188.    */
  189.   void setWritten(int i) {
  190.     written |= 1L << i;
  191.   }
  192.   /**
  193.    * Record that the tuple does not contain an element at the position
  194.    * provided.
  195.    */
  196.   void clearWritten(int i) {
  197.     written &= -1 ^ (1L << i);
  198.   }
  199.   /**
  200.    * Clear any record of which writables have been written to, without
  201.    * releasing storage.
  202.    */
  203.   void clearWritten() {
  204.     written = 0L;
  205.   }
  206. }