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>UberBucket</h1>
45   * 
46   * <p>
47   * Uber bucket holds a reference to the static revision root bucket tree.
48   * </p>
49   * 
50   * @author Sebastian Graf, University of Konstanz
51   * @author Marc Kramis, University of Konstanz
52   */
53  public final class UberBucket implements IReferenceBucket {
54  
55      /** Number of revisions. */
56      private final long mRevisionCount;
57  
58      /** Reference key for first indirect bucket. */
59      private final long mReferenceKeys[];
60  
61      /** Referenced hashcodes for keys. */
62      private final byte[][] mReferenceHashs;
63  
64      /** Key of this UberBucket. */
65      private final long mBucketKey;
66  
67      /** Counter for new buckets. */
68      private long mBucketCounter;
69  
70      /**
71       * New uber bucket
72       * 
73       * @param pBucketKey
74       *            key of this bucket
75       * @param pRevisionCount
76       *            count of all revisions in this storage
77       * @param pBucketCounter
78       *            Counter for all buckets
79       */
80      public UberBucket(final long pBucketKey, final long pRevisionCount, final long pBucketCounter) {
81          mRevisionCount = pRevisionCount;
82          mReferenceKeys = new long[1];
83          mReferenceHashs = new byte[1][];
84          Arrays.fill(mReferenceHashs, new byte[0]);
85          mBucketKey = pBucketKey;
86          mBucketCounter = pBucketCounter;
87      }
88  
89      /**
90       * Get revision key of current in-memory state.
91       * 
92       * @return Revision key.
93       */
94      public long getRevisionNumber() {
95          return mRevisionCount;
96      }
97  
98      /**
99       * {@inheritDoc}
100      */
101     @Override
102     public void serialize(final DataOutput pOutput) throws TTIOException {
103         try {
104             pOutput.writeInt(IConstants.UBERBUCKET);
105             pOutput.writeLong(mBucketKey);
106             pOutput.writeLong(mRevisionCount);
107             pOutput.writeLong(mBucketCounter);
108             pOutput.writeLong(mReferenceKeys[0]);
109             pOutput.writeInt(mReferenceHashs[0].length);
110             pOutput.write(mReferenceHashs[0]);
111         } catch (final IOException exc) {
112             throw new TTIOException(exc);
113         }
114     }
115 
116     /**
117      * {@inheritDoc}
118      */
119     @Override
120     public long getBucketKey() {
121         return mBucketKey;
122     }
123 
124     /**
125      * Incrementing the counter.
126      * 
127      * @return the incremented counter
128      */
129     public long incrementBucketCounter() {
130         mBucketCounter = mBucketCounter + 1;
131         return mBucketCounter;
132     }
133 
134     /**
135      * Getter for mBucketCounter.
136      * 
137      * @return the mBucketCounter
138      */
139     public long getBucketCounter() {
140         return mBucketCounter;
141     }
142 
143     /**
144      * {@inheritDoc}
145      */
146     @Override
147     public long[] getReferenceKeys() {
148         return mReferenceKeys;
149     }
150 
151     /**
152      * {@inheritDoc}
153      */
154     @Override
155     public void setReferenceKey(int pIndex, long pKey) {
156         mReferenceKeys[pIndex] = pKey;
157     }
158 
159     /**
160      * {@inheritDoc}
161      */
162     @Override
163     public String toString() {
164         return toStringHelper(this).add("mBucketKey", mBucketKey).add("mBucketCounter", mBucketCounter).add(
165             "mRevisionCount", mRevisionCount).add("mReferenceKeys", Arrays.toString(mReferenceKeys)).add(
166             "mReferenceHashs", Arrays.toString(mReferenceHashs)).toString();
167     }
168 
169     /**
170      * {@inheritDoc}
171      */
172     @Override
173     public byte[][] getReferenceHashs() {
174         return mReferenceHashs;
175     }
176 
177     /**
178      * {@inheritDoc}
179      */
180     @Override
181     public void setReferenceHash(int pIndex, byte[] pHash) {
182         mReferenceHashs[pIndex] = pHash;
183     }
184 
185     /**
186      * {@inheritDoc}
187      */
188     @Override
189     public int hashCode() {
190         final int prime = 17207;
191         int result = 1;
192         result = prime * result + (int)(mBucketCounter ^ (mBucketCounter >>> 32));
193         result = prime * result + (int)(mBucketKey ^ (mBucketKey >>> 32));
194         for (byte[] hash : mReferenceHashs) {
195             result = prime * result + Arrays.hashCode(hash);
196         }
197         result = prime * result + Arrays.hashCode(mReferenceKeys);
198         result = prime * result + (int)(mRevisionCount ^ (mRevisionCount >>> 32));
199         return result;
200     }
201 
202     /**
203      * {@inheritDoc}
204      */
205     @Override
206     public boolean equals(Object obj) {
207         return obj.hashCode() == this.hashCode();
208     }
209 
210     /**
211      * {@inheritDoc}
212      */
213     @Override
214     public HashCode secureHash() {
215         final Hasher code =
216             StandardSettings.HASHFUNC.newHasher().putLong(mBucketKey).putLong(mRevisionCount).putLong(
217                 mBucketCounter);
218         for (int i = 0; i < mReferenceKeys.length; i++) {
219             code.putLong(mReferenceKeys[i]);
220             code.putBytes(mReferenceHashs[i]);
221         }
222         return code.hash();
223     }
224 }