1 package org.apache.helix;
2 /*
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 */
20 import java.nio.ByteBuffer;
21
22 public class FnvHashFunction implements HashFunction
23 {
24 private static final long FNV_BASIS = 0x811c9dc5;
25 private static final long FNV_PRIME = (1 << 24) + 0x193;
26
27 @Override
28 public long hash(ByteBuffer buf)
29 {
30 int length = buf.position() + buf.remaining();
31 return hash(buf, 0, length);
32 }
33
34 @Override
35 public long hash(ByteBuffer buf, int off, int len)
36 {
37 long hash = FNV_BASIS;
38
39 int last = Math.min(off + len, buf.position() + buf.remaining());
40
41 for (int i=off; i< last; i++)
42 {
43 hash ^= 0xFF & buf.get(i);
44 hash *= FNV_PRIME;
45 }
46 return hash;
47 }
48
49 public long hash(byte[] key)
50 {
51 long hash = FNV_BASIS;
52 for(int i = 0; i < key.length; i++) {
53 hash ^= 0xFF & key[i];
54 hash *= FNV_PRIME;
55 }
56
57 return hash;
58 }
59
60 @Override
61 public long hash(byte[] key, int numBuckets)
62 {
63 return hash(key)%numBuckets;
64 }
65
66
67 private long hash(long val)
68 {
69 long hashval = FNV_BASIS;
70
71 for(int i = 0; i < 8; i++)
72 {
73 long octet = val & 0x00ff;
74 val = val >> 8;
75
76 hashval = hashval ^ octet;
77 hashval = hashval * FNV_PRIME;
78 }
79 return (int)hashval;
80 }
81
82 @Override
83 public long hash(long val, int numBuckets)
84 {
85 return hash(val)%numBuckets;
86 }
87
88 /*
89 public static void main(String[] args)
90 {
91 byte[] b = new byte[1024*1024*100];
92 ByteBuffer buf = ByteBuffer.allocateDirect(1024*1024*100).order(DbusEvent.byteOrder);
93 Random r = new Random();
94 r.nextBytes(b);
95 buf.put(b);
96
97 FnvHashFunction fun = new FnvHashFunction();
98 CRC32 chksum = new CRC32();
99 JenkinsHashFunction jFun = new JenkinsHashFunction();
100
101 long start = 0;
102 long end = 0;
103 long hash = 0;
104 long diff = 0;
105 long delayMicro = 0;
106
107 chksum.reset();
108 chksum.update(b);
109 long prevhash = chksum.getValue();
110 for (int i = 0; i < 10; i++)
111 {
112 start = System.nanoTime();
113 chksum.reset();
114 chksum.update(b);
115 hash = chksum.getValue();
116 end = System.nanoTime();
117 assert(prevhash == hash);
118 diff += (end - start);
119 }
120
121 delayMicro = (diff/1000)/10;
122
123 System.out.println("Latency of System CRC32 (Micro Seconds) is: " + delayMicro);
124
125 prevhash = fun.hash(b);
126 for (int i = 0; i < 10; i++)
127 {
128 start = System.nanoTime();
129 hash = fun.hash(b);
130 end = System.nanoTime();
131 assert(prevhash == hash);
132 diff += (end - start);
133 }
134 delayMicro = (diff/1000)/10;
135 System.out.println("Latency of FNV (Micro Seconds) is: " + delayMicro);
136
137 prevhash = jFun.hash(b);
138 for (int i = 0; i < 10; i++)
139 {
140 start = System.nanoTime();
141 hash = jFun.hash(b);
142 end = System.nanoTime();
143 assert(prevhash == hash);
144 diff += (end - start);
145 }
146 delayMicro = (diff/1000)/10;
147 System.out.println("Latency of Jenkins (Micro Seconds) is: " + delayMicro);
148
149 prevhash = ByteBufferCRC32.getChecksum(b);
150 for (int i = 0; i < 10; i++)
151 {
152 start = System.nanoTime();
153 hash = ByteBufferCRC32.getChecksum(b);
154 end = System.nanoTime();
155 assert(prevhash == hash);
156 diff += (end - start);
157 }
158 delayMicro = (diff/1000)/10;
159 System.out.println("Latency of ByteBufferCRC32 (Micro Seconds) is: " + delayMicro);
160
161 //System.out.println("Buffer position-Remaining :" + buf.position() + "-" + buf.remaining());
162
163 prevhash = fun.hash(buf);
164 for (int i = 0; i < 10; i++)
165 {
166 start = System.nanoTime();
167 hash = fun.hash(buf);
168 end = System.nanoTime();
169 assert(prevhash == hash);
170 diff += (end - start);
171 }
172 delayMicro = (diff/1000)/10;
173 System.out.println("Latency of FNV (Micro Seconds) for ByteBuffer is: " + delayMicro);
174 //System.out.println("Buffer position-Remaining :" + buf.position() + "-" + buf.remaining());
175
176 prevhash = fun.hash(buf);
177 for (int i = 0; i < 10; i++)
178 {
179 start = System.nanoTime();
180 hash = fun.hash(buf);
181 end = System.nanoTime();
182 assert(prevhash == hash);
183 diff += (end - start);
184 }
185 delayMicro = (diff/1000)/10;
186 System.out.println("Latency of Jenkins (Micro Seconds) for ByteBuffer is: " + delayMicro);
187 //System.out.println("Buffer position-Remaining :" + buf.position() + "-" + buf.remaining());
188 prevhash = ByteBufferCRC32.getChecksum(buf);
189 for (int i = 0; i < 10; i++)
190 {
191 start = System.nanoTime();
192 hash = ByteBufferCRC32.getChecksum(buf);
193 end = System.nanoTime();
194 assert(prevhash == hash);
195 diff += (end - start);
196 }
197 delayMicro = (diff/1000)/10;
198 System.out.println("Latency of ByteBufferCRC32 (Micro Seconds) for ByteBuffer is: " + delayMicro);
199
200 //System.out.println("Buffer position-Remaining :" + buf.position() + "-" + buf.remaining());
201 }
202 */
203 }