FingerPrint:go转java源码解析

FingerPrint:go转java源码解析,第1张

需求:
对数据库做一个哈希压缩吧,用数字指纹

看看go源码:

package main

import (
	"fmt"
)

type Label struct {
	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Value                string   `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

var (
	labelsB = []*Label{
		{Name: "__name__", Value: "http_requests_total"},
		{Name: "code", Value: "200"},
		{Name: "handler", Value: "query"},
	}
	expectedB = uint64(0x145426e4f81508d1)
)
const (
	offset64      uint64 = 14695981039346656037
	prime64       uint64 = 1099511628211
	separatorByte byte   = 255
)

// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
func hashAdd(h uint64, s string) uint64 {
	fmt.Println(len(s))
	for i := 0; i < len(s); i++ {
		fmt.Printf("%v\n",s[i])
		h ^= uint64(s[i])
		//fmt.Println(h)
		h *= prime64
		//fmt.Println(h)
	}
	return h
}

// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
func hashAddByte(h uint64, b byte) uint64 {
	h ^= uint64(b)
	h *= prime64
	return h
}

// Fingerprint calculates a fingerprint of SORTED BY NAME labels.
// It is adopted from labelSetToFingerprint, but avoids type conversions and memory allocations.
func Fingerprint(labels []*Label) uint64 {
	if len(labels) == 0 {
		return offset64
	}

	sum := offset64
	for _, l := range labels {
		println(l.Name, l.Value)
		sum = hashAdd(sum, l.Name)
		println(sum)
		sum = hashAddByte(sum, separatorByte)
		println(sum)
		sum = hashAdd(sum, l.Value)
		println(sum)
		sum = hashAddByte(sum, separatorByte)
		println(sum)
		println()
	}
	return sum
}

func main() {
	/*mylabel := []*Label{
		{Name: "__name__", Value: "up"},
		{Name: "instance", Value: "promhouse_clickhouse_exporter_1:9116"},
		{Name: "job", Value: "clickhouse"},
	}
	fmt.Println(Fingerprint(mylabel))

	 */
	fmt.Println(hashAdd(offset64, "一体化"))
}

转成java


import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;


public class FingerPrint
{
    private static final BigInteger offset64 = new BigInteger("14695981039346656037");
    private static final BigInteger prime64 = new BigInteger("1099511628211");
    private static final String separatorByte = "255";
    private static Gson gson = new GsonBuilder().serializeNulls().create();

    public static void main(String[] args)
    {

        
        //System.out.println(hashAdd(offset64, "__name__"));
        //System.out.println(hashAdd(offset64, "一体化"));

    }

    public static BigInteger hashAdd(BigInteger h, String s)
    {
        String[] strings = s.split("");
        for (int i=0; i<s.length(); i++)
        {
            //System.out.println(strings[i]);
            //System.out.println(strings[i].getBytes().length);
            //中文的编码有三位,逐位解析
            for(byte b: strings[i].getBytes()) {
                //System.out.println((b + 256) % 256);
                //将中文编码变为正数
                h = h.xor(BigInteger.valueOf((b + 256) % 256));
                //根据go的uint64的限制进行mod
                h = h.multiply(prime64).mod(new BigInteger("18446744073709551616"));
            }
            //h = h.xor(new BigInteger(strings[i].getBytes()));
            //System.out.println(h);
            //h = h.multiply(prime64).mod(new BigInteger("18446744073709551616"));
            //System.out.println(h);
        }
        return h;
    }

    public static BigInteger hashAddByte(BigInteger h, String s)
    {
        h = h.xor(new BigInteger(s));
        h = h.multiply(prime64).mod(new BigInteger("18446744073709551616"));
        return h;
    }

    public static BigInteger fingerprint(JsonObject prometheusLabelJsonObject)
    {
        if (prometheusLabelJsonObject.size()==0)
        {
            return offset64;
        }
        else
        {
            BigInteger sum = new BigInteger(String.valueOf(offset64));
            for(Map.Entry<String, JsonElement> entry : prometheusLabelJsonObject.entrySet())
            {
                //System.out.println(entry.getKey());
                //System.out.println(entry.getValue().getAsString());
                sum = hashAdd(sum, entry.getKey());
                //System.out.println(sum);
                sum = hashAddByte(sum, separatorByte);
                //System.out.println(sum);
                sum = hashAdd(sum, entry.getValue().getAsString());
                //System.out.println(sum);
                sum = hashAddByte(sum, separatorByte);
                //System.out.println(sum);
                //System.out.println();
            }
            return sum;
        }
    }
}

代码转换坑点:
1.java用大数
2.go uint64要除上界
3.go对中文的处理直接分三个ascii(0-256), java三合1还是负数,要变正数

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/996106.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存