improve leveldb batch usage and pointer releasing in caches

This commit is contained in:
StephenButtolph 2020-06-19 11:02:38 -04:00
parent f78d7b3caf
commit 006ff75149
4 changed files with 24 additions and 13 deletions

View File

@ -18,9 +18,10 @@ import (
// database, writing changes to the underlying database only when commit is // database, writing changes to the underlying database only when commit is
// called. // called.
type Database struct { type Database struct {
lock sync.RWMutex lock sync.RWMutex
mem map[string]valueDelete mem map[string]valueDelete
db database.Database db database.Database
batch database.Batch
} }
type valueDelete struct { type valueDelete struct {
@ -31,8 +32,9 @@ type valueDelete struct {
// New returns a new prefixed database // New returns a new prefixed database
func New(db database.Database) *Database { func New(db database.Database) *Database {
return &Database{ return &Database{
mem: make(map[string]valueDelete, memdb.DefaultSize), mem: make(map[string]valueDelete, memdb.DefaultSize),
db: db, db: db,
batch: db.NewBatch(),
} }
} }
@ -169,6 +171,7 @@ func (db *Database) SetDatabase(newDB database.Database) error {
} }
db.db = newDB db.db = newDB
db.batch = newDB.NewBatch()
return nil return nil
} }
@ -206,7 +209,9 @@ func (db *Database) Abort() {
func (db *Database) abort() { db.mem = make(map[string]valueDelete, memdb.DefaultSize) } func (db *Database) abort() { db.mem = make(map[string]valueDelete, memdb.DefaultSize) }
// CommitBatch returns a batch that will commit all pending writes to the underlying database // CommitBatch returns a batch that will commit all pending writes to the
// underlying database. The returned batch should be written before future calls
// to this DB unless the batch will never be written.
func (db *Database) CommitBatch() (database.Batch, error) { func (db *Database) CommitBatch() (database.Batch, error) {
db.lock.Lock() db.lock.Lock()
defer db.lock.Unlock() defer db.lock.Unlock()
@ -219,21 +224,21 @@ func (db *Database) commitBatch() (database.Batch, error) {
return nil, database.ErrClosed return nil, database.ErrClosed
} }
batch := db.db.NewBatch() db.batch.Reset()
for key, value := range db.mem { for key, value := range db.mem {
if value.delete { if value.delete {
if err := batch.Delete([]byte(key)); err != nil { if err := db.batch.Delete([]byte(key)); err != nil {
return nil, err return nil, err
} }
} else if err := batch.Put([]byte(key), value.value); err != nil { } else if err := db.batch.Put([]byte(key), value.value); err != nil {
return nil, err return nil, err
} }
} }
if err := batch.Write(); err != nil { if err := db.batch.Write(); err != nil {
return nil, err return nil, err
} }
return batch, nil return db.batch, nil
} }
// Close implements the database.Database interface // Close implements the database.Database interface

View File

@ -54,6 +54,8 @@ func (vtx *uniqueVertex) refresh() {
func (vtx *uniqueVertex) Evict() { func (vtx *uniqueVertex) Evict() {
if vtx.v != nil { if vtx.v != nil {
vtx.v.unique = false vtx.v.unique = false
// make sure the parents are able to be garbage collected
vtx.v.parents = nil
} }
} }

View File

@ -85,7 +85,11 @@ func (tx *UniqueTx) refresh() {
// Evict is called when this UniqueTx will no longer be returned from a cache // Evict is called when this UniqueTx will no longer be returned from a cache
// lookup // lookup
func (tx *UniqueTx) Evict() { tx.unique = false } // Lock is already held here func (tx *UniqueTx) Evict() {
// Lock is already held here
tx.unique = false
tx.deps = nil
}
func (tx *UniqueTx) setStatus(status choices.Status) error { func (tx *UniqueTx) setStatus(status choices.Status) error {
tx.refresh() tx.refresh()

View File

@ -35,7 +35,7 @@ const (
batchSize = 30 batchSize = 30
stateCacheSize = 10000 stateCacheSize = 10000
idCacheSize = 10000 idCacheSize = 10000
txCacheSize = 100000 txCacheSize = 10000
addressSep = "-" addressSep = "-"
) )