mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-22 10:57:42 +08:00
Some checks are pending
CodeQL / codeql (push) Waiting to run
Docker Build / docker-build (push) Waiting to run
Gateway Conformance / gateway-conformance (push) Waiting to run
Gateway Conformance / gateway-conformance-libp2p-experiment (push) Waiting to run
Go Build / go-build (push) Waiting to run
Go Check / go-check (push) Waiting to run
Go Lint / go-lint (push) Waiting to run
Go Test / go-test (push) Waiting to run
Interop / interop-prep (push) Waiting to run
Interop / helia-interop (push) Blocked by required conditions
Interop / ipfs-webui (push) Blocked by required conditions
Sharness / sharness-test (push) Waiting to run
Spell Check / spellcheck (push) Waiting to run
* Update pebble db to latest format by default If the pebble database format is not explicitly set in the config, then set it to the latest format version by default. This will ensure that the database format is sufficiently up-to-date to be compatible with a major version upgrade of pebble.
191 lines
5.0 KiB
Go
191 lines
5.0 KiB
Go
package pebbleds
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/cockroachdb/pebble"
|
|
pebbleds "github.com/ipfs/go-ds-pebble"
|
|
"github.com/ipfs/kubo/misc/fsutil"
|
|
"github.com/ipfs/kubo/plugin"
|
|
"github.com/ipfs/kubo/repo"
|
|
"github.com/ipfs/kubo/repo/fsrepo"
|
|
)
|
|
|
|
// Plugins is exported list of plugins that will be loaded.
|
|
var Plugins = []plugin.Plugin{
|
|
&pebbledsPlugin{},
|
|
}
|
|
|
|
type pebbledsPlugin struct{}
|
|
|
|
var _ plugin.PluginDatastore = (*pebbledsPlugin)(nil)
|
|
|
|
func (*pebbledsPlugin) Name() string {
|
|
return "ds-pebble"
|
|
}
|
|
|
|
func (*pebbledsPlugin) Version() string {
|
|
return "0.1.0"
|
|
}
|
|
|
|
func (*pebbledsPlugin) Init(_ *plugin.Environment) error {
|
|
return nil
|
|
}
|
|
|
|
func (*pebbledsPlugin) DatastoreTypeName() string {
|
|
return "pebbleds"
|
|
}
|
|
|
|
type datastoreConfig struct {
|
|
path string
|
|
cacheSize int64
|
|
|
|
// Documentation of these values: https://pkg.go.dev/github.com/cockroachdb/pebble@v1.1.2#Options
|
|
pebbleOpts *pebble.Options
|
|
}
|
|
|
|
// PebbleDatastoreConfig returns a configuration stub for a pebble datastore
|
|
// from the given parameters.
|
|
func (*pebbledsPlugin) DatastoreConfigParser() fsrepo.ConfigFromMap {
|
|
return func(params map[string]any) (fsrepo.DatastoreConfig, error) {
|
|
var c datastoreConfig
|
|
var ok bool
|
|
|
|
c.path, ok = params["path"].(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("'path' field is missing or not string")
|
|
}
|
|
|
|
cacheSize, err := getConfigInt("cacheSize", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
c.cacheSize = int64(cacheSize)
|
|
|
|
bytesPerSync, err := getConfigInt("bytesPerSync", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
disableWAL, err := getConfigBool("disableWAL", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fmv, err := getConfigInt("formatMajorVersion", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
formatMajorVersion := pebble.FormatMajorVersion(fmv)
|
|
l0CompactionThreshold, err := getConfigInt("l0CompactionThreshold", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
l0StopWritesThreshold, err := getConfigInt("l0StopWritesThreshold", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
lBaseMaxBytes, err := getConfigInt("lBaseMaxBytes", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
maxConcurrentCompactions, err := getConfigInt("maxConcurrentCompactions", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
memTableSize, err := getConfigInt("memTableSize", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
memTableStopWritesThreshold, err := getConfigInt("memTableStopWritesThreshold", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
walBytesPerSync, err := getConfigInt("walBytesPerSync", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
walMinSyncSec, err := getConfigInt("walMinSyncIntervalSeconds", params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Use latest version by default. This will ensure that format is
|
|
// compatible across database upgrades.
|
|
if formatMajorVersion == 0 {
|
|
formatMajorVersion = pebble.FormatNewest
|
|
}
|
|
|
|
if bytesPerSync != 0 || disableWAL || formatMajorVersion != 0 || l0CompactionThreshold != 0 || l0StopWritesThreshold != 0 || lBaseMaxBytes != 0 || maxConcurrentCompactions != 0 || memTableSize != 0 || memTableStopWritesThreshold != 0 || walBytesPerSync != 0 || walMinSyncSec != 0 {
|
|
c.pebbleOpts = &pebble.Options{
|
|
BytesPerSync: bytesPerSync,
|
|
DisableWAL: disableWAL,
|
|
FormatMajorVersion: formatMajorVersion,
|
|
L0CompactionThreshold: l0CompactionThreshold,
|
|
L0StopWritesThreshold: l0StopWritesThreshold,
|
|
LBaseMaxBytes: int64(lBaseMaxBytes),
|
|
MemTableSize: uint64(memTableSize),
|
|
MemTableStopWritesThreshold: memTableStopWritesThreshold,
|
|
WALBytesPerSync: walBytesPerSync,
|
|
}
|
|
if maxConcurrentCompactions != 0 {
|
|
c.pebbleOpts.MaxConcurrentCompactions = func() int { return maxConcurrentCompactions }
|
|
}
|
|
if walMinSyncSec != 0 {
|
|
c.pebbleOpts.WALMinSyncInterval = func() time.Duration { return time.Duration(walMinSyncSec) * time.Second }
|
|
}
|
|
}
|
|
|
|
return &c, nil
|
|
}
|
|
}
|
|
|
|
func getConfigBool(name string, params map[string]any) (bool, error) {
|
|
val, ok := params[name]
|
|
if ok {
|
|
bval, ok := val.(bool)
|
|
if !ok {
|
|
return false, fmt.Errorf("%q field was not a bool", name)
|
|
}
|
|
return bval, nil
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func getConfigInt(name string, params map[string]any) (int, error) {
|
|
val, ok := params[name]
|
|
if ok {
|
|
// TODO: see why val may be an int or a float64.
|
|
ival, ok := val.(int)
|
|
if !ok {
|
|
fval, ok := val.(float64)
|
|
if !ok {
|
|
return 0, fmt.Errorf("%q field was not an integer or a float64", name)
|
|
}
|
|
return int(fval), nil
|
|
}
|
|
return ival, nil
|
|
}
|
|
return 0, nil
|
|
}
|
|
|
|
func (c *datastoreConfig) DiskSpec() fsrepo.DiskSpec {
|
|
return map[string]interface{}{
|
|
"type": "pebbleds",
|
|
"path": c.path,
|
|
}
|
|
}
|
|
|
|
func (c *datastoreConfig) Create(path string) (repo.Datastore, error) {
|
|
p := c.path
|
|
if !filepath.IsAbs(p) {
|
|
p = filepath.Join(path, p)
|
|
}
|
|
|
|
if err := fsutil.DirWritable(p); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return pebbleds.NewDatastore(p, pebbleds.WithCacheSize(c.cacheSize), pebbleds.WithPebbleOpts(c.pebbleOpts))
|
|
}
|