github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/store/localstore/goleveldb/goleveldb.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package goleveldb 15 16 import ( 17 "sync" 18 19 "github.com/insionng/yougam/libraries/juju/errors" 20 "github.com/insionng/yougam/libraries/pingcap/tidb/store/localstore/engine" 21 "github.com/insionng/yougam/libraries/syndtr/goleveldb/leveldb" 22 "github.com/insionng/yougam/libraries/syndtr/goleveldb/leveldb/opt" 23 "github.com/insionng/yougam/libraries/syndtr/goleveldb/leveldb/storage" 24 "github.com/insionng/yougam/libraries/syndtr/goleveldb/leveldb/util" 25 ) 26 27 var ( 28 _ engine.DB = (*db)(nil) 29 _ engine.Batch = (*leveldb.Batch)(nil) 30 ) 31 32 var ( 33 p = sync.Pool{ 34 New: func() interface{} { 35 return &leveldb.Batch{} 36 }, 37 } 38 ) 39 40 type db struct { 41 *leveldb.DB 42 } 43 44 func (d *db) Get(key []byte) ([]byte, error) { 45 v, err := d.DB.Get(key, nil) 46 if err == leveldb.ErrNotFound { 47 return nil, errors.Trace(engine.ErrNotFound) 48 } 49 return v, err 50 } 51 52 func (d *db) NewBatch() engine.Batch { 53 b := p.Get().(*leveldb.Batch) 54 return b 55 } 56 57 func (d *db) Seek(startKey []byte) ([]byte, []byte, error) { 58 iter := d.DB.NewIterator(&util.Range{Start: startKey}, nil) 59 defer iter.Release() 60 if ok := iter.First(); !ok { 61 return nil, nil, errors.Trace(engine.ErrNotFound) 62 } 63 return iter.Key(), iter.Value(), nil 64 } 65 66 func (d *db) SeekReverse(key []byte) ([]byte, []byte, error) { 67 iter := d.DB.NewIterator(&util.Range{}, nil) 68 defer iter.Release() 69 if len(key) == 0 { 70 if ok := iter.Last(); !ok { 71 return nil, nil, engine.ErrNotFound 72 } 73 return iter.Key(), iter.Value(), nil 74 } 75 iter.Seek(key) 76 if ok := iter.Prev(); !ok { 77 return nil, nil, engine.ErrNotFound 78 } 79 return iter.Key(), iter.Value(), nil 80 } 81 82 func (d *db) Commit(b engine.Batch) error { 83 batch, ok := b.(*leveldb.Batch) 84 if !ok { 85 return errors.Errorf("invalid batch type %T", b) 86 } 87 err := d.DB.Write(batch, nil) 88 batch.Reset() 89 p.Put(batch) 90 return err 91 } 92 93 func (d *db) Close() error { 94 return d.DB.Close() 95 } 96 97 // Driver implements engine Driver. 98 type Driver struct { 99 } 100 101 // Open opens or creates a local storage database for the given path. 102 func (driver Driver) Open(path string) (engine.DB, error) { 103 d, err := leveldb.OpenFile(path, &opt.Options{BlockCacheCapacity: 600 * 1024 * 1024}) 104 105 return &db{d}, err 106 } 107 108 // MemoryDriver implements engine Driver 109 type MemoryDriver struct { 110 } 111 112 // Open opens a memory storage database. 113 func (driver MemoryDriver) Open(path string) (engine.DB, error) { 114 d, err := leveldb.Open(storage.NewMemStorage(), nil) 115 return &db{d}, err 116 }