func (f *LogFile) Stat() (int64, time.Time) {
	f.mu.RLock()
	size, modTime := f.size, f.modTime
	f.mu.RUnlock()
	return size, modTime
}
Stat returns size and last modification time of the file.
package tsi1
import (
	"bufio"
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"hash/crc32"
	"io"
	"os"
	"sort"
	"sync"
	"time"
	"github.com/influxdata/influxdb/models"
	"github.com/influxdata/influxdb/pkg/bloom"
	"github.com/influxdata/influxdb/pkg/estimator"
	"github.com/influxdata/influxdb/pkg/estimator/hll"
	"github.com/influxdata/influxdb/pkg/mmap"
	"github.com/influxdata/influxdb/tsdb"
)
var (
	ErrLogEntryChecksumMismatch = errors.New("log entry checksum mismatch")
)
const (
	LogEntrySeriesTombstoneFlag      = 0x01
	LogEntryMeasurementTombstoneFlag = 0x02
	LogEntryTagKeyTombstoneFlag      = 0x04
	LogEntryTagValueTombstoneFlag    = 0x08
)
type LogFile struct {
	mu     sync.RWMutex
	wg     sync.WaitGroup  
	id     int             
	data   []byte          
	file   *os.File        
	w      *bufio.Writer   
	buf    []byte          
	keyBuf []byte
	sfile   *tsdb.SeriesFile  
	size    int64             
	modTime time.Time         
	mSketch, mTSketch estimator.Sketch  
	sSketch, sTSketch estimator.Sketch  
	seriesIDSet, tombstoneSeriesIDSet *tsdb.SeriesIDSet
	mms logMeasurements
	path string
}
func NewLogFile(sfile *tsdb.SeriesFile, path string) *LogFile {
	return &LogFile{
		sfile:    sfile,
		path:     path,
		mms:      make(logMeasurements),
		mSketch:  hll.NewDefaultPlus(),
		mTSketch: hll.NewDefaultPlus(),
		sSketch:  hll.NewDefaultPlus(),
		sTSketch: hll.NewDefaultPlus(),
		seriesIDSet:          tsdb.NewSeriesIDSet(),
		tombstoneSeriesIDSet: tsdb.NewSeriesIDSet(),
	}
}
func (f *LogFile) Open() error {
	if err := f.open(); err != nil {
		f.Close()
		return err
	}
	return nil
}
func (f *LogFile) open() error {
	f.id, _ = ParseFilename(f.path)
	file, err := os.OpenFile(f.Path(), os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		return err
	}
	f.file = file
	f.w = bufio.NewWriter(f.file)
	fi, err := file.Stat()
	if err != nil {
		return err
	} else if fi.Size() == 0 {
		return nil
	}
	f.size = fi.Size()
	f.modTime = fi.ModTime()
	data, err := mmap.Map(f.Path(), 0)
	if err != nil {
		return err
	}
	f.data = data
	var n int64
	for buf := f.data; len(buf) > 0; {
		var e LogEntry
		if err := e.UnmarshalBinary(buf); err == io.ErrShortBuffer || err == ErrLogEntryChecksumMismatch {
			break
		} else if err != nil {
			return err
		}
		f.execEntry(&e)
		n += int64(e.Size)
		buf = buf[e.Size:]
	}
	f.size = n
	if _, err := file.Seek(n, io.SeekStart); err != nil {
		return err
	}
	return nil
}
func (f *LogFile) Close() error {
	f.wg.Wait()
	if f.w != nil {
		f.w.Flush()
		f.w = nil
	}
	if f.file != nil {
		f.file.Close()
		f.file = nil
	}
	if f.data != nil {
		mmap.Unmap(f.data)
	}
	f.mms = make(logMeasurements)
	return nil
}
func (f *LogFile) Flush() error {
	if f.w != nil {
		return f.w.Flush()
	}
	return nil
}
func (f *LogFile) ID() int { return f.id }
func (f *LogFile) Path() string { return f.path }
func (f *LogFile) SetPath(path string) { f.path = path }
func (f *LogFile) Level() int { return 0 }
func (f *LogFile) Filter() *bloom.Filter { return nil }
func (f *LogFile) Retain() { f.wg.Add(1) }
func (f *LogFile) Release() { f.wg.Done() }