package com.meidusa.amoeba.sqljep.function;
import com.meidusa.amoeba.sqljep.ASTFunNode;
import com.meidusa.amoeba.sqljep.JepRuntime;
import com.meidusa.amoeba.sqljep.ParseException;
/**
* 针对String的hash算法
*
* @author hexianmao
* @version 2008-10-27 下午05:49:02
*/
public class StringHash extends PostfixCommand {
private static final int _hash_len = 8;
private static final int _bit_len = 5;
private static final long _unknown = -1L;
public int getNumberOfParameters() {
return 1;
}
public Comparable<?>[] evaluate(ASTFunNode node, JepRuntime runtime) throws ParseException {
node.childrenAccept(runtime.ev, null);
Comparable<?> param = runtime.stack.pop();
return new Comparable<?>[] { param };
}
public Comparable<?> getResult(Comparable<?>... comparables) throws ParseException {
if (comparables[0] != null && comparables[0] instanceof String) {
return hash((String) comparables[0]);
}
return _unknown;
}
/**
* <pre>
* 字符串hash算法:s[0]*31ˆ(n-1) + s[1]*31ˆ(n-2) + ... + s[n-1]
* 其中s[]为字符串的字符数组,换算成程序的表达式为:
* h = 31*h + s.charAt(i); => h = (h << 5) - h + s.charAt(i);
* 注:对hash的字符串做了长度限定,保证其结果不会超出数据类型的范围。
* </pre>
*/
private static long hash(String s) {
long h = 0;
for (int i = 0; (i < _hash_len && i < s.length()); i++) {
h = (h << _bit_len) - h + s.charAt(i);
}
return h;
}
}