github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/cmd/pebble/db.go (about) 1 // Copyright 2019 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package main 6 7 import ( 8 "log" 9 10 "github.com/petermattis/pebble" 11 "github.com/petermattis/pebble/cache" 12 "github.com/petermattis/pebble/internal/bytealloc" 13 ) 14 15 // DB specifies the minimal interfaces that need to be implemented to support 16 // the pebble command. 17 type DB interface { 18 NewIter(*pebble.IterOptions) iterator 19 NewBatch() batch 20 Scan(key []byte, count int64, reverse bool) error 21 Metrics() *pebble.VersionMetrics 22 Flush() error 23 } 24 25 type iterator interface { 26 SeekGE(key []byte) bool 27 Valid() bool 28 Key() []byte 29 Value() []byte 30 First() bool 31 Next() bool 32 Last() bool 33 Prev() bool 34 Close() error 35 } 36 37 type batch interface { 38 Commit(opts *pebble.WriteOptions) error 39 Set(key, value []byte, opts *pebble.WriteOptions) error 40 LogData(data []byte, opts *pebble.WriteOptions) error 41 Repr() []byte 42 } 43 44 // Adapters for Pebble. Since the interfaces above are based on Pebble's 45 // interfaces, it can simply forward calls for everything. 46 type pebbleDB struct { 47 d *pebble.DB 48 } 49 50 func newPebbleDB(dir string) DB { 51 opts := &pebble.Options{ 52 Cache: cache.New(cacheSize), 53 Comparer: mvccComparer, 54 DisableWAL: disableWAL, 55 MemTableSize: 64 << 20, 56 MemTableStopWritesThreshold: 4, 57 MinCompactionRate: 4 << 20, // 4 MB/s 58 MinFlushRate: 1 << 20, // 1 MB/s 59 L0CompactionThreshold: 2, 60 L0StopWritesThreshold: 32, 61 LBaseMaxBytes: 64 << 20, // 64 MB 62 Levels: []pebble.LevelOptions{{ 63 BlockSize: 32 << 10, 64 }}, 65 Merger: &pebble.Merger{ 66 Name: "cockroach_merge_operator", 67 }, 68 } 69 opts.EnsureDefaults() 70 71 if verbose { 72 opts.EventListener = pebble.MakeLoggingEventListener(nil) 73 opts.EventListener.TableDeleted = nil 74 opts.EventListener.TableIngested = nil 75 opts.EventListener.WALCreated = nil 76 opts.EventListener.WALDeleted = nil 77 } 78 79 p, err := pebble.Open(dir, opts) 80 if err != nil { 81 log.Fatal(err) 82 } 83 return pebbleDB{p} 84 } 85 86 func (p pebbleDB) Flush() error { 87 return p.d.Flush() 88 } 89 90 func (p pebbleDB) NewIter(opts *pebble.IterOptions) iterator { 91 return p.d.NewIter(opts) 92 } 93 94 func (p pebbleDB) NewBatch() batch { 95 return p.d.NewBatch() 96 } 97 98 func (p pebbleDB) Scan(key []byte, count int64, reverse bool) error { 99 var data bytealloc.A 100 iter := p.d.NewIter(nil) 101 if reverse { 102 for i, valid := 0, iter.SeekLT(key); valid; valid = iter.Prev() { 103 data, _ = data.Copy(iter.Key()) 104 data, _ = data.Copy(iter.Value()) 105 i++ 106 if i >= int(count) { 107 break 108 } 109 } 110 } else { 111 for i, valid := 0, iter.SeekGE(key); valid; valid = iter.Next() { 112 data, _ = data.Copy(iter.Key()) 113 data, _ = data.Copy(iter.Value()) 114 i++ 115 if i >= int(count) { 116 break 117 } 118 } 119 } 120 return iter.Close() 121 } 122 123 func (p pebbleDB) Metrics() *pebble.VersionMetrics { 124 return p.d.Metrics() 125 }