Ejemplo n.º 1
0
// Create a new manifest file; need external synchronization.
func (s *session) newManifest(rec *sessionRecord, v *version) (err error) {
	num := s.allocFileNum()
	file := s.stor.GetFile(num, storage.TypeManifest)
	writer, err := file.Create()
	if err != nil {
		return
	}
	jw := journal.NewWriter(writer)

	if v == nil {
		v = s.version_NB()
	}
	if rec == nil {
		rec = new(sessionRecord)
	}
	s.fillRecord(rec, true)
	v.fillRecord(rec)

	defer func() {
		if err == nil {
			s.recordCommited(rec)
			if s.manifest != nil {
				s.manifest.Close()
			}
			if s.manifestWriter != nil {
				s.manifestWriter.Close()
			}
			if s.manifestFile != nil {
				s.manifestFile.Remove()
			}
			s.manifestFile = file
			s.manifestWriter = writer
			s.manifest = jw
		} else {
			writer.Close()
			file.Remove()
			s.reuseFileNum(num)
		}
	}()

	w, err := jw.Next()
	if err != nil {
		return
	}
	err = rec.encode(w)
	if err != nil {
		return
	}
	err = jw.Flush()
	if err != nil {
		return
	}
	err = s.stor.SetManifest(file)
	return
}
Ejemplo n.º 2
0
// Create new memdb and froze the old one; need external synchronization.
// newMem only called synchronously by the writer.
func (db *DB) newMem(n int) (mem *memDB, err error) {
	num := db.s.allocFileNum()
	file := db.s.getJournalFile(num)
	w, err := file.Create()
	if err != nil {
		db.s.reuseFileNum(num)
		return
	}

	db.memMu.Lock()
	defer db.memMu.Unlock()

	if db.frozenMem != nil {
		panic("still has frozen mem")
	}

	if db.journal == nil {
		db.journal = journal.NewWriter(w)
	} else {
		db.journal.Reset(w)
		db.journalWriter.Close()
		db.frozenJournalFile = db.journalFile
	}
	db.journalWriter = w
	db.journalFile = file
	db.frozenMem = db.mem
	mem, ok := db.memPool.Get().(*memDB)
	if ok && mem.db.Capacity() >= n {
		mem.db.Reset()
		mem.incref()
	} else {
		mem = &memDB{
			pool: db.memPool,
			db:   memdb.New(db.s.icmp, maxInt(db.s.o.GetWriteBuffer(), n)),
			ref:  1,
		}
	}
	mem.incref()
	db.mem = 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
	return
}