View Javadoc

1   /**
2    * Copyright (c) 2011, University of Konstanz, Distributed Systems Group
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    * * Redistributions of source code must retain the above copyright
8    * notice, this list of conditions and the following disclaimer.
9    * * Redistributions in binary form must reproduce the above copyright
10   * notice, this list of conditions and the following disclaimer in the
11   * documentation and/or other materials provided with the distribution.
12   * * Neither the name of the University of Konstanz nor the
13   * names of its contributors may be used to endorse or promote products
14   * derived from this software without specific prior written permission.
15   * 
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20   * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   */
27  
28  package org.treetank.io;
29  
30  import static com.google.common.base.Objects.toStringHelper;
31  
32  import java.io.DataInput;
33  import java.io.DataInputStream;
34  import java.io.DataOutput;
35  import java.io.DataOutputStream;
36  import java.io.IOException;
37  
38  import org.treetank.api.IMetaEntryFactory;
39  import org.treetank.api.IDataFactory;
40  import org.treetank.bucket.DataBucket;
41  import org.treetank.bucket.BucketFactory;
42  import org.treetank.bucket.interfaces.IBucket;
43  import org.treetank.exception.TTIOException;
44  
45  import com.sleepycat.bind.tuple.TupleBinding;
46  import com.sleepycat.bind.tuple.TupleInput;
47  import com.sleepycat.bind.tuple.TupleOutput;
48  
49  /**
50   * <h1>LogValue</h1> 
51   * 
52   * This class acts as a container for revisioned {@link DataBucket}s. Each
53   * {@link DataBucket} is stored in a versioned manner. If
54   * modifications occur, the versioned {@link DataBucket}s are dereferenced and
55   * reconstructed. Afterwards, this container is used to store a complete {@link DataBucket} as well as one for
56   * upcoming modifications.
57   * 
58   * Both {@link DataBucket}s can differ since the complete one is mainly used for
59   * read access and the modifying one for write access (and therefore mostly lazy
60   * dereferenced).
61   * 
62   * Since objects of this class are stored in a cache, the class has to be
63   * serializable.
64   * 
65   * @author Sebastian Graf, University of Konstanz
66   * 
67   */
68  public final class LogValue {
69  
70      private final IBucket mComplete;
71  
72      private final IBucket mModified;
73  
74      /**
75       * Constructor with both, complete and modifying bucket.
76       * 
77       * @param pComplete
78       *            to be used as a base for this container
79       * @param pModifying
80       *            to be used as a base for this container
81       */
82      public LogValue(final IBucket pComplete, final IBucket pModifying) {
83          this.mComplete = pComplete;
84          this.mModified = pModifying;
85      }
86  
87      /**
88       * Getting the complete bucket.
89       * 
90       * @return the complete bucket
91       */
92      public IBucket getComplete() {
93          return mComplete;
94      }
95  
96      /**
97       * Getting the modified bucket.
98       * 
99       * @return the modified bucket
100      */
101     public IBucket getModified() {
102         return mModified;
103     }
104 
105  
106     /**
107      * {@inheritDoc}
108      */
109     @Override
110     public String toString() {
111         return toStringHelper(this).add("mComplete", mComplete).add("mModified", mModified).toString();
112     }
113 
114     /**
115      * Binding for serializing LogValues in the BDB.
116      * 
117      * @author Sebastian Graf, University of Konstanz
118      * 
119      */
120     static class LogValueBinding extends TupleBinding<LogValue> {
121 
122         private final BucketFactory mFac;
123 
124         /**
125          * Constructor
126          * 
127          * @param pDataFac
128          *            for the deserialization of datas
129          * @param pMetaFac
130          *            for the deserialization of meta-entries
131          */
132         public LogValueBinding(final IDataFactory pDataFac, final IMetaEntryFactory pMetaFac) {
133             mFac = new BucketFactory(pDataFac, pMetaFac);
134         }
135 
136         /**
137          * {@inheritDoc}
138          */
139         @Override
140         public LogValue entryToObject(final TupleInput arg0) {
141             try {
142                 final DataInput data = new DataInputStream(arg0);
143                 final IBucket current = mFac.deserializeBucket(data);
144                 final IBucket modified = mFac.deserializeBucket(data);
145                 arg0.close();
146                 return new LogValue(current, modified);
147             } catch (IOException | TTIOException exc) {
148                 throw new RuntimeException(exc);
149             }
150         }
151 
152         /**
153          * {@inheritDoc}
154          */
155         @Override
156         public void objectToEntry(final LogValue arg0, final TupleOutput arg1) {
157             try {
158                 final DataOutput data = new DataOutputStream(arg1);
159                 arg0.getComplete().serialize(data);
160                 arg0.getModified().serialize(data);
161                 arg1.close();
162             } catch (IOException | TTIOException exc) {
163                 throw new RuntimeException(exc);
164             }
165         }
166     }
167 
168     /**
169      * {@inheritDoc}
170      */
171     @Override
172     public int hashCode() {
173         final int prime = 80309;
174         int result = 1;
175         result = prime * result + ((mComplete == null) ? 0 : mComplete.hashCode());
176         result = prime * result + ((mModified == null) ? 0 : mModified.hashCode());
177         return result;
178     }
179 
180     /**
181      * {@inheritDoc}
182      */
183     @Override
184     public boolean equals(Object obj) {
185         if (this == obj)
186             return true;
187         if (obj == null)
188             return false;
189         if (getClass() != obj.getClass())
190             return false;
191         LogValue other = (LogValue)obj;
192         if (mComplete == null) {
193             if (other.mComplete != null)
194                 return false;
195         } else if (!mComplete.equals(other.mComplete))
196             return false;
197         if (mModified == null) {
198             if (other.mModified != null)
199                 return false;
200         } else if (!mModified.equals(other.mModified))
201             return false;
202         return true;
203     }
204 }