dongzhong2018 2017-10-01 16:03
浏览 288
已采纳

Go LevelDB中重复键的覆盖/抛出错误

When using the following code below I expect to have only one entry in the db. I use the syndtr/goleveldb LevelDB implementation for Go.

for count := 0; count < 5; count++ {
    err := db.Put([]byte("key"), []byte("value"))
    if err != nil {
        t.Error(err)
    }
}

Instead, a hexdump reveals that there are 5 entries:

00000000  a8 ef d2 d4 17 00 01 01  00 00 00 00 00 00 00 01  |................|
00000010  00 00 00 01 03 6b 65 79  05 76 61 6c 75 65 10 23  |.....key.value.#|
00000020  44 b5 17 00 01 02 00 00  00 00 00 00 00 01 00 00  |D...............|
00000030  00 01 03 6b 65 79 05 76  61 6c 75 65 77 be 34 95  |...key.valuew.4.|
00000040  17 00 01 03 00 00 00 00  00 00 00 01 00 00 00 01  |................|
00000050  03 6b 65 79 05 76 61 6c  75 65 08 35 86 60 17 00  |.key.value.5.`..|
00000060  01 04 00 00 00 00 00 00  00 01 00 00 00 01 03 6b  |...............k|
00000070  65 79 05 76 61 6c 75 65  6f 8c f6 00 17 00 01 05  |ey.valueo.......|
00000080  00 00 00 00 00 00 00 01  00 00 00 01 03 6b 65 79  |.............key|
00000090  05 76 61 6c 75 65                                 |.value|
00000096

From my understanding LevelDB should by default overwrite any duplicate key or at least throw an error.

How can I control when the value gets overwritten or how can I get an error (other than checking db.Has(key) every time that I db.Put(key)? Does compaction have anything to do with this?

  • 写回答

1条回答

  • dongtang6775 2017-10-01 16:50
    关注

    LevelDB is a log-structured merge-tree and has transaction logs (the ones you were inspecting with hexdump). With this code you can validate that only one value is present for your key:

    package main
    
    import ( "fmt"
    "github.com/syndtr/goleveldb/leveldb"
    )
    
    func main () {
            db, err := leveldb.OpenFile("mydb.test", nil)
            if err != nil { fmt.Println(err) }
    
            for count := 0; count < 5; count++ {
                    err := db.Put([]byte("keys"), []byte("values"), nil)
                    if err != nil {
                        fmt.Println(err)
                    }
            }
    
            iter := db.NewIterator(nil, nil)
            for iter.Next() {
                    key := iter.Key()
                    value := iter.Value()
                    fmt.Println(string(key), string(value))
            }
            iter.Release()
    
            defer db.Close()
    }
    

    How can I control when the value gets overwritten?

    You can't, if the key is present, its value gets overwritten

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

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器