douzi4724 2013-05-08 14:01
浏览 93
已采纳

按字节比较varint编码的int64

I'm using levigo, the leveldb bindings for Go. My keys are int64's and need to be kept sorted. By default, leveldb uses a bytewise comparator so I'm trying to use varint encoding.

func i2b(x int64) []byte {
    b := make([]byte, binary.MaxVarintLen64)
    n := binary.PutVarint(b, x)
    return key[:n]
}

My keys are not being sorted correctly. I wrote the following as a test.

var prev int64 = 0
for i := int64(1); i < 1e5; i++ {
    if bytes.Compare(i2b(i), i2b(prev)) <= 0 {
        log.Fatalf("bytewise: %d > %d", b2i(prev), i)
    }
    prev = i
}

output: bytewise: 127 > 128

playground

I'm not sure where the problem is. Am I doing the encoding wrong? Is varint not the right encoding to use?

EDIT:

BigEndian fixed width encoding is bytewise comparable

func i2b(x int64) []byte {
  b := make([]byte, 8)
  binary.BigEndian.PutUint64(b, uint64(x))
  return b
}
  • 写回答

1条回答 默认 最新

  • dsiuy42084 2013-05-08 14:23
    关注

    The varint encoding is not bytewise comparable* wrt to the order of the values it caries. One option how to write the ordering/collating function (cmp bellow) is for example:

    package main
    
    import (
            "encoding/binary"
            "log"
    )
    
    func i2b(x int64) []byte {
            var b [binary.MaxVarintLen64]byte
            return b[:binary.PutVarint(b[:], x)]
    }
    
    func cmp(a, b []byte) int64 {
            x, n := binary.Varint(a)
            if n < 0 {
                    log.Fatal(n)
            }
    
            y, n := binary.Varint(b)
            if n < 0 {
                    log.Fatal(n)
            }
    
            return x - y
    }
    
    func main() {
            var prev int64 = 0
            for i := int64(1); i < 1e5; i++ {
                    if cmp(i2b(i), i2b(prev)) <= 0 {
                            log.Fatal("fail")
                    }
                    prev = i
            }
    }
    

    Playground

    (*) The reason is (also) the bit fiddling performed.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵