mtsatellite/leveldb.go

97 lines
1.9 KiB
Go

// Copyright 2014 by Sascha L. Teichmann
// Use of this source code is governed by the MIT license
// that can be found in the LICENSE file.
package main
import (
leveldb "github.com/jmhodges/levigo"
)
type LevelDBBackend struct {
cache *leveldb.Cache
db *leveldb.DB
tx *leveldb.WriteBatch
}
func NewLeveDBBackend(path string, cacheSize int) (ldb *LevelDBBackend, err error) {
cache := leveldb.NewLRUCache(cacheSize * 1024 * 1024)
opts := leveldb.NewOptions()
opts.SetCache(cache)
opts.SetCreateIfMissing(true)
var db *leveldb.DB
if db, err = leveldb.Open(path, opts); err != nil {
cache.Close()
return
}
ldb = &LevelDBBackend{
cache: cache,
db: db}
return
}
func (ldb *LevelDBBackend) Shutdown() error {
tx := ldb.tx
if tx != nil {
ldb.tx = nil
tx.Close()
}
ldb.db.Close()
ldb.cache.Close()
return nil
}
func (ldb *LevelDBBackend) Fetch(hash, key []byte) ([]byte, error) {
ro := leveldb.NewReadOptions()
defer ro.Close()
return ldb.db.Get(ro, key)
}
func (ldb *LevelDBBackend) InTransaction() bool {
return ldb.tx != nil
}
func (ldb *LevelDBBackend) keyExists(key []byte) (exists bool, err error) {
ro := leveldb.NewReadOptions()
defer ro.Close()
var data []byte
if data, err = ldb.db.Get(ro, key); err != nil {
return
}
exists = data != nil
return
}
func (ldb *LevelDBBackend) Store(hash, key, value []byte) (exists bool, err error) {
if exists, err = ldb.keyExists(key); err != nil {
return
}
if ldb.tx != nil {
ldb.tx.Put(key, value)
return
}
wo := leveldb.NewWriteOptions()
defer wo.Close()
if err = ldb.db.Put(wo, key, value); err != nil {
return
}
return
}
func (ldb *LevelDBBackend) BeginTransaction() error {
ldb.tx = leveldb.NewWriteBatch()
return nil
}
func (ldb *LevelDBBackend) CommitTransaction() error {
tx := ldb.tx
ldb.tx = nil
wo := leveldb.NewWriteOptions()
defer wo.Close()
return ldb.db.Write(wo, tx)
}