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  }