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

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

    点赞 评论

相关推荐 更多相似问题