188 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| package goleveldb
 | |
| 
 | |
| import (
 | |
| 	"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/lunny/nodb/config"
 | |
| 	"github.com/lunny/nodb/store/driver"
 | |
| 
 | |
| 	"os"
 | |
| )
 | |
| 
 | |
| const defaultFilterBits int = 10
 | |
| 
 | |
| type Store struct {
 | |
| }
 | |
| 
 | |
| func (s Store) String() string {
 | |
| 	return DBName
 | |
| }
 | |
| 
 | |
| type MemStore struct {
 | |
| }
 | |
| 
 | |
| func (s MemStore) String() string {
 | |
| 	return MemDBName
 | |
| }
 | |
| 
 | |
| type DB struct {
 | |
| 	path string
 | |
| 
 | |
| 	cfg *config.LevelDBConfig
 | |
| 
 | |
| 	db *leveldb.DB
 | |
| 
 | |
| 	opts *opt.Options
 | |
| 
 | |
| 	iteratorOpts *opt.ReadOptions
 | |
| 
 | |
| 	cache cache.Cache
 | |
| 
 | |
| 	filter filter.Filter
 | |
| }
 | |
| 
 | |
| func (s Store) Open(path string, cfg *config.Config) (driver.IDB, error) {
 | |
| 	if err := os.MkdirAll(path, os.ModePerm); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	db := new(DB)
 | |
| 	db.path = path
 | |
| 	db.cfg = &cfg.LevelDB
 | |
| 
 | |
| 	db.initOpts()
 | |
| 
 | |
| 	var err error
 | |
| 	db.db, err = leveldb.OpenFile(db.path, db.opts)
 | |
| 
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return db, nil
 | |
| }
 | |
| 
 | |
| func (s Store) Repair(path string, cfg *config.Config) error {
 | |
| 	db, err := leveldb.RecoverFile(path, newOptions(&cfg.LevelDB))
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	db.Close()
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (s MemStore) Open(path string, cfg *config.Config) (driver.IDB, error) {
 | |
| 	db := new(DB)
 | |
| 	db.path = path
 | |
| 	db.cfg = &cfg.LevelDB
 | |
| 
 | |
| 	db.initOpts()
 | |
| 
 | |
| 	var err error
 | |
| 	db.db, err = leveldb.Open(storage.NewMemStorage(), db.opts)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return db, nil
 | |
| }
 | |
| 
 | |
| 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
 | |
| }
 | |
| 
 | |
| func newOptions(cfg *config.LevelDBConfig) *opt.Options {
 | |
| 	opts := &opt.Options{}
 | |
| 	opts.ErrorIfMissing = false
 | |
| 
 | |
| 	cfg.Adjust()
 | |
| 
 | |
| 	//opts.BlockCacher = cache.NewLRU(cfg.CacheSize)
 | |
| 	opts.BlockCacheCapacity = cfg.CacheSize
 | |
| 
 | |
| 	//we must use bloomfilter
 | |
| 	opts.Filter = filter.NewBloomFilter(defaultFilterBits)
 | |
| 
 | |
| 	if !cfg.Compression {
 | |
| 		opts.Compression = opt.NoCompression
 | |
| 	} else {
 | |
| 		opts.Compression = opt.SnappyCompression
 | |
| 	}
 | |
| 
 | |
| 	opts.BlockSize = cfg.BlockSize
 | |
| 	opts.WriteBuffer = cfg.WriteBufferSize
 | |
| 
 | |
| 	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)
 | |
| }
 | |
| 
 | |
| 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
 | |
| }
 | |
| 
 | |
| func (db *DB) Begin() (driver.Tx, error) {
 | |
| 	return nil, driver.ErrTxSupport
 | |
| }
 | |
| 
 | |
| 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
 | |
| }
 | |
| 
 | |
| func init() {
 | |
| 	driver.Register(Store{})
 | |
| 	driver.Register(MemStore{})
 | |
| }
 |