View Javadoc

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.giraph.writable.kryo;
19  
20  import java.io.DataInput;
21  import java.io.DataOutput;
22  import java.io.IOException;
23  
24  import org.apache.giraph.utils.WritableUtils;
25  import org.apache.hadoop.io.Writable;
26  
27  /**
28   * Generic wrapper object, making any object writable.
29   *
30   * Uses Kryo inside for serialization.
31   * Current configuration is not optimized for performance,
32   * but Writable interface doesn't allow much room for it.
33   *
34   * Note - Java8 lambdas need to implement Serializable to work.
35   *
36   * @param <T> Object type
37   */
38  public class KryoWritableWrapper<T> implements Writable {
39    /** Wrapped object */
40    private T object;
41  
42    /**
43     * Create wrapper given an object.
44     * @param object Object instance
45     */
46    public KryoWritableWrapper(T object) {
47      this.object = object;
48    }
49  
50    /**
51     * Creates wrapper initialized with null.
52     */
53    public KryoWritableWrapper() {
54    }
55  
56    /**
57     * Unwrap the object value
58     * @return Object value
59     */
60    public T get() {
61      return object;
62    }
63  
64    /**
65     * Set wrapped object value
66     * @param object New object value
67     */
68    public void set(T object) {
69      this.object = object;
70    }
71  
72    @Override
73    public void readFields(DataInput in) throws java.io.IOException {
74      object = HadoopKryo.readClassAndObject(in);
75    }
76  
77    @Override
78    public void write(DataOutput out) throws IOException {
79      HadoopKryo.writeClassAndObject(out, object);
80    }
81  
82    /**
83     * Returns Writable instance, wrapping given object only
84     * if it is not already writable.
85     *
86     * @param object Object to potentially wrap
87     * @return Writable object holding argument
88     */
89    public static Writable wrapIfNeeded(Object object) {
90      if (object instanceof Writable) {
91        return (Writable) object;
92      } else {
93        return new KryoWritableWrapper<>(object);
94      }
95    }
96  
97    /**
98     * Unwrap Writable object if it was wrapped initially,
99     * inverse of wrapIfNeeded function.
100    * @param value Potentially wrapped value
101    * @return Original unwrapped value
102    * @param <T> Type of returned object.
103    */
104   public static <T> T unwrapIfNeeded(Writable value) {
105     if (value instanceof KryoWritableWrapper) {
106       return ((KryoWritableWrapper<T>) value).get();
107     } else {
108       return (T) value;
109     }
110   }
111 
112   /**
113    * Wrap object with KryoWritableWrapper, create a writable copy of it,
114    * and then unwrap it, allowing any object to be copied.
115    *
116    * @param object Object to copy
117    * @return copy of the object
118    * @param <T> Type of the object
119    */
120   public static <T> T wrapAndCopy(T object) {
121     return WritableUtils.createCopy(new KryoWritableWrapper<>(object)).get();
122   }
123 }