syncthing/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_state.go

116 lines
2.6 KiB
Go
Raw Normal View History

2014-07-06 14:46:48 +02:00
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package leveldb
import (
"sync/atomic"
"github.com/syndtr/goleveldb/leveldb/journal"
"github.com/syndtr/goleveldb/leveldb/memdb"
)
// Get latest sequence number.
2014-07-23 08:31:36 +02:00
func (db *DB) getSeq() uint64 {
return atomic.LoadUint64(&db.seq)
2014-07-06 14:46:48 +02:00
}
// Atomically adds delta to seq.
2014-07-23 08:31:36 +02:00
func (db *DB) addSeq(delta uint64) {
atomic.AddUint64(&db.seq, delta)
2014-07-06 14:46:48 +02:00
}
// Create new memdb and froze the old one; need external synchronization.
// newMem only called synchronously by the writer.
2014-07-23 08:31:36 +02:00
func (db *DB) newMem(n int) (mem *memdb.DB, err error) {
num := db.s.allocFileNum()
file := db.s.getJournalFile(num)
2014-07-06 14:46:48 +02:00
w, err := file.Create()
if err != nil {
2014-07-23 08:31:36 +02:00
db.s.reuseFileNum(num)
2014-07-06 14:46:48 +02:00
return
}
2014-07-23 08:31:36 +02:00
db.memMu.Lock()
defer db.memMu.Unlock()
if db.journal == nil {
db.journal = journal.NewWriter(w)
2014-07-06 14:46:48 +02:00
} else {
2014-07-23 08:31:36 +02:00
db.journal.Reset(w)
db.journalWriter.Close()
db.frozenJournalFile = db.journalFile
2014-07-06 14:46:48 +02:00
}
2014-07-23 08:31:36 +02:00
db.journalWriter = w
db.journalFile = file
db.frozenMem = db.mem
db.mem = memdb.New(db.s.icmp, maxInt(db.s.o.GetWriteBuffer(), n))
mem = db.mem
// The seq only incremented by the writer. And whoever called newMem
// should hold write lock, so no need additional synchronization here.
db.frozenSeq = db.seq
2014-07-06 14:46:48 +02:00
return
}
// Get all memdbs.
2014-07-23 08:31:36 +02:00
func (db *DB) getMems() (e *memdb.DB, f *memdb.DB) {
db.memMu.RLock()
defer db.memMu.RUnlock()
return db.mem, db.frozenMem
2014-07-06 14:46:48 +02:00
}
// Get frozen memdb.
2014-07-23 08:31:36 +02:00
func (db *DB) getEffectiveMem() *memdb.DB {
db.memMu.RLock()
defer db.memMu.RUnlock()
return db.mem
2014-07-06 14:46:48 +02:00
}
// Check whether we has frozen memdb.
2014-07-23 08:31:36 +02:00
func (db *DB) hasFrozenMem() bool {
db.memMu.RLock()
defer db.memMu.RUnlock()
return db.frozenMem != nil
2014-07-06 14:46:48 +02:00
}
// Get frozen memdb.
2014-07-23 08:31:36 +02:00
func (db *DB) getFrozenMem() *memdb.DB {
db.memMu.RLock()
defer db.memMu.RUnlock()
return db.frozenMem
2014-07-06 14:46:48 +02:00
}
// Drop frozen memdb; assume that frozen memdb isn't nil.
2014-07-23 08:31:36 +02:00
func (db *DB) dropFrozenMem() {
db.memMu.Lock()
if err := db.frozenJournalFile.Remove(); err != nil {
db.logf("journal@remove removing @%d %q", db.frozenJournalFile.Num(), err)
2014-07-06 14:46:48 +02:00
} else {
2014-07-23 08:31:36 +02:00
db.logf("journal@remove removed @%d", db.frozenJournalFile.Num())
2014-07-06 14:46:48 +02:00
}
2014-07-23 08:31:36 +02:00
db.frozenJournalFile = nil
db.frozenMem = nil
db.memMu.Unlock()
2014-07-06 14:46:48 +02:00
}
// Set closed flag; return true if not already closed.
2014-07-23 08:31:36 +02:00
func (db *DB) setClosed() bool {
return atomic.CompareAndSwapUint32(&db.closed, 0, 1)
2014-07-06 14:46:48 +02:00
}
// Check whether DB was closed.
2014-07-23 08:31:36 +02:00
func (db *DB) isClosed() bool {
return atomic.LoadUint32(&db.closed) != 0
2014-07-06 14:46:48 +02:00
}
// Check read ok status.
2014-07-23 08:31:36 +02:00
func (db *DB) ok() error {
if db.isClosed() {
2014-07-06 14:46:48 +02:00
return ErrClosed
}
return nil
}