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.bucket;
29  
30  import static com.google.common.base.Objects.toStringHelper;
31  
32  import java.io.DataOutput;
33  import java.io.IOException;
34  import java.util.Arrays;
35  
36  import org.treetank.access.conf.StandardSettings;
37  import org.treetank.bucket.interfaces.IReferenceBucket;
38  import org.treetank.exception.TTIOException;
39  
40  import com.google.common.hash.HashCode;
41  import com.google.common.hash.Hasher;
42  
43  /**
44   * <h1>RevisionRootBucket</h1>
45   * 
46   * <p>
47   * Revision root bucket holds a reference to the name bucket as well as the static data-bucket tree.
48   * </p>
49   * 
50   * @author Sebastian Graf, University of Konstanz
51   * @author Marc Kramis, University of Konstanz
52   */
53  public final class RevisionRootBucket implements IReferenceBucket {
54  
55      /** Offset of name bucket reference. */
56      public static final int META_REFERENCE_OFFSET = 1;
57  
58      /** Last allocated data key. */
59      private long mMaxDataKey;
60  
61      /** Revision of this bucket. */
62      private final long mRevision;
63  
64      /** Reference keys. */
65      private final long[] mReferenceKeys;
66  
67      /** Hashcode of keys. */
68      private final byte[][] mReferenceHashs;
69  
70      /** Key of this bucket. */
71      private final long mBucketKey;
72  
73      /**
74       * Constructor of RevisionRootBuckets.
75       * 
76       * @param pBucketKey
77       *            Key of this bucket
78       * @param pRevision
79       *            to be created
80       * @param pMaxDataKey
81       *            maximal data key given
82       */
83      public RevisionRootBucket(final long pBucketKey, final long pRevision, final long pMaxDataKey) {
84          mRevision = pRevision;
85          mReferenceKeys = new long[2];
86          mReferenceHashs = new byte[2][];
87          Arrays.fill(mReferenceHashs, new byte[0]);
88          mMaxDataKey = pMaxDataKey;
89          mBucketKey = pBucketKey;
90      }
91  
92      /**
93       * Get last allocated data key.
94       * 
95       * @return Last allocated data key.
96       */
97      public long getMaxDataKey() {
98          return mMaxDataKey;
99      }
100 
101     /**
102      * Increment number of datas by one while allocating another key.
103      */
104     public long incrementMaxDataKey() {
105         return mMaxDataKey++;
106     }
107 
108     /**
109      * Getting revision of this root bucket.
110      * 
111      * @return current revision
112      */
113     public long getRevision() {
114         return mRevision;
115     }
116 
117     /**
118      * {@inheritDoc}
119      */
120     @Override
121     public void serialize(final DataOutput pOutput) throws TTIOException {
122         try {
123             pOutput.writeInt(IConstants.REVISIONROOTBUCKET);
124             pOutput.writeLong(mBucketKey);
125             pOutput.writeLong(mRevision);
126             pOutput.writeLong(mMaxDataKey);
127             for (long key : mReferenceKeys) {
128                 pOutput.writeLong(key);
129             }
130             for (byte[] hash : mReferenceHashs) {
131                 pOutput.writeInt(hash.length);
132                 pOutput.write(hash);
133             }
134         } catch (final IOException exc) {
135             throw new TTIOException(exc);
136         }
137     }
138 
139     /**
140      * {@inheritDoc}
141      */
142     @Override
143     public long getBucketKey() {
144         return mBucketKey;
145     }
146 
147     /**
148      * {@inheritDoc}
149      */
150     @Override
151     public long[] getReferenceKeys() {
152         return mReferenceKeys;
153     }
154 
155     /**
156      * {@inheritDoc}
157      */
158     @Override
159     public void setReferenceKey(int pIndex, long pKey) {
160         mReferenceKeys[pIndex] = pKey;
161     }
162 
163     /**
164      * {@inheritDoc}
165      */
166     @Override
167     public String toString() {
168         return toStringHelper(this).add("mBucketKey", mBucketKey).add("mRevision", mRevision).add(
169             "mMaxDataKey", mMaxDataKey).add("mReferenceKeys", Arrays.toString(mReferenceKeys)).add(
170             "mReferenceHashs", Arrays.toString(mReferenceHashs)).toString();
171     }
172 
173     /**
174      * {@inheritDoc}
175      */
176     @Override
177     public byte[][] getReferenceHashs() {
178         return mReferenceHashs;
179     }
180 
181     /**
182      * {@inheritDoc}
183      */
184     @Override
185     public void setReferenceHash(int pIndex, byte[] pHash) {
186         mReferenceHashs[pIndex] = pHash;
187     }
188 
189     /**
190      * {@inheritDoc}
191      */
192     @Override
193     public int hashCode() {
194         final int prime = 53623;
195         int result = 1;
196         result = prime * result + (int)(mBucketKey ^ (mBucketKey >>> 32));
197         result = prime * result + (int)(mMaxDataKey ^ (mMaxDataKey >>> 32));
198         result = prime * result + Arrays.hashCode(mReferenceKeys);
199         for (byte[] hash : mReferenceHashs) {
200             result = prime * result + Arrays.hashCode(hash);
201         }
202         result = prime * result + (int)(mRevision ^ (mRevision >>> 32));
203         return result;
204     }
205 
206     /**
207      * {@inheritDoc}
208      */
209     @Override
210     public boolean equals(Object obj) {
211         return obj.hashCode() == this.hashCode();
212     }
213 
214     /**
215      * {@inheritDoc}
216      */
217     @Override
218     public HashCode secureHash() {
219         final Hasher code =
220             StandardSettings.HASHFUNC.newHasher().putLong(mBucketKey).putLong(mMaxDataKey).putLong(mRevision);
221         for (int i = 0; i < mReferenceKeys.length; i++) {
222             code.putLong(mReferenceKeys[i]);
223             code.putBytes(mReferenceHashs[i]);
224         }
225         return code.hash();
226     }
227 
228 }