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.Map;
35  import java.util.Set;
36  import java.util.concurrent.ConcurrentHashMap;
37  
38  import org.treetank.access.conf.StandardSettings;
39  import org.treetank.api.IMetaEntry;
40  import org.treetank.bucket.interfaces.IBucket;
41  import org.treetank.exception.TTIOException;
42  
43  import com.google.common.hash.HashCode;
44  import com.google.common.hash.Hasher;
45  
46  /**
47   * <h1>MetaBucket</h1>
48   * 
49   * <p>
50   * This bucket stored variable key -> value mappings, whereas elements must implement the {@link IMetaEntry}s.
51   * </p>
52   * 
53   * @author Sebastian Graf, University of Konstanz
54   * @author Marc Kramis, University of Konstanz
55   */
56  public final class MetaBucket implements IBucket {
57  
58      /** Map the hash of a name to its name. */
59      private final ConcurrentHashMap<IMetaEntry, IMetaEntry> mMetaMap;
60  
61      /** Key of this bucket. */
62      private final long mBucketKey;
63  
64      /**
65       * Create name bucket.
66       * 
67       * @param pBucketKey
68       *            key of this bucket
69       */
70      public MetaBucket(final long pBucketKey) {
71          mMetaMap = new ConcurrentHashMap<IMetaEntry, IMetaEntry>();
72          mBucketKey = pBucketKey;
73      }
74  
75      /**
76       * Putting an entry to the map.
77       * 
78       * @param pKey
79       *            to be stored.
80       * @param pVal
81       *            to be stored.
82       * @return if entry already existing, return that one.
83       * @see ConcurrentHashMap#put(Object, Object)
84       */
85      public IMetaEntry put(final IMetaEntry pKey, final IMetaEntry pVal) {
86          return mMetaMap.put(pKey, pVal);
87      }
88  
89      /**
90       * Getting an entry.
91       * 
92       * @param pKey
93       *            to be retrieved
94       * @return the suitable value, if present. Null otherwise
95       * @see ConcurrentHashMap#get(Object)
96       */
97      public IMetaEntry get(final IMetaEntry pKey) {
98          return mMetaMap.get(pKey);
99      }
100 
101     /**
102      * Getting the size.
103      * 
104      * @return the number of entries in this bucket
105      * @see ConcurrentHashMap#size()
106      */
107     public int size() {
108         return mMetaMap.size();
109     }
110 
111     /**
112      * Getting the entry set of the bucket.
113      * 
114      * @return the entry set of this bucket
115      * @see ConcurrentHashMap#entrySet()
116      */
117     public Set<Map.Entry<IMetaEntry, IMetaEntry>> entrySet() {
118         return mMetaMap.entrySet();
119     }
120 
121     /**
122      * Removing an element within this bucket
123      * 
124      * @param pKey
125      *            to be removed
126      * @return the element removed, null otherwise
127      * @see ConcurrentHashMap#remove(Object)
128      */
129     public IMetaEntry remove(final IMetaEntry pKey) {
130         return mMetaMap.remove(pKey);
131     }
132 
133     /**
134      * {@inheritDoc}
135      */
136     @Override
137     public void serialize(final DataOutput pOutput) throws TTIOException {
138         try {
139             pOutput.writeInt(IConstants.METABUCKET);
140             pOutput.writeLong(mBucketKey);
141             pOutput.writeInt(mMetaMap.size());
142             for (final Map.Entry<IMetaEntry, IMetaEntry> key : mMetaMap.entrySet()) {
143                 key.getKey().serialize(pOutput);
144                 key.getValue().serialize(pOutput);
145             }
146         } catch (final IOException exc) {
147             throw new TTIOException(exc);
148         }
149     }
150 
151     /**
152      * {@inheritDoc}
153      */
154     @Override
155     public long getBucketKey() {
156         return mBucketKey;
157     }
158 
159     /**
160      * {@inheritDoc}
161      */
162     @Override
163     public String toString() {
164         return toStringHelper(this).add("mBucketKey", mBucketKey).add("mMetaMap", mMetaMap).toString();
165     }
166 
167     /**
168      * {@inheritDoc}
169      */
170     @Override
171     public int hashCode() {
172         final int prime = 42677;
173         int result = 1;
174         result = prime * result + (int)(mBucketKey ^ (mBucketKey >>> 32));
175         result = prime * result + ((mMetaMap == null) ? 0 : mMetaMap.hashCode());
176         return result;
177     }
178 
179     /**
180      * {@inheritDoc}
181      */
182     @Override
183     public boolean equals(Object obj) {
184       return obj.hashCode()==this.hashCode();
185     }
186     
187     /**
188      * {@inheritDoc}
189      */
190     @Override
191     public HashCode  secureHash() {
192         final Hasher code = StandardSettings.HASHFUNC.newHasher().putLong(mBucketKey);
193         for (final IMetaEntry key : mMetaMap.keySet()) {
194             final IMetaEntry val = mMetaMap.get(key);
195             code.putObject(key, key.getFunnel());
196             code.putObject(val, val.getFunnel());
197         }
198         return code.hash();
199     }
200 
201 }