FingerPrint:go转java源码解析

43 篇文章 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还是负数,要变正数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白速龙王的回眸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值