1 /**
2  *
3  * Copyright (c) 2005, European Commission project OneLab under contract 034819 (http://www.one-lab.org)
4  * All rights reserved.
5  * Redistribution and use in source and binary forms, with or
6  * without modification, are permitted provided that the following
7  * conditions are met:
8  *  - Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  - Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the distribution.
13  *  - Neither the name of the University Catholique de Louvain - UCL
14  *    nor the names of its contributors may be used to endorse or
15  *    promote products derived from this software without specific prior
16  *    written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /**
33  * Licensed to the Apache Software Foundation (ASF) under one
34  * or more contributor license agreements.  See the NOTICE file
35  * distributed with this work for additional information
36  * regarding copyright ownership.  The ASF licenses this file
37  * to you under the Apache License, Version 2.0 (the
38  * "License"); you may not use this file except in compliance
39  * with the License.  You may obtain a copy of the License at
40  *
41  *     http://www.apache.org/licenses/LICENSE-2.0
42  *
43  * Unless required by applicable law or agreed to in writing, software
44  * distributed under the License is distributed on an "AS IS" BASIS,
45  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46  * See the License for the specific language governing permissions and
47  * limitations under the License.
48  */
49 package org.apache.hadoop.util.bloom;
50 
51 import java.io.DataInput;
52 import java.io.DataOutput;
53 import java.io.IOException;
54 
55 import org.apache.hadoop.io.WritableComparable;
56 
57 /**
58  * The general behavior of a key that must be stored in a filter.
59  *
60  * @see Filter The general behavior of a filter
61  */
62 public class Key implements WritableComparable<Key> {
63   /** Byte value of key */
64   byte[] bytes;
65 
66   /**
67    * The weight associated to <i>this</i> key.
68    * <p>
69    * <b>Invariant</b>: if it is not specified, each instance of
70    * <code>Key</code> will have a default weight of 1.0
71    */
72   double weight;
73 
74   /** default constructor - use with readFields */
Key()75   public Key() {}
76 
77   /**
78    * Constructor.
79    * <p>
80    * Builds a key with a default weight.
81    * @param value The byte value of <i>this</i> key.
82    */
Key(byte[] value)83   public Key(byte[] value) {
84     this(value, 1.0);
85   }
86 
87   /**
88    * Constructor.
89    * <p>
90    * Builds a key with a specified weight.
91    * @param value The value of <i>this</i> key.
92    * @param weight The weight associated to <i>this</i> key.
93    */
Key(byte[] value, double weight)94   public Key(byte[] value, double weight) {
95     set(value, weight);
96   }
97 
98   /**
99    * @param value
100    * @param weight
101    */
set(byte[] value, double weight)102   public void set(byte[] value, double weight) {
103     if (value == null) {
104       throw new IllegalArgumentException("value can not be null");
105     }
106     this.bytes = value;
107     this.weight = weight;
108   }
109 
110   /** @return byte[] The value of <i>this</i> key. */
getBytes()111   public byte[] getBytes() {
112     return this.bytes;
113   }
114 
115   /** @return Returns the weight associated to <i>this</i> key. */
getWeight()116   public double getWeight() {
117     return weight;
118   }
119 
120   /**
121    * Increments the weight of <i>this</i> key with a specified value.
122    * @param weight The increment.
123    */
incrementWeight(double weight)124   public void incrementWeight(double weight) {
125     this.weight += weight;
126   }
127 
128   /** Increments the weight of <i>this</i> key by one. */
incrementWeight()129   public void incrementWeight() {
130     this.weight++;
131   }
132 
133   @Override
equals(Object o)134   public boolean equals(Object o) {
135     if (!(o instanceof Key)) {
136       return false;
137     }
138     return this.compareTo((Key)o) == 0;
139   }
140 
141   @Override
hashCode()142   public int hashCode() {
143     int result = 0;
144     for (int i = 0; i < bytes.length; i++) {
145       result ^= Byte.valueOf(bytes[i]).hashCode();
146     }
147     result ^= Double.valueOf(weight).hashCode();
148     return result;
149   }
150 
151   // Writable
152 
write(DataOutput out)153   public void write(DataOutput out) throws IOException {
154     out.writeInt(bytes.length);
155     out.write(bytes);
156     out.writeDouble(weight);
157   }
158 
readFields(DataInput in)159   public void readFields(DataInput in) throws IOException {
160     this.bytes = new byte[in.readInt()];
161     in.readFully(this.bytes);
162     weight = in.readDouble();
163   }
164 
165   // Comparable
166 
compareTo(Key other)167   public int compareTo(Key other) {
168     int result = this.bytes.length - other.getBytes().length;
169     for (int i = 0; result == 0 && i < bytes.length; i++) {
170       result = this.bytes[i] - other.bytes[i];
171     }
172 
173     if (result == 0) {
174       result = Double.valueOf(this.weight - other.weight).intValue();
175     }
176     return result;
177   }
178 }