MCPcopy
hub / github.com/etcd-io/bbolt / WriteTo

Method WriteTo

tx.go:391–468  ·  view source on GitHub ↗

WriteTo writes the entire database to a writer. If err == nil then exactly tx.Size() bytes will be written into the writer.

(w io.Writer)

Source from the content-addressed store, hash-verified

389// WriteTo writes the entire database to a writer.
390// If err == nil then exactly tx.Size() bytes will be written into the writer.
391func (tx *Tx) WriteTo(w io.Writer) (n int64, err error) {
392 var f *os.File
393 // There is a risk that between the time a read-only transaction
394 // is created and the time the file is actually opened, the
395 // underlying db file at tx.db.path may have been replaced
396 // (e.g. via rename). In that case, opening the file again would
397 // unexpectedly point to a different file, rather than the one
398 // the transaction was based on.
399 //
400 // To overcome this, we reuse the already opened file handle when
401 // WriteFlag not set. When the WriteFlag is set, we reopen the file
402 // but verify that it still refers to the same underlying file
403 // (by device and inode). If it does not, we fall back to
404 // reusing the existing already opened file handle.
405 if tx.WriteFlag != 0 {
406 // Attempt to open reader with WriteFlag
407 f, err = tx.db.openFile(tx.db.path, os.O_RDONLY|tx.WriteFlag, 0)
408 if err != nil {
409 return 0, err
410 }
411
412 if ok, err := sameFile(tx.db.file, f); !ok {
413 lg := tx.db.Logger()
414 if cerr := f.Close(); cerr != nil {
415 lg.Errorf("failed to close the file (%s): %v", tx.db.path, cerr)
416 }
417 lg.Warningf("The underlying file has changed, so reuse the already opened file (%s): %v", tx.db.path, err)
418 f = tx.db.file
419 } else {
420 defer func() {
421 if cerr := f.Close(); err == nil {
422 err = cerr
423 }
424 }()
425 }
426 } else {
427 f = tx.db.file
428 }
429
430 // Generate a meta page. We use the same page data for both meta pages.
431 buf := make([]byte, tx.db.pageSize)
432 page := (*common.Page)(unsafe.Pointer(&buf[0]))
433 page.SetFlags(common.MetaPageFlag)
434 *page.Meta() = *tx.meta
435
436 // Write meta 0.
437 page.SetId(0)
438 page.Meta().SetChecksum(page.Meta().Sum64())
439 nn, err := w.Write(buf)
440 n += int64(nn)
441 if err != nil {
442 return n, fmt.Errorf("meta 0 copy: %s", err)
443 }
444
445 // Write meta 1 with a lower transaction id.
446 page.SetId(1)
447 page.Meta().DecTxid()
448 page.Meta().SetChecksum(page.Meta().Sum64())

Callers 3

CopyMethod · 0.95
CopyFileMethod · 0.95
stopProfilingFunction · 0.80

Calls 13

SizeMethod · 0.95
sameFileFunction · 0.85
LoggerMethod · 0.80
MetaMethod · 0.80
SetIdMethod · 0.80
SetChecksumMethod · 0.80
Sum64Method · 0.80
DecTxidMethod · 0.80
ErrorfMethod · 0.65
WarningfMethod · 0.65
WriteMethod · 0.65
CloseMethod · 0.45

Tested by

no test coverage detected