2014-07-25 13:58:00 +04:00
|
|
|
package goleveldb
|
|
|
|
|
|
|
|
import (
|
2014-11-20 17:52:29 +03:00
|
|
|
"github.com/syndtr/goleveldb/leveldb"
|
|
|
|
"github.com/syndtr/goleveldb/leveldb/cache"
|
|
|
|
"github.com/syndtr/goleveldb/leveldb/filter"
|
|
|
|
"github.com/syndtr/goleveldb/leveldb/opt"
|
|
|
|
"github.com/syndtr/goleveldb/leveldb/storage"
|
|
|
|
"github.com/syndtr/goleveldb/leveldb/util"
|
2014-09-01 13:45:47 +04:00
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
"github.com/siddontang/ledisdb/config"
|
2014-07-25 13:58:00 +04:00
|
|
|
"github.com/siddontang/ledisdb/store/driver"
|
2014-08-07 12:49:48 +04:00
|
|
|
|
2014-07-25 13:58:00 +04:00
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
const defaultFilterBits int = 10
|
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
type Store struct {
|
|
|
|
}
|
2014-07-25 13:58:00 +04:00
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
func (s Store) String() string {
|
2014-08-15 20:08:01 +04:00
|
|
|
return DBName
|
2014-07-25 13:58:00 +04:00
|
|
|
}
|
|
|
|
|
2014-09-01 13:45:47 +04:00
|
|
|
type MemStore struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s MemStore) String() string {
|
|
|
|
return MemDBName
|
|
|
|
}
|
|
|
|
|
2014-07-25 13:58:00 +04:00
|
|
|
type DB struct {
|
2014-08-07 12:49:48 +04:00
|
|
|
path string
|
|
|
|
|
|
|
|
cfg *config.LevelDBConfig
|
2014-07-25 13:58:00 +04:00
|
|
|
|
|
|
|
db *leveldb.DB
|
|
|
|
|
|
|
|
opts *opt.Options
|
|
|
|
|
|
|
|
iteratorOpts *opt.ReadOptions
|
|
|
|
|
2014-10-09 09:05:55 +04:00
|
|
|
syncOpts *opt.WriteOptions
|
|
|
|
|
2014-07-25 13:58:00 +04:00
|
|
|
cache cache.Cache
|
|
|
|
|
|
|
|
filter filter.Filter
|
|
|
|
}
|
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
func (s Store) Open(path string, cfg *config.Config) (driver.IDB, error) {
|
2014-09-18 17:27:43 +04:00
|
|
|
if err := os.MkdirAll(path, 0755); err != nil {
|
2014-07-25 13:58:00 +04:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
db := new(DB)
|
2014-08-07 12:49:48 +04:00
|
|
|
db.path = path
|
|
|
|
db.cfg = &cfg.LevelDB
|
2014-07-25 13:58:00 +04:00
|
|
|
|
2014-09-01 13:45:47 +04:00
|
|
|
db.initOpts()
|
|
|
|
|
|
|
|
var err error
|
|
|
|
db.db, err = leveldb.OpenFile(db.path, db.opts)
|
|
|
|
|
|
|
|
if err != nil {
|
2014-07-25 13:58:00 +04:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return db, nil
|
|
|
|
}
|
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
func (s Store) Repair(path string, cfg *config.Config) error {
|
|
|
|
db, err := leveldb.RecoverFile(path, newOptions(&cfg.LevelDB))
|
2014-07-25 13:58:00 +04:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
db.Close()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-09-01 13:45:47 +04:00
|
|
|
func (s MemStore) Open(path string, cfg *config.Config) (driver.IDB, error) {
|
|
|
|
db := new(DB)
|
|
|
|
db.path = path
|
|
|
|
db.cfg = &cfg.LevelDB
|
2014-07-25 13:58:00 +04:00
|
|
|
|
2014-09-01 13:45:47 +04:00
|
|
|
db.initOpts()
|
2014-07-25 13:58:00 +04:00
|
|
|
|
|
|
|
var err error
|
2014-09-01 13:45:47 +04:00
|
|
|
db.db, err = leveldb.Open(storage.NewMemStorage(), db.opts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return db, nil
|
|
|
|
}
|
2014-07-25 13:58:00 +04:00
|
|
|
|
2014-09-01 13:45:47 +04:00
|
|
|
func (s MemStore) Repair(path string, cfg *config.Config) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (db *DB) initOpts() {
|
|
|
|
db.opts = newOptions(db.cfg)
|
|
|
|
|
|
|
|
db.iteratorOpts = &opt.ReadOptions{}
|
|
|
|
db.iteratorOpts.DontFillCache = true
|
2014-10-09 09:05:55 +04:00
|
|
|
|
|
|
|
db.syncOpts = &opt.WriteOptions{}
|
|
|
|
db.syncOpts.Sync = true
|
2014-07-25 13:58:00 +04:00
|
|
|
}
|
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
func newOptions(cfg *config.LevelDBConfig) *opt.Options {
|
2014-07-25 13:58:00 +04:00
|
|
|
opts := &opt.Options{}
|
|
|
|
opts.ErrorIfMissing = false
|
|
|
|
|
2014-12-12 15:56:17 +03:00
|
|
|
opts.BlockCacheCapacity = cfg.CacheSize
|
2014-07-25 13:58:00 +04:00
|
|
|
|
|
|
|
//we must use bloomfilter
|
|
|
|
opts.Filter = filter.NewBloomFilter(defaultFilterBits)
|
|
|
|
|
|
|
|
if !cfg.Compression {
|
|
|
|
opts.Compression = opt.NoCompression
|
|
|
|
} else {
|
|
|
|
opts.Compression = opt.SnappyCompression
|
|
|
|
}
|
|
|
|
|
2014-08-07 12:49:48 +04:00
|
|
|
opts.BlockSize = cfg.BlockSize
|
|
|
|
opts.WriteBuffer = cfg.WriteBufferSize
|
2014-12-12 15:56:17 +03:00
|
|
|
opts.OpenFilesCacheCapacity = cfg.MaxOpenFiles
|
2014-11-20 17:52:29 +03:00
|
|
|
|
|
|
|
//here we use default value, later add config support
|
|
|
|
opts.CompactionTableSize = 32 * 1024 * 1024
|
|
|
|
opts.WriteL0SlowdownTrigger = 16
|
|
|
|
opts.WriteL0PauseTrigger = 64
|
2014-07-25 13:58:00 +04:00
|
|
|
|
|
|
|
return opts
|
|
|
|
}
|
|
|
|
|
|
|
|
func (db *DB) Close() error {
|
|
|
|
return db.db.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (db *DB) Put(key, value []byte) error {
|
|
|
|
return db.db.Put(key, value, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (db *DB) Get(key []byte) ([]byte, error) {
|
|
|
|
v, err := db.db.Get(key, nil)
|
|
|
|
if err == leveldb.ErrNotFound {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
return v, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (db *DB) Delete(key []byte) error {
|
|
|
|
return db.db.Delete(key, nil)
|
|
|
|
}
|
|
|
|
|
2014-10-09 09:05:55 +04:00
|
|
|
func (db *DB) SyncPut(key []byte, value []byte) error {
|
|
|
|
return db.db.Put(key, value, db.syncOpts)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (db *DB) SyncDelete(key []byte) error {
|
|
|
|
return db.db.Delete(key, db.syncOpts)
|
|
|
|
}
|
|
|
|
|
2014-07-25 13:58:00 +04:00
|
|
|
func (db *DB) NewWriteBatch() driver.IWriteBatch {
|
|
|
|
wb := &WriteBatch{
|
|
|
|
db: db,
|
|
|
|
wbatch: new(leveldb.Batch),
|
|
|
|
}
|
|
|
|
return wb
|
|
|
|
}
|
|
|
|
|
|
|
|
func (db *DB) NewIterator() driver.IIterator {
|
|
|
|
it := &Iterator{
|
|
|
|
db.db.NewIterator(nil, db.iteratorOpts),
|
|
|
|
}
|
|
|
|
|
|
|
|
return it
|
|
|
|
}
|
2014-07-29 13:29:51 +04:00
|
|
|
|
2014-08-25 10:18:23 +04:00
|
|
|
func (db *DB) NewSnapshot() (driver.ISnapshot, error) {
|
|
|
|
snapshot, err := db.db.GetSnapshot()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
s := &Snapshot{
|
|
|
|
db: db,
|
|
|
|
snp: snapshot,
|
|
|
|
}
|
|
|
|
|
|
|
|
return s, nil
|
|
|
|
}
|
|
|
|
|
2014-09-12 11:06:36 +04:00
|
|
|
func (db *DB) Compact() error {
|
2020-04-24 08:07:38 +03:00
|
|
|
return db.db.CompactRange(util.Range{
|
|
|
|
Start: nil,
|
|
|
|
Limit: nil,
|
|
|
|
})
|
2014-09-12 11:06:36 +04:00
|
|
|
}
|
|
|
|
|
2014-08-15 20:08:01 +04:00
|
|
|
func init() {
|
|
|
|
driver.Register(Store{})
|
2014-09-01 13:45:47 +04:00
|
|
|
driver.Register(MemStore{})
|
2014-08-15 20:08:01 +04:00
|
|
|
}
|