Allow partitioned index filter in rocksdb
This commit is contained in:
parent
41252d33d2
commit
a34ac14883
65
db/dboptions.go
Normal file
65
db/dboptions.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
// #include "rocksdb/c.h"
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/tecbot/gorocksdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createAndSetDBOptions(bloomBits int, twoLevelIndex bool, c *gorocksdb.Cache) *gorocksdb.Options {
|
||||||
|
// get access to all db options, gorocksdb does not expose all
|
||||||
|
|
||||||
|
// opts := gorocksdb.NewDefaultOptions()
|
||||||
|
cNativeOpts := C.rocksdb_options_create()
|
||||||
|
opts := &gorocksdb.Options{}
|
||||||
|
cField := reflect.Indirect(reflect.ValueOf(opts)).FieldByName("c")
|
||||||
|
cPtr := (**C.rocksdb_options_t)(unsafe.Pointer(cField.UnsafeAddr()))
|
||||||
|
*cPtr = cNativeOpts
|
||||||
|
|
||||||
|
// blockOpts := gorocksdb.NewDefaultBlockBasedTableOptions()
|
||||||
|
cNativeBlockOpts := C.rocksdb_block_based_options_create()
|
||||||
|
blockOpts := &gorocksdb.BlockBasedTableOptions{}
|
||||||
|
cBlockField := reflect.Indirect(reflect.ValueOf(blockOpts)).FieldByName("c")
|
||||||
|
cBlockPtr := (**C.rocksdb_block_based_table_options_t)(unsafe.Pointer(cBlockField.UnsafeAddr()))
|
||||||
|
*cBlockPtr = cNativeBlockOpts
|
||||||
|
|
||||||
|
blockOpts.SetBlockSize(32 << 10) // 32kB
|
||||||
|
blockOpts.SetBlockCache(c)
|
||||||
|
if bloomBits > 0 {
|
||||||
|
blockOpts.SetFilterPolicy(gorocksdb.NewBloomFilter(bloomBits))
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/facebook/rocksdb/wiki/Partitioned-Index-Filters
|
||||||
|
if twoLevelIndex {
|
||||||
|
// blockOpts.SetCacheIndexAndFilterBlocks(true)
|
||||||
|
blockOpts.SetIndexType(gorocksdb.KTwoLevelIndexSearchIndexType)
|
||||||
|
C.rocksdb_block_based_options_set_partition_filters(cNativeBlockOpts, boolToChar(true))
|
||||||
|
C.rocksdb_block_based_options_set_metadata_block_size(cNativeBlockOpts, C.uint64_t(4096))
|
||||||
|
C.rocksdb_block_based_options_set_cache_index_and_filter_blocks_with_high_priority(cNativeBlockOpts, boolToChar(true))
|
||||||
|
blockOpts.SetPinL0FilterAndIndexBlocksInCache(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.SetBlockBasedTableFactory(blockOpts)
|
||||||
|
opts.SetCreateIfMissing(true)
|
||||||
|
opts.SetCreateIfMissingColumnFamilies(true)
|
||||||
|
opts.SetMaxBackgroundCompactions(6)
|
||||||
|
opts.SetMaxBackgroundFlushes(6)
|
||||||
|
opts.SetBytesPerSync(8 << 20) // 8MB
|
||||||
|
opts.SetWriteBufferSize(1 << 27) // 128MB
|
||||||
|
opts.SetMaxBytesForLevelBase(1 << 27) // 128MB
|
||||||
|
opts.SetMaxOpenFiles(25000)
|
||||||
|
opts.SetCompression(gorocksdb.LZ4HCCompression)
|
||||||
|
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
||||||
|
// boolToChar converts a bool value to C.uchar.
|
||||||
|
func boolToChar(b bool) C.uchar {
|
||||||
|
if b {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
@ -59,47 +59,13 @@ const (
|
|||||||
var cfNames = []string{"default", "height", "addresses", "txAddresses", "addressBalance", "blockTxs", "transactions"}
|
var cfNames = []string{"default", "height", "addresses", "txAddresses", "addressBalance", "blockTxs", "transactions"}
|
||||||
|
|
||||||
func openDB(path string, c *gorocksdb.Cache) (*gorocksdb.DB, []*gorocksdb.ColumnFamilyHandle, error) {
|
func openDB(path string, c *gorocksdb.Cache) (*gorocksdb.DB, []*gorocksdb.ColumnFamilyHandle, error) {
|
||||||
bloom := gorocksdb.NewBloomFilter(10)
|
// opts with bloom filter
|
||||||
blockOpts := gorocksdb.NewDefaultBlockBasedTableOptions()
|
opts := createAndSetDBOptions(10, true, c)
|
||||||
blockOpts.SetBlockSize(16 << 10) // 16kB
|
// opts for addresses without bloom filter
|
||||||
blockOpts.SetBlockCache(c)
|
// from documentation: if most of your queries are executed using iterators, you shouldn't set bloom filter
|
||||||
blockOpts.SetFilterPolicy(bloom)
|
optsAddresses := createAndSetDBOptions(0, true, c)
|
||||||
blockOpts.SetCacheIndexAndFilterBlocks(true)
|
|
||||||
blockOpts.SetPinL0FilterAndIndexBlocksInCache(true)
|
|
||||||
|
|
||||||
opts := gorocksdb.NewDefaultOptions()
|
|
||||||
opts.SetBlockBasedTableFactory(blockOpts)
|
|
||||||
opts.SetCreateIfMissing(true)
|
|
||||||
opts.SetCreateIfMissingColumnFamilies(true)
|
|
||||||
opts.SetMaxBackgroundCompactions(6)
|
|
||||||
opts.SetMaxBackgroundFlushes(6)
|
|
||||||
opts.SetBytesPerSync(1 << 20) // 1MB
|
|
||||||
opts.SetWriteBufferSize(1 << 27) // 128MB
|
|
||||||
opts.SetMaxOpenFiles(25000)
|
|
||||||
opts.SetCompression(gorocksdb.LZ4HCCompression)
|
|
||||||
|
|
||||||
// opts for addresses are different:
|
|
||||||
// no bloom filter - from documentation: If most of your queries are executed using iterators, you shouldn't set bloom filter
|
|
||||||
blockOptsAddress := gorocksdb.NewDefaultBlockBasedTableOptions()
|
|
||||||
blockOptsAddress.SetBlockSize(16 << 10) // 16kB
|
|
||||||
blockOptsAddress.SetBlockCache(c) // 8GB
|
|
||||||
blockOptsAddress.SetCacheIndexAndFilterBlocks(true)
|
|
||||||
blockOptsAddress.SetPinL0FilterAndIndexBlocksInCache(true)
|
|
||||||
|
|
||||||
optsAddresses := gorocksdb.NewDefaultOptions()
|
|
||||||
optsAddresses.SetBlockBasedTableFactory(blockOptsAddress)
|
|
||||||
optsAddresses.SetCreateIfMissing(true)
|
|
||||||
optsAddresses.SetCreateIfMissingColumnFamilies(true)
|
|
||||||
optsAddresses.SetMaxBackgroundCompactions(6)
|
|
||||||
optsAddresses.SetMaxBackgroundFlushes(6)
|
|
||||||
optsAddresses.SetBytesPerSync(1 << 20) // 1MB
|
|
||||||
optsAddresses.SetWriteBufferSize(1 << 27) // 128MB
|
|
||||||
optsAddresses.SetMaxOpenFiles(25000)
|
|
||||||
optsAddresses.SetCompression(gorocksdb.LZ4HCCompression)
|
|
||||||
|
|
||||||
// default, height, addresses, txAddresses, addressBalance, blockTxids, transactions
|
// default, height, addresses, txAddresses, addressBalance, blockTxids, transactions
|
||||||
fcOptions := []*gorocksdb.Options{opts, opts, optsAddresses, opts, opts, opts, opts}
|
fcOptions := []*gorocksdb.Options{opts, opts, optsAddresses, opts, opts, opts, opts}
|
||||||
|
|
||||||
db, cfh, err := gorocksdb.OpenDbColumnFamilies(opts, path, cfNames, fcOptions)
|
db, cfh, err := gorocksdb.OpenDbColumnFamilies(opts, path, cfNames, fcOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -111,7 +77,7 @@ func openDB(path string, c *gorocksdb.Cache) (*gorocksdb.DB, []*gorocksdb.Column
|
|||||||
// needs to be called to release it.
|
// needs to be called to release it.
|
||||||
func NewRocksDB(path string, parser bchain.BlockChainParser, metrics *common.Metrics) (d *RocksDB, err error) {
|
func NewRocksDB(path string, parser bchain.BlockChainParser, metrics *common.Metrics) (d *RocksDB, err error) {
|
||||||
glog.Infof("rocksdb: open %s, version %v", path, dbVersion)
|
glog.Infof("rocksdb: open %s, version %v", path, dbVersion)
|
||||||
c := gorocksdb.NewLRUCache(8 << 30) // 8GB
|
c := gorocksdb.NewLRUCache(1 << 30) // 1GB
|
||||||
db, cfh, err := openDB(path, c)
|
db, cfh, err := openDB(path, c)
|
||||||
wo := gorocksdb.NewDefaultWriteOptions()
|
wo := gorocksdb.NewDefaultWriteOptions()
|
||||||
ro := gorocksdb.NewDefaultReadOptions()
|
ro := gorocksdb.NewDefaultReadOptions()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user