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

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

报告相同问题?

悬赏问题

  • ¥30 vmware exsi重置后登不上
  • ¥15 易盾点选的cb参数怎么解啊
  • ¥15 MATLAB运行显示错误,如何解决?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?
  • ¥15 电磁场的matlab仿真
  • ¥15 mars2d在vue3中的引入问题
  • ¥50 h5唤醒支付宝并跳转至向小荷包转账界面