View Javadoc

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 }